diff --git a/.atl/.skill-registry.cache.json b/.atl/.skill-registry.cache.json new file mode 100644 index 0000000..bdbaea9 --- /dev/null +++ b/.atl/.skill-registry.cache.json @@ -0,0 +1,3 @@ +{ + "fingerprint": "c324de9e9faf30231900c691aca5f3a07c7db099" +} \ No newline at end of file diff --git a/.atl/skill-registry.md b/.atl/skill-registry.md new file mode 100644 index 0000000..58213aa --- /dev/null +++ b/.atl/skill-registry.md @@ -0,0 +1,34 @@ +# Skill Registry — headquarter + + + +Last updated: 2026-05-27 + +## Sources scanned + +- .opencode/skills +- /home/alex/.config/opencode/skills + +## Contract + +**Delegator use only.** This registry is an index, not a summary. Any agent that launches subagents reads it to select relevant skills, then passes exact `SKILL.md` paths for the subagent to read before work. + +`SKILL.md` remains the source of truth. Do not inject generated summaries or compact rules by default; pass paths so subagents load the full runtime contract and preserve author intent. + +## Skills + +| Skill | Trigger / description | Scope | Path | +| --- | --- | --- | --- | +| `auto-commit` | Use when you are making multiple edits or completing significant work in a git repository to automatically create commits | user | `/home/alex/.config/opencode/skills/auto-commit/SKILL.md` | +| `openspec` | Use OpenSpec as the source of truth for planning, implementation, verification, and archive discipline. | user | `/home/alex/.config/opencode/skills/openspec/SKILL.md` | +| `openspec-apply-change` | Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks. | project | `/home/alex/projects/headquarter/.opencode/skills/openspec-apply-change/SKILL.md` | +| `openspec-archive-change` | Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete. | project | `/home/alex/projects/headquarter/.opencode/skills/openspec-archive-change/SKILL.md` | +| `openspec-explore` | Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change. | project | `/home/alex/projects/headquarter/.opencode/skills/openspec-explore/SKILL.md` | +| `openspec-propose` | Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation. | project | `/home/alex/projects/headquarter/.opencode/skills/openspec-propose/SKILL.md` | + +## Loading protocol + +1. Match task context and target files against the `Trigger / description` column. +2. Pass only the matching `Path` values to the subagent under `## Skills to load before work`. +3. Instruct the subagent to read those exact `SKILL.md` files before reading, writing, reviewing, testing, or creating artifacts. +4. If no matching skill exists, proceed without project skill injection and report `skill_resolution: none`. diff --git a/.gitignore b/.gitignore index 77d7a72..d10ca6a 100644 --- a/.gitignore +++ b/.gitignore @@ -49,5 +49,8 @@ apps/web/dist/ .DS_Store Thumbs.db /.stoneforge/.worktrees/ -# Local Pi runtime state +# Pi / agent cache +.pi/ .atl/ +.sisyphus/ +.pi-lens/ diff --git a/.sisyphus/run-continuation/ses_1da2608b1ffergOzow3NQt1mGr.json b/.sisyphus/run-continuation/ses_1da2608b1ffergOzow3NQt1mGr.json new file mode 100644 index 0000000..94a9870 --- /dev/null +++ b/.sisyphus/run-continuation/ses_1da2608b1ffergOzow3NQt1mGr.json @@ -0,0 +1,10 @@ +{ + "sessionID": "ses_1da2608b1ffergOzow3NQt1mGr", + "updatedAt": "2026-05-15T23:50:42.832Z", + "sources": { + "background-task": { + "state": "idle", + "updatedAt": "2026-05-15T23:50:42.832Z" + } + } +} \ No newline at end of file diff --git a/apps/api/.pi-lens/cache/python-rules-v2.json b/apps/api/.pi-lens/cache/python-rules-v2.json new file mode 100644 index 0000000..bb12d7e --- /dev/null +++ b/apps/api/.pi-lens/cache/python-rules-v2.json @@ -0,0 +1,568 @@ +{ + "version": "v2", + "timestamp": 1779889907001, + "ruleHash": "fd9b2b15f2ac8993", + "queries": [ + { + "id": "bare-except", + "name": "Bare Except Clause", + "severity": "warning", + "language": "python", + "message": "Bare 'except:' clause — catches SystemExit, KeyboardInterrupt", + "query": " (except_clause\n \"except\") @CLAUSE", + "metavars": [ + "CLAUSE" + ], + "post_filter": "bare_except_only", + "defect_class": "silent-error", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/bare-except.yml" + }, + { + "id": "eval-exec", + "name": "Eval/Exec Usage", + "severity": "warning", + "language": "python", + "message": "{{FUNC}}() detected — security risk, code injection vulnerability", + "query": " (call\n function: (identifier) @FUNC\n (#match? @FUNC \"^(eval|exec)$\")\n arguments: (argument_list) @ARGS)", + "metavars": [ + "FUNC", + "ARGS" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/eval-exec.yml" + }, + { + "id": "exit-signature-check", + "name": "__exit__ Missing Parameters", + "severity": "error", + "language": "python", + "message": "__exit__ should accept type, value, and traceback arguments", + "query": " (function_definition\n name: (identifier) @NAME (#eq? @NAME \"__exit__\")\n parameters: (parameters\n (_) @SELF\n . (_) @PARAM1?\n . (_) @PARAM2?\n . (_) @PARAM3?))", + "metavars": [ + "NAME", + "SELF", + "PARAM1", + "PARAM2", + "PARAM3" + ], + "post_filter": "exit_params_insufficient", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/exit-signature-check.yml" + }, + { + "id": "in-operator-unsupported", + "name": "In and Not In Operators Should Be Used on Valid Objects", + "severity": "warning", + "language": "python", + "message": "'in' operator used on object that may not support containment", + "query": " (comparison_operator\n (identifier) @OBJ\n \"in\"\n (identifier) @TARGET)\n (comparison_operator\n (identifier) @OBJ\n \"not\"\n \"in\"\n (identifier) @TARGET)", + "metavars": [ + "OBJ", + "TARGET" + ], + "post_filter": "check_in_operator_types", + "defect_class": "correctness", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/in-operator-unsupported.yml" + }, + { + "id": "is-vs-equals", + "name": "Is vs Equals for Literals", + "severity": "warning", + "language": "python", + "message": "Using 'is' with literal — use '==' for value comparison", + "query": " (comparison_operator\n (identifier)\n (\"is\")\n (string) @LITERAL)\n (comparison_operator\n (identifier)\n (\"is not\")\n (string) @LITERAL)\n (comparison_operator\n (identifier)\n (\"is\")\n (integer) @LITERAL)\n (comparison_operator\n (identifier)\n (\"is not\")\n (integer) @LITERAL)", + "metavars": [ + "LITERAL" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/is-vs-equals.yml" + }, + { + "id": "iter-return-iterator", + "name": "__iter__ Should Return Iterator", + "severity": "warning", + "language": "python", + "message": "__iter__ should return an iterator (object with __next__ method)", + "query": " (function_definition\n name: (identifier) @NAME (#eq? @NAME \"__iter__\")\n body: (block\n (return_statement) @RETURN))", + "metavars": [ + "NAME", + "RETURN" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/iter-return-iterator.yml" + }, + { + "id": "mutable-default-arg", + "name": "Mutable Default Argument", + "severity": "warning", + "language": "python", + "message": "Mutable default argument — list/dict/set as default value", + "query": " (function_definition\n (parameters\n (default_parameter\n (identifier) @PARAM\n [(list) (dictionary) (set)] @MUTABLE)))", + "metavars": [ + "PARAM", + "MUTABLE" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/mutable-default-arg.yml" + }, + { + "id": "no-super-torchscript", + "name": "super Should Not Be Used in TorchScript Methods", + "severity": "error", + "language": "python", + "message": "super() calls should not be used in TorchScript methods", + "query": " (function_definition\n (decorator\n (call\n function: (identifier) @DEC (#match? @DEC \"^(torch\\.jit\\.script|jit\\.script)$\")))\n body: (block\n (call\n function: (identifier) @FUNC (#eq? @FUNC \"super\")) @CALL))", + "metavars": [ + "DEC", + "FUNC", + "CALL" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/no-super-torchscript.yml" + }, + { + "id": "notimplemented-boolean-context", + "name": "NotImplemented in Boolean Context", + "severity": "error", + "language": "python", + "message": "NotImplemented should not be used in boolean contexts", + "query": " (if_statement\n condition: (identifier) @COND (#eq? @COND \"NotImplemented\"))\n (while_statement\n condition: (identifier) @COND (#eq? @COND \"NotImplemented\"))\n (binary_operator\n (identifier) @COND (#eq? @COND \"NotImplemented\")\n (\"and\" | \"or\"))\n (boolean_operator\n (identifier) @COND (#eq? @COND \"NotImplemented\"))\n (unary_operator\n operator: (\"not\")\n argument: (identifier) @COND (#eq? @COND \"NotImplemented\"))", + "metavars": [ + "COND" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/notimplemented-boolean-context.yml" + }, + { + "id": "python-assert-production", + "name": "Assert in Production Code", + "severity": "warning", + "language": "python", + "message": "assert statement stripped by Python -O flag — use explicit checks with exceptions in production code", + "query": " (assert_statement) @ASSERT", + "metavars": [ + "ASSERT" + ], + "defect_class": "correctness", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-assert-production.yml" + }, + { + "id": "python-command-injection", + "name": "Command Injection Sink", + "severity": "error", + "language": "python", + "message": "Potential command injection sink — avoid shell execution with dynamic input", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list) @ARGS\n (#eq? @MOD \"os\")\n (#match? @FN \"^(system|popen)$\"))\n\n (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list\n (keyword_argument\n name: (identifier) @KW\n value: (true)))\n (#eq? @MOD \"subprocess\")\n (#match? @FN \"^(run|Popen|call|check_output|check_call)$\")\n (#eq? @KW \"shell\"))", + "metavars": [ + "MOD", + "FN", + "ARGS", + "KW" + ], + "post_filter": "py_command_injection_sink", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-command-injection.yml" + }, + { + "id": "python-cross-language-method", + "name": "Cross-Language Method Leakage", + "severity": "warning", + "language": "python", + "message": "'{METHOD}' is not a Python method — likely a {LANG} idiom leaking in", + "query": " (call\n function: (attribute\n object: (_) @OBJ\n attribute: (identifier) @METHOD)\n (#match? @METHOD \"^(push|forEach|indexOf|charAt|substring|hasOwnProperty|unshift|flatMap|padStart|padEnd|trimStart|trimEnd|equals|isEmpty|println|printf|getClass|hashCode|toCharArray|getBytes|compareTo|equalsIgnoreCase|startsWith|endsWith|each|collect|select|reject|detect|inject|chomp|chop|gsub|upcase|downcase|present|blank|Add|Contains|ToLower|ToUpper|Trim|Substring|WriteLine|ReadLine|TryParse|forEach|includes|assign|freeze|splice|unshift|shift|flatMap)$\"))", + "metavars": [ + "OBJ", + "METHOD" + ], + "post_filter": "match_captures", + "post_filter_params": { + "METHOD": "^(push|forEach|indexOf|charAt|substring|hasOwnProperty|unshift|flatMap|padStart|padEnd|trimStart|trimEnd|equals|isEmpty|println|printf|getClass|hashCode|toCharArray|getBytes|compareTo|equalsIgnoreCase|startsWith|endsWith|each|collect|select|reject|detect|inject|chomp|chop|gsub|upcase|downcase|present|blank|Add|Contains|ToLower|ToUpper|Trim|Substring|WriteLine|ReadLine|TryParse|forEach|includes|assign|freeze|splice|unshift|shift|flatMap)$" + }, + "defect_class": "hallucination", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml" + }, + { + "id": "python-debugger", + "name": "Debugger Statement", + "severity": "warning", + "language": "python", + "message": "Debugger call '{{FUNC}}' — remove before committing", + "query": " (call\n function: (identifier) @FUNC\n (#eq? @FUNC \"breakpoint\"))\n\n (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FUNC)\n (#eq? @MOD \"pdb\")\n (#match? @FUNC \"^(set_trace|post_mortem|pm|run|runcall)$\"))", + "metavars": [ + "FUNC", + "MOD" + ], + "defect_class": "safety", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-debugger.yml" + }, + { + "id": "python-empty-except", + "name": "Empty Except Block", + "severity": "warning", + "language": "python", + "message": "Except block only contains 'pass' — handle or re-raise the exception", + "query": " (try_statement\n (except_clause\n body: (block) @BODY))", + "metavars": [ + "BODY" + ], + "post_filter": "python_empty_except", + "defect_class": "silent-error", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-empty-except.yml" + }, + { + "id": "python-hallucinated-import", + "name": "Hallucinated Import", + "severity": "warning", + "language": "python", + "message": "Hallucinated import — '{NAME}' does not exist in '{MODULE}'", + "query": " (import_from_statement\n module_name: (dotted_name) @MODULE\n name: (dotted_name) @NAME)", + "metavars": [ + "MODULE", + "NAME" + ], + "post_filter": "match_captures", + "post_filter_params": { + "MODULE": "^(requests|flask|django|typing|collections|asyncio|json|unittest|pytest|urllib|sqlalchemy)$", + "NAME": "^(JSONResponse|HTMLResponse|RedirectResponse|StreamingResponse|Depends|Query|Path|Body|Header|Cookie|Form|File|UploadFile|FastAPI|APIRouter|HTTPException|BackgroundTasks|dataclass|fields|BaseModel|Field|validator|aiohttp|parse|stringify|fixture|TestCase|get|post|put|delete|Model|Session|Column|Integer|String)$" + }, + "defect_class": "hallucination", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml" + }, + { + "id": "python-hardcoded-secrets", + "name": "Hardcoded Secret", + "severity": "warning", + "language": "python", + "message": "Hardcoded {{VARNAME}} — use environment variables or a secrets manager", + "query": " (assignment\n left: (identifier) @VARNAME\n right: (string) @VALUE)", + "metavars": [ + "VARNAME", + "VALUE" + ], + "post_filter": "check_secret_pattern", + "defect_class": "secrets", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hardcoded-secrets.yml" + }, + { + "id": "python-insecure-deserialization", + "name": "Insecure Deserialization", + "severity": "error", + "language": "python", + "message": "Potential insecure deserialization sink — avoid unsafe loaders", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list (_) @DATA)\n (#match? @MOD \"^(pickle|yaml)$\")\n (#match? @FN \"^(load|loads|unsafe_load)$\"))", + "metavars": [ + "MOD", + "FN", + "DATA" + ], + "post_filter": "py_insecure_deserialization_sink", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-insecure-deserialization.yml" + }, + { + "id": "python-insecure-random", + "name": "Insecure Randomness", + "severity": "warning", + "language": "python", + "message": "Insecure randomness source detected — use secrets or os.urandom for security-sensitive values", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list) @ARGS\n (#eq? @MOD \"random\")\n (#match? @FN \"^(random|randint|randrange|choice|choices)$\"))", + "metavars": [ + "MOD", + "FN", + "ARGS" + ], + "defect_class": "injection", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-insecure-random.yml" + }, + { + "id": "python-mutable-class-attr", + "name": "Mutable Class Attribute", + "severity": "warning", + "language": "python", + "message": "Class attribute '{{VARNAME}}' is mutable — shared across all instances", + "query": " (class_definition\n body: (block\n (expression_statement\n (assignment\n left: (identifier) @VARNAME\n right: [\n (list) @VALUE\n (dictionary) @VALUE\n (set) @VALUE\n ]))))", + "metavars": [ + "VARNAME", + "VALUE" + ], + "post_filter": "not_in_function", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-mutable-class-attr.yml" + }, + { + "id": "python-path-traversal", + "name": "Path Traversal Risk", + "severity": "warning", + "language": "python", + "message": "Potential path traversal sink — sanitize and constrain file paths", + "query": " [\n (call\n function: (identifier) @FN\n arguments: (argument_list\n [(identifier) (binary_operator) (call)] @PATH))\n (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list\n [(identifier) (binary_operator) (call)] @PATH))\n ]\n (#match? @FN \"^(open|read_text|read_bytes|write_text|write_bytes|remove|unlink|rmdir)$\")", + "metavars": [ + "MOD", + "FN", + "PATH" + ], + "post_filter": "py_path_traversal_sink", + "defect_class": "injection", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-path-traversal.yml" + }, + { + "id": "python-print-statement", + "name": "Print Statement in Production", + "severity": "warning", + "language": "python", + "message": "print() — remove debug output before committing", + "query": " (call\n function: (identifier) @FUNC\n (#eq? @FUNC \"print\")\n arguments: (argument_list) @ARGS)", + "metavars": [ + "FUNC", + "ARGS" + ], + "post_filter": "not_in_test_block", + "defect_class": "safety", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-print-statement.yml" + }, + { + "id": "python-raise-string", + "name": "Raise String Instead of Exception", + "severity": "warning", + "language": "python", + "message": "raise with string literal — Python 3 requires exception instances", + "query": " (raise_statement\n (string) @VALUE)", + "metavars": [ + "VALUE" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-raise-string.yml" + }, + { + "id": "python-sleep-in-test", + "name": "time.sleep in Test", + "severity": "warning", + "language": "python", + "message": "time.sleep() in test — use synchronisation primitives or polling helpers instead of fixed sleeps", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n (#eq? @MOD \"time\")\n (#eq? @FN \"sleep\")) @CALL", + "metavars": [ + "MOD", + "FN", + "CALL" + ], + "defect_class": "async-misuse", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sleep-in-test.yml" + }, + { + "id": "python-sql-injection", + "name": "SQL Injection Risk", + "severity": "error", + "language": "python", + "message": "Potential SQL injection sink — use parameterized queries", + "query": " (call\n function: (attribute\n object: (_) @OBJ\n attribute: (identifier) @FN)\n arguments: (argument_list\n [(binary_operator) (identifier) (call)] @SQL\n (_)*))", + "metavars": [ + "OBJ", + "FN", + "SQL" + ], + "post_filter": "py_sql_injection_sink", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml" + }, + { + "id": "python-ssrf", + "name": "SSRF Risk", + "severity": "warning", + "language": "python", + "message": "Potential SSRF sink — validate/allowlist outbound URLs", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list\n [(identifier) (subscript) (call)] @URL)\n (#eq? @MOD \"requests\")\n (#match? @FN \"^(get|post|put|patch|delete|request|head|options)$\"))", + "metavars": [ + "MOD", + "FN", + "URL" + ], + "post_filter": "py_ssrf_sink", + "defect_class": "injection", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-ssrf.yml" + }, + { + "id": "python-subprocess-shell", + "name": "subprocess with shell=True", + "severity": "warning", + "language": "python", + "message": "subprocess called with shell=True — command injection risk if any argument is user-controlled", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list\n (keyword_argument\n name: (identifier) @KW\n value: (true) @VAL))\n (#eq? @MOD \"subprocess\")\n (#match? @FN \"^(run|Popen|call|check_output|check_call)$\")\n (#eq? @KW \"shell\"))", + "metavars": [ + "MOD", + "FN", + "KW" + ], + "defect_class": "injection", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-subprocess-shell.yml" + }, + { + "id": "python-thread-global-write", + "name": "Threaded Shared State Risk", + "severity": "warning", + "language": "python", + "message": "Thread creation detected — ensure shared state mutations are synchronized", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list) @ARGS)\n (#eq? @MOD \"threading\")\n (#eq? @FN \"Thread\")", + "metavars": [ + "MOD", + "FN", + "ARGS" + ], + "defect_class": "async-misuse", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-thread-global-write.yml" + }, + { + "id": "python-unsafe-regex", + "name": "Unsafe Dynamic Regex", + "severity": "warning", + "language": "python", + "message": "re.{{FUNC}}() with variable pattern — ReDoS risk if pattern is user-controlled", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FUNC)\n arguments: (argument_list\n (identifier) @PATTERN)\n (#eq? @MOD \"re\")\n (#match? @FUNC \"^(compile|match|search|fullmatch|findall|finditer|sub|subn|split)$\"))", + "metavars": [ + "MOD", + "FUNC", + "PATTERN" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-unsafe-regex.yml" + }, + { + "id": "python-weak-hash", + "name": "Weak Hash Primitive", + "severity": "error", + "language": "python", + "message": "Weak hash primitive detected (MD5/SHA1) — use SHA-256+ for security-sensitive contexts", + "query": " (call\n function: (attribute\n object: (identifier) @MOD\n attribute: (identifier) @FN)\n arguments: (argument_list) @ARGS\n (#eq? @MOD \"hashlib\")\n (#match? @FN \"^(md5|sha1)$\"))", + "metavars": [ + "MOD", + "FN", + "ARGS" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/python-weak-hash.yml" + }, + { + "id": "return-in-generator", + "name": "Return with Value in Generator", + "severity": "error", + "language": "python", + "message": "'return' with a value should not be used in a generator function", + "query": " (function_definition\n body: (block\n (return_statement\n (_) @RETURN_VAL) @RETURN)) @FUNCTION", + "metavars": [ + "FUNCTION", + "RETURN", + "RETURN_VAL" + ], + "post_filter": "is_generator_with_valued_return", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/return-in-generator.yml" + }, + { + "id": "return-in-init", + "name": "Return Value in __init__", + "severity": "error", + "language": "python", + "message": "__init__ should not return a value — it must always return None", + "query": " (function_definition\n name: (identifier) @NAME (#eq? @NAME \"__init__\")\n body: (block\n (return_statement\n (_) @RETURN_VAL) @RETURN))", + "metavars": [ + "NAME", + "RETURN", + "RETURN_VAL" + ], + "post_filter": "has_return_value", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/return-in-init.yml" + }, + { + "id": "send-file-mimetype", + "name": "send_file Should Specify Mimetype or Download Name", + "severity": "error", + "language": "python", + "message": "send_file should specify 'mimetype' or 'download_name' when used with file-like objects", + "query": " (call\n function: (identifier) @FUNC (#eq? @FUNC \"send_file\")\n arguments: (argument_list\n (_) @FIRST_ARG\n (keyword_argument)? @KW))", + "metavars": [ + "FUNC", + "FIRST_ARG", + "KW" + ], + "post_filter": "missing_mimetype_and_download_name", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/send-file-mimetype.yml" + }, + { + "id": "unreachable-except", + "name": "Unreachable Except Clause", + "severity": "warning", + "language": "python", + "message": "Unreachable except clause — earlier except catches all", + "query": " (try_statement\n (except_clause\n \"except\") @GENERAL\n (except_clause\n \"except\"\n (identifier) @SPECIFIC))", + "metavars": [ + "GENERAL", + "SPECIFIC" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/unreachable-except.yml" + }, + { + "id": "wildcard-import", + "name": "Wildcard Import", + "severity": "warning", + "language": "python", + "message": "Wildcard import — pollutes namespace, hard to track origin", + "query": " (import_from_statement\n module_name: (dotted_name) @MODULE\n (wildcard_import) @WILDCARD)", + "metavars": [ + "MODULE", + "WILDCARD" + ], + "defect_class": "safety", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/wildcard-import.yml" + }, + { + "id": "yield-return-outside-function", + "name": "Yield/Return Outside Function", + "severity": "error", + "language": "python", + "message": "{{STATEMENT}} used outside function — syntax error", + "query": " (module\n (expression_statement\n (yield) @STATEMENT))\n (module\n (expression_statement\n (yield_expression) @STATEMENT))\n (module\n (return_statement) @STATEMENT)", + "metavars": [ + "STATEMENT" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/python/yield-return-outside-function.yml" + } + ] +} \ No newline at end of file diff --git a/apps/api/.pi-lens/cache/review-graph.json b/apps/api/.pi-lens/cache/review-graph.json deleted file mode 100644 index 0d649ad..0000000 --- a/apps/api/.pi-lens/cache/review-graph.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"v2","builtAt":"2026-05-28T11:31:47.398Z","signature":"/home/alex/projects/headquarter/apps/api/alembic/env.py:1566:1779050260293.852|/home/alex/projects/headquarter/apps/api/alembic/versions/0001_initial_schema.py:4658:1779050260293.852|/home/alex/projects/headquarter/apps/api/alembic/versions/0002_refresh_tokens.py:2405:1779050260294.7954|/home/alex/projects/headquarter/apps/api/alembic/versions/0003_user_configs.py:1101:1779139057995.512|/home/alex/projects/headquarter/apps/api/alembic/versions/0004_tool_types.py:1575:1779139081351.2407|/home/alex/projects/headquarter/apps/api/alembic/versions/0005_ssh_keys_timestamps.py:1039:1779184269353.1443|/home/alex/projects/headquarter/apps/api/alembic/versions/0006_tool_instances.py:2716:1779215731764.582|/home/alex/projects/headquarter/apps/api/alembic/versions/0007_instance_container_name.py:715:1779265847432.003|/home/alex/projects/headquarter/apps/api/alembic/versions/0008_tool_type_category.py:911:1779267040781.6345|/home/alex/projects/headquarter/apps/api/alembic/versions/0009_tool_configs.py:2039:1779267064123.3723|/home/alex/projects/headquarter/apps/api/alembic/versions/0010_tool_type_default_port.py:689:1779277879364.0645|/home/alex/projects/headquarter/apps/api/alembic/versions/0011_tool_instance_tunnel_fields.py:894:1779279491357.6292|/home/alex/projects/headquarter/apps/api/alembic/versions/0012_default_port_req.py:1229:1779290612348.005|/home/alex/projects/headquarter/apps/api/alembic/versions/0013_add_probe_result.py:743:1779478921751.2427|/home/alex/projects/headquarter/apps/api/alembic/versions/0014_merge_heads.py:525:1779958621074.462|/home/alex/projects/headquarter/apps/api/alembic/versions/0015_single_interface.py:3832:1779958621081.462|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_22_add_clone_mode.py:1312:1779485016565.7122|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_23_remove_is_builtin.py:698:1779620544420.1614|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_220141_add_startup_command.py:683:1779700843566.628|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_add_config_profiles.py:4826:1779645589985.5532|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_26_add_git_mounts.py:716:1779870048496.4265|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_27_external_repos.py:1150:1779870986784.585|/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_28_add_tool_definition_manifests.py:13934:1779967994204.917|/home/alex/projects/headquarter/apps/api/alembic/versions/20260527160017_add_pi_agent_tool_type.py:3794:1779958621081.462|/home/alex/projects/headquarter/apps/api/alembic/versions/398082499c30_add_tool_config_fields.py:1576:1779467943887.104|/home/alex/projects/headquarter/apps/api/alembic/versions/6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py:455:1779958621081.462|/home/alex/projects/headquarter/apps/api/alembic/versions/8ed7dd80973d_create_config_folders_table.py:1770:1779467958721.936|/home/alex/projects/headquarter/apps/api/alembic/versions/af8512103d67_add_tool_type_fields.py:1432:1779467930354.6824|/home/alex/projects/headquarter/apps/api/alembic/versions/f3d2dc90ba3a_merge_single_interface_and_clone_mode.py:559:1779958621094.4617|/home/alex/projects/headquarter/apps/api/src/__init__.py:31:1779050260294.7954|/home/alex/projects/headquarter/apps/api/src/api/__init__.py:139:1779050826659.6775|/home/alex/projects/headquarter/apps/api/src/api/auth.py:7944:1779912973110.818|/home/alex/projects/headquarter/apps/api/src/api/config_folders.py:12351:1779710572785.8096|/home/alex/projects/headquarter/apps/api/src/api/config_profiles.py:27916:1779958621095.4617|/home/alex/projects/headquarter/apps/api/src/api/dashboard.py:2121:1779218866429.8337|/home/alex/projects/headquarter/apps/api/src/api/git_repositories.py:46638:1779958621112.4614|/home/alex/projects/headquarter/apps/api/src/api/health.py:4554:1779958621112.4614|/home/alex/projects/headquarter/apps/api/src/api/instance_proxy.py:4233:1779958621116.4614|/home/alex/projects/headquarter/apps/api/src/api/projects.py:6672:1779958621116.4614|/home/alex/projects/headquarter/apps/api/src/api/shared_validators.py:2682:1779958621132.4612|/home/alex/projects/headquarter/apps/api/src/api/ssh_keys.py:7517:1779958621133.4612|/home/alex/projects/headquarter/apps/api/src/api/terminal.py:12567:1779958621133.4612|/home/alex/projects/headquarter/apps/api/src/api/tool_configs.py:11248:1779958621152.461|/home/alex/projects/headquarter/apps/api/src/api/tool_definitions.py:13721:1779962991824.0735|/home/alex/projects/headquarter/apps/api/src/api/tool_instances.py:81390:1779962991812.0737|/home/alex/projects/headquarter/apps/api/src/api/tool_types_validation.py:2608:1779710051058.87|/home/alex/projects/headquarter/apps/api/src/api/tool_types.py:18213:1779958621153.461|/home/alex/projects/headquarter/apps/api/src/api/user_config.py:3431:1779958621153.461|/home/alex/projects/headquarter/apps/api/src/api/users.py:4291:1779708729186.244|/home/alex/projects/headquarter/apps/api/src/auth/__init__.py:308:1779137370597.2402|/home/alex/projects/headquarter/apps/api/src/auth/cookies.py:287:1779139942809.316|/home/alex/projects/headquarter/apps/api/src/auth/dependencies.py:2891:1779958621153.461|/home/alex/projects/headquarter/apps/api/src/auth/oidc.py:1650:1779137182579.4893|/home/alex/projects/headquarter/apps/api/src/auth/session.py:2228:1779645590016.553|/home/alex/projects/headquarter/apps/api/src/config.py:4705:1779286905138.4783|/home/alex/projects/headquarter/apps/api/src/database.py:3904:1779138928838.0117|/home/alex/projects/headquarter/apps/api/src/logging_config.py:2832:1779135759825.8926|/home/alex/projects/headquarter/apps/api/src/main.py:4791:1779962991745.0745|/home/alex/projects/headquarter/apps/api/src/models/__init__.py:770:1779962991815.0735|/home/alex/projects/headquarter/apps/api/src/models/base.py:640:1779109950568.2888|/home/alex/projects/headquarter/apps/api/src/models/config_folder.py:1199:1779468006545.395|/home/alex/projects/headquarter/apps/api/src/models/config_profile.py:3157:1779885324307.303|/home/alex/projects/headquarter/apps/api/src/models/git_repository.py:1415:1779870334034.114|/home/alex/projects/headquarter/apps/api/src/models/project.py:1241:1779109950568.697|/home/alex/projects/headquarter/apps/api/src/models/ssh_key.py:993:1779184246096.4092|/home/alex/projects/headquarter/apps/api/src/models/tool_config.py:1814:1779471154363.973|/home/alex/projects/headquarter/apps/api/src/models/tool_definition_manifest.py:2449:1779962991760.0742|/home/alex/projects/headquarter/apps/api/src/models/tool_instance.py:3057:1779962991776.074|/home/alex/projects/headquarter/apps/api/src/models/tool_type.py:2196:1779962991768.0742|/home/alex/projects/headquarter/apps/api/src/models/user_config.py:680:1779109990811.1602|/home/alex/projects/headquarter/apps/api/src/models/user.py:981:1779137408181.7927|/home/alex/projects/headquarter/apps/api/src/scripts/__init__.py:43:1779050260295.4287|/home/alex/projects/headquarter/apps/api/src/scripts/seed.py:1099:1779050260295.7207|/home/alex/projects/headquarter/apps/api/src/services/clone.py:2697:1779912904816.8372|/home/alex/projects/headquarter/apps/api/src/services/config_profile_resolver.py:15234:1779874299307.0806|/home/alex/projects/headquarter/apps/api/src/services/docker_build.py:2454:1779958621154.461|/home/alex/projects/headquarter/apps/api/src/services/docker.py:16097:1779958667213.9204|/home/alex/projects/headquarter/apps/api/src/services/manifest_compiler.py:13851:1779962991788.074|/home/alex/projects/headquarter/apps/api/src/services/permission_fixer.py:4631:1779962991795.0737|/home/alex/projects/headquarter/apps/api/src/services/readiness_probe.py:2120:1779468682156.7576|/home/alex/projects/headquarter/apps/api/src/services/ssh_keys.py:2050:1779481962606.4976|/home/alex/projects/headquarter/apps/api/src/services/terminal_manager.py:5804:1779958621154.461|/home/alex/projects/headquarter/apps/api/src/services/terminal_session.py:8778:1779912904787.3071|/home/alex/projects/headquarter/apps/api/src/utils/git_control.py:8284:1779958621174.4607|/home/alex/projects/headquarter/apps/api/src/utils/git_files.py:13552:1779618531450.968|/home/alex/projects/headquarter/apps/api/src/utils/git_history.py:11790:1779189553538.5813|/home/alex/projects/headquarter/apps/api/src/utils/git_url_parser.py:6437:1779185863539.9849|/home/alex/projects/headquarter/apps/api/tests/conftest.py:7687:1779958621174.4607|/home/alex/projects/headquarter/apps/api/tests/integration/__init__.py:0:1779471420954.9705|/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_api.py:3813:1779471420958.8003|/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_services.py:2447:1779471420958.9465|/home/alex/projects/headquarter/apps/api/tests/integration/test_config_folders_api.py:9227:1779473067454.4243|/home/alex/projects/headquarter/apps/api/tests/integration/test_config_profiles_api.py:16841:1779886811162.0073|/home/alex/projects/headquarter/apps/api/tests/integration/test_git_control.py:5257:1779478799198.6309|/home/alex/projects/headquarter/apps/api/tests/integration/test_models.py:3080:1779958621180.4607|/home/alex/projects/headquarter/apps/api/tests/integration/test_projects_api.py:8540:1779958621180.4607|/home/alex/projects/headquarter/apps/api/tests/integration/test_seed.py:864:1779471420972.4473|/home/alex/projects/headquarter/apps/api/tests/integration/test_ssh_keys_api.py:689:1779471420972.5269|/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_configs_api_extended.py:9897:1779958621181.4607|/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api_extended.py:12371:1779958621181.4607|/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api.py:12510:1779556564012.5024|/home/alex/projects/headquarter/apps/api/tests/integration/test_users_api.py:6616:1779473987795.1477|/home/alex/projects/headquarter/apps/api/tests/system/__init__.py:0:1779109035822.815|/home/alex/projects/headquarter/apps/api/tests/unit/__init__.py:0:1779110037714.6304|/home/alex/projects/headquarter/apps/api/tests/unit/test_config_profile_resolver.py:15730:1779958621181.4607|/home/alex/projects/headquarter/apps/api/tests/unit/test_config.py:2316:1779110755300.477|/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_build.py:5738:1779471360116.6558|/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_service.py:1697:1779958603311.6707|/home/alex/projects/headquarter/apps/api/tests/unit/test_git_mount_resolution.py:4797:1779958621182.4607|/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_clone_preflight.py:1109:1779474860172.3552|/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_working_clones.py:2843:1779474860172.3552|/home/alex/projects/headquarter/apps/api/tests/unit/test_git_url_parser.py:5471:1779958621182.4607|/home/alex/projects/headquarter/apps/api/tests/unit/test_manifest_compiler.py:11095:1779962991834.0735|/home/alex/projects/headquarter/apps/api/tests/unit/test_migration_metadata.py:1177:1779110847713.4197|/home/alex/projects/headquarter/apps/api/tests/unit/test_permission_fixer.py:5348:1779962991842.0732|/home/alex/projects/headquarter/apps/api/tests/unit/test_readiness_probe.py:7321:1779958621190.4604|/home/alex/projects/headquarter/apps/api/tests/unit/test_session_branch_selection.py:6346:1779958621197.4604","fileSignatures":[["/home/alex/projects/headquarter/apps/api/alembic/env.py","1566:1779050260293.852"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0001_initial_schema.py","4658:1779050260293.852"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0002_refresh_tokens.py","2405:1779050260294.7954"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0003_user_configs.py","1101:1779139057995.512"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0004_tool_types.py","1575:1779139081351.2407"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0005_ssh_keys_timestamps.py","1039:1779184269353.1443"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0006_tool_instances.py","2716:1779215731764.582"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0007_instance_container_name.py","715:1779265847432.003"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0008_tool_type_category.py","911:1779267040781.6345"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0009_tool_configs.py","2039:1779267064123.3723"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0010_tool_type_default_port.py","689:1779277879364.0645"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0011_tool_instance_tunnel_fields.py","894:1779279491357.6292"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0012_default_port_req.py","1229:1779290612348.005"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0013_add_probe_result.py","743:1779478921751.2427"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0014_merge_heads.py","525:1779958621074.462"],["/home/alex/projects/headquarter/apps/api/alembic/versions/0015_single_interface.py","3832:1779958621081.462"],["/home/alex/projects/headquarter/apps/api/alembic/versions/20260527160017_add_pi_agent_tool_type.py","3794:1779958621081.462"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_22_add_clone_mode.py","1312:1779485016565.7122"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_23_remove_is_builtin.py","698:1779620544420.1614"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_220141_add_startup_command.py","683:1779700843566.628"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_add_config_profiles.py","4826:1779645589985.5532"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_26_add_git_mounts.py","716:1779870048496.4265"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_27_external_repos.py","1150:1779870986784.585"],["/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_28_add_tool_definition_manifests.py","13934:1779967994204.917"],["/home/alex/projects/headquarter/apps/api/alembic/versions/398082499c30_add_tool_config_fields.py","1576:1779467943887.104"],["/home/alex/projects/headquarter/apps/api/alembic/versions/6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py","455:1779958621081.462"],["/home/alex/projects/headquarter/apps/api/alembic/versions/8ed7dd80973d_create_config_folders_table.py","1770:1779467958721.936"],["/home/alex/projects/headquarter/apps/api/alembic/versions/af8512103d67_add_tool_type_fields.py","1432:1779467930354.6824"],["/home/alex/projects/headquarter/apps/api/alembic/versions/f3d2dc90ba3a_merge_single_interface_and_clone_mode.py","559:1779958621094.4617"],["/home/alex/projects/headquarter/apps/api/src/__init__.py","31:1779050260294.7954"],["/home/alex/projects/headquarter/apps/api/src/api/__init__.py","139:1779050826659.6775"],["/home/alex/projects/headquarter/apps/api/src/api/auth.py","7944:1779912973110.818"],["/home/alex/projects/headquarter/apps/api/src/api/config_folders.py","12351:1779710572785.8096"],["/home/alex/projects/headquarter/apps/api/src/api/config_profiles.py","27916:1779958621095.4617"],["/home/alex/projects/headquarter/apps/api/src/api/dashboard.py","2121:1779218866429.8337"],["/home/alex/projects/headquarter/apps/api/src/api/git_repositories.py","46638:1779958621112.4614"],["/home/alex/projects/headquarter/apps/api/src/api/health.py","4554:1779958621112.4614"],["/home/alex/projects/headquarter/apps/api/src/api/instance_proxy.py","4233:1779958621116.4614"],["/home/alex/projects/headquarter/apps/api/src/api/projects.py","6672:1779958621116.4614"],["/home/alex/projects/headquarter/apps/api/src/api/shared_validators.py","2682:1779958621132.4612"],["/home/alex/projects/headquarter/apps/api/src/api/ssh_keys.py","7517:1779958621133.4612"],["/home/alex/projects/headquarter/apps/api/src/api/terminal.py","12567:1779958621133.4612"],["/home/alex/projects/headquarter/apps/api/src/api/tool_configs.py","11248:1779958621152.461"],["/home/alex/projects/headquarter/apps/api/src/api/tool_definitions.py","13721:1779962991824.0735"],["/home/alex/projects/headquarter/apps/api/src/api/tool_instances.py","81390:1779962991812.0737"],["/home/alex/projects/headquarter/apps/api/src/api/tool_types.py","18213:1779958621153.461"],["/home/alex/projects/headquarter/apps/api/src/api/tool_types_validation.py","2608:1779710051058.87"],["/home/alex/projects/headquarter/apps/api/src/api/user_config.py","3431:1779958621153.461"],["/home/alex/projects/headquarter/apps/api/src/api/users.py","4291:1779708729186.244"],["/home/alex/projects/headquarter/apps/api/src/auth/__init__.py","308:1779137370597.2402"],["/home/alex/projects/headquarter/apps/api/src/auth/cookies.py","287:1779139942809.316"],["/home/alex/projects/headquarter/apps/api/src/auth/dependencies.py","2891:1779958621153.461"],["/home/alex/projects/headquarter/apps/api/src/auth/oidc.py","1650:1779137182579.4893"],["/home/alex/projects/headquarter/apps/api/src/auth/session.py","2228:1779645590016.553"],["/home/alex/projects/headquarter/apps/api/src/config.py","4705:1779286905138.4783"],["/home/alex/projects/headquarter/apps/api/src/database.py","3904:1779138928838.0117"],["/home/alex/projects/headquarter/apps/api/src/logging_config.py","2832:1779135759825.8926"],["/home/alex/projects/headquarter/apps/api/src/main.py","4791:1779962991745.0745"],["/home/alex/projects/headquarter/apps/api/src/models/__init__.py","770:1779962991815.0735"],["/home/alex/projects/headquarter/apps/api/src/models/base.py","640:1779109950568.2888"],["/home/alex/projects/headquarter/apps/api/src/models/config_folder.py","1199:1779468006545.395"],["/home/alex/projects/headquarter/apps/api/src/models/config_profile.py","3157:1779885324307.303"],["/home/alex/projects/headquarter/apps/api/src/models/git_repository.py","1415:1779870334034.114"],["/home/alex/projects/headquarter/apps/api/src/models/project.py","1241:1779109950568.697"],["/home/alex/projects/headquarter/apps/api/src/models/ssh_key.py","993:1779184246096.4092"],["/home/alex/projects/headquarter/apps/api/src/models/tool_config.py","1814:1779471154363.973"],["/home/alex/projects/headquarter/apps/api/src/models/tool_definition_manifest.py","2449:1779962991760.0742"],["/home/alex/projects/headquarter/apps/api/src/models/tool_instance.py","3057:1779962991776.074"],["/home/alex/projects/headquarter/apps/api/src/models/tool_type.py","2196:1779962991768.0742"],["/home/alex/projects/headquarter/apps/api/src/models/user.py","981:1779137408181.7927"],["/home/alex/projects/headquarter/apps/api/src/models/user_config.py","680:1779109990811.1602"],["/home/alex/projects/headquarter/apps/api/src/scripts/__init__.py","43:1779050260295.4287"],["/home/alex/projects/headquarter/apps/api/src/scripts/seed.py","1099:1779050260295.7207"],["/home/alex/projects/headquarter/apps/api/src/services/clone.py","2697:1779912904816.8372"],["/home/alex/projects/headquarter/apps/api/src/services/config_profile_resolver.py","15234:1779874299307.0806"],["/home/alex/projects/headquarter/apps/api/src/services/docker.py","16097:1779958667213.9204"],["/home/alex/projects/headquarter/apps/api/src/services/docker_build.py","2454:1779958621154.461"],["/home/alex/projects/headquarter/apps/api/src/services/manifest_compiler.py","13851:1779962991788.074"],["/home/alex/projects/headquarter/apps/api/src/services/permission_fixer.py","4631:1779962991795.0737"],["/home/alex/projects/headquarter/apps/api/src/services/readiness_probe.py","2120:1779468682156.7576"],["/home/alex/projects/headquarter/apps/api/src/services/ssh_keys.py","2050:1779481962606.4976"],["/home/alex/projects/headquarter/apps/api/src/services/terminal_manager.py","5804:1779958621154.461"],["/home/alex/projects/headquarter/apps/api/src/services/terminal_session.py","8778:1779912904787.3071"],["/home/alex/projects/headquarter/apps/api/src/utils/git_control.py","8284:1779958621174.4607"],["/home/alex/projects/headquarter/apps/api/src/utils/git_files.py","13552:1779618531450.968"],["/home/alex/projects/headquarter/apps/api/src/utils/git_history.py","11790:1779189553538.5813"],["/home/alex/projects/headquarter/apps/api/src/utils/git_url_parser.py","6437:1779185863539.9849"],["/home/alex/projects/headquarter/apps/api/tests/conftest.py","7687:1779958621174.4607"],["/home/alex/projects/headquarter/apps/api/tests/integration/__init__.py","0:1779471420954.9705"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_api.py","3813:1779471420958.8003"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_services.py","2447:1779471420958.9465"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_config_folders_api.py","9227:1779473067454.4243"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_config_profiles_api.py","16841:1779886811162.0073"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_git_control.py","5257:1779478799198.6309"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_models.py","3080:1779958621180.4607"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_projects_api.py","8540:1779958621180.4607"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_seed.py","864:1779471420972.4473"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_ssh_keys_api.py","689:1779471420972.5269"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_configs_api_extended.py","9897:1779958621181.4607"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api.py","12510:1779556564012.5024"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api_extended.py","12371:1779958621181.4607"],["/home/alex/projects/headquarter/apps/api/tests/integration/test_users_api.py","6616:1779473987795.1477"],["/home/alex/projects/headquarter/apps/api/tests/system/__init__.py","0:1779109035822.815"],["/home/alex/projects/headquarter/apps/api/tests/unit/__init__.py","0:1779110037714.6304"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_config.py","2316:1779110755300.477"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_config_profile_resolver.py","15730:1779958621181.4607"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_build.py","5738:1779471360116.6558"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_service.py","1697:1779958603311.6707"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_git_mount_resolution.py","4797:1779958621182.4607"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_clone_preflight.py","1109:1779474860172.3552"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_working_clones.py","2843:1779474860172.3552"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_git_url_parser.py","5471:1779958621182.4607"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_manifest_compiler.py","11095:1779962991834.0735"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_migration_metadata.py","1177:1779110847713.4197"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_permission_fixer.py","5348:1779962991842.0732"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_readiness_probe.py","7321:1779958621190.4604"],["/home/alex/projects/headquarter/apps/api/tests/unit/test_session_branch_selection.py","6346:1779958621197.4604"]],"nodes":[["file:/home/alex/projects/headquarter/apps/api/alembic/env.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/env.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/env.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0001_initial_schema.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0001_initial_schema.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0001_initial_schema.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0002_refresh_tokens.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0002_refresh_tokens.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0002_refresh_tokens.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0003_user_configs.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0003_user_configs.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0003_user_configs.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0004_tool_types.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0004_tool_types.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0004_tool_types.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0005_ssh_keys_timestamps.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0005_ssh_keys_timestamps.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0005_ssh_keys_timestamps.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0006_tool_instances.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0006_tool_instances.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0006_tool_instances.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0007_instance_container_name.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0007_instance_container_name.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0007_instance_container_name.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0008_tool_type_category.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0008_tool_type_category.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0008_tool_type_category.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0009_tool_configs.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0009_tool_configs.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0009_tool_configs.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0010_tool_type_default_port.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0010_tool_type_default_port.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0010_tool_type_default_port.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0011_tool_instance_tunnel_fields.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0011_tool_instance_tunnel_fields.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0011_tool_instance_tunnel_fields.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0012_default_port_req.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0012_default_port_req.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0012_default_port_req.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0013_add_probe_result.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0013_add_probe_result.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0013_add_probe_result.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0014_merge_heads.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0014_merge_heads.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0014_merge_heads.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/0015_single_interface.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/0015_single_interface.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/0015_single_interface.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/20260527160017_add_pi_agent_tool_type.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/20260527160017_add_pi_agent_tool_type.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/20260527160017_add_pi_agent_tool_type.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_22_add_clone_mode.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_22_add_clone_mode.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_22_add_clone_mode.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_23_remove_is_builtin.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_23_remove_is_builtin.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_23_remove_is_builtin.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_220141_add_startup_command.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_220141_add_startup_command.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_220141_add_startup_command.py","metadata":{"featureKind":"cli-command","trustBoundaries":["network","external-api","serialization","user-input","process-exec"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_add_config_profiles.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_add_config_profiles.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_24_add_config_profiles.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_26_add_git_mounts.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_26_add_git_mounts.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_26_add_git_mounts.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_27_external_repos.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_27_external_repos.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_27_external_repos.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/398082499c30_add_tool_config_fields.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/398082499c30_add_tool_config_fields.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/398082499c30_add_tool_config_fields.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/8ed7dd80973d_create_config_folders_table.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/8ed7dd80973d_create_config_folders_table.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/8ed7dd80973d_create_config_folders_table.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/af8512103d67_add_tool_type_fields.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/af8512103d67_add_tool_type_fields.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/af8512103d67_add_tool_type_fields.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/f3d2dc90ba3a_merge_single_interface_and_clone_mode.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/f3d2dc90ba3a_merge_single_interface_and_clone_mode.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/f3d2dc90ba3a_merge_single_interface_and_clone_mode.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/auth.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/auth.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/auth.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/config_folders.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/config_folders.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/config_folders.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/config_profiles.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/config_profiles.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/config_profiles.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/dashboard.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/dashboard.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/dashboard.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/git_repositories.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/git_repositories.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/git_repositories.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/health.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/health.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/health.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/instance_proxy.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/instance_proxy.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/instance_proxy.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/projects.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/projects.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/projects.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/shared_validators.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/shared_validators.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/shared_validators.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/ssh_keys.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/ssh_keys.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/ssh_keys.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/terminal.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/terminal.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/terminal.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/tool_configs.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/tool_configs.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/tool_configs.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/tool_definitions.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/tool_definitions.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/tool_definitions.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/tool_instances.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/tool_instances.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/tool_instances.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/tool_types.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/tool_types.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/tool_types.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/tool_types_validation.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/tool_types_validation.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/tool_types_validation.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/user_config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/user_config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/user_config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/api/users.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/api/users.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/api/users.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/auth/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/auth/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/auth/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/auth/cookies.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/auth/cookies.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/auth/cookies.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/auth/dependencies.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/auth/dependencies.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/auth/dependencies.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/auth/oidc.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/auth/oidc.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/auth/oidc.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/auth/session.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/auth/session.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/auth/session.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/database.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/database.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/database.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/logging_config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/logging_config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/logging_config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/main.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/main.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/main.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/base.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/base.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/base.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/config_folder.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/config_folder.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/config_folder.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/config_profile.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/config_profile.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/config_profile.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/git_repository.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/git_repository.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/git_repository.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/project.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/project.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/project.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/ssh_key.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/ssh_key.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/ssh_key.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/tool_config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/tool_config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/tool_config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/tool_definition_manifest.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/tool_definition_manifest.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/tool_definition_manifest.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/tool_instance.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/tool_instance.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/tool_instance.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/tool_type.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/tool_type.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/tool_type.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/user.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/user.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/user.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/models/user_config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/models/user_config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/models/user_config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/scripts/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/scripts/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/scripts/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/scripts/seed.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/scripts/seed.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/scripts/seed.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/clone.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/clone.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/clone.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/config_profile_resolver.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/config_profile_resolver.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/config_profile_resolver.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/docker.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/docker.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/docker.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/docker_build.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/docker_build.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/docker_build.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/manifest_compiler.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/manifest_compiler.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/manifest_compiler.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/permission_fixer.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/permission_fixer.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/permission_fixer.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/readiness_probe.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/readiness_probe.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/readiness_probe.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/ssh_keys.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/ssh_keys.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/ssh_keys.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/terminal_manager.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/terminal_manager.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/terminal_manager.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/services/terminal_session.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/services/terminal_session.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/services/terminal_session.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/src/utils/git_control.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/utils/git_control.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/utils/git_control.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/utils/git_files.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/utils/git_files.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/utils/git_files.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/utils/git_history.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/utils/git_history.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/utils/git_history.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/src/utils/git_url_parser.py",{"id":"file:/home/alex/projects/headquarter/apps/api/src/utils/git_url_parser.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/src/utils/git_url_parser.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/conftest.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/conftest.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/conftest.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_api.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_services.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_services.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_auth_services.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_config_folders_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_config_folders_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_config_folders_api.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_config_profiles_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_config_profiles_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_config_profiles_api.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_git_control.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_git_control.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_git_control.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_models.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_models.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_models.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_projects_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_projects_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_projects_api.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_seed.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_seed.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_seed.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_ssh_keys_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_ssh_keys_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_ssh_keys_api.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_configs_api_extended.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_configs_api_extended.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_configs_api_extended.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api_extended.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api_extended.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_tool_types_api_extended.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/integration/test_users_api.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/integration/test_users_api.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/integration/test_users_api.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/system/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/system/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/system/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/__init__.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/__init__.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/__init__.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_config.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_config.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_config.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_config_profile_resolver.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_config_profile_resolver.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_config_profile_resolver.py","metadata":{"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_build.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_build.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_build.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_service.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_service.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_docker_service.py","metadata":{"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_mount_resolution.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_mount_resolution.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_git_mount_resolution.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_clone_preflight.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_clone_preflight.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_clone_preflight.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_working_clones.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_working_clones.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_git_repository_working_clones.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_url_parser.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_git_url_parser.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_git_url_parser.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_manifest_compiler.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_manifest_compiler.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_manifest_compiler.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_migration_metadata.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_migration_metadata.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_migration_metadata.py","metadata":{"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_permission_fixer.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_permission_fixer.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_permission_fixer.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_readiness_probe.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_readiness_probe.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_readiness_probe.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/api/tests/unit/test_session_branch_selection.py",{"id":"file:/home/alex/projects/headquarter/apps/api/tests/unit/test_session_branch_selection.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/tests/unit/test_session_branch_selection.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_28_add_tool_definition_manifests.py",{"id":"file:/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_28_add_tool_definition_manifests.py","kind":"file","language":"python","filePath":"/home/alex/projects/headquarter/apps/api/alembic/versions/2026_05_28_add_tool_definition_manifests.py","metadata":{"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}]],"edges":[]} \ No newline at end of file diff --git a/apps/api/alembic/versions/2026_05_28_add_terminal_sessions_table.py b/apps/api/alembic/versions/2026_05_28_add_terminal_sessions_table.py new file mode 100644 index 0000000..11f2364 --- /dev/null +++ b/apps/api/alembic/versions/2026_05_28_add_terminal_sessions_table.py @@ -0,0 +1,61 @@ +"""add terminal_sessions table + +Revision ID: 2026_05_28_add_terminal_sessions +Revises: 20260527_160017_add_pi_agent +Create Date: 2026-05-28 + +""" + +from collections.abc import Sequence + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision: str = "2026_05_28_add_terminal_sessions" +down_revision: str | None = "2026_05_28_add_tool_definition_manifests" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.create_table( + "terminal_sessions", + sa.Column("id", sa.UUID(), nullable=False), + sa.Column("instance_id", sa.UUID(), nullable=False), + sa.Column("name", sa.String(length=255), nullable=True), + sa.Column("status", sa.String(length=50), nullable=False), + sa.Column("last_activity_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("closed_at", sa.DateTime(timezone=True), nullable=True), + sa.Column( + "created_at", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=False, + ), + sa.Column( + "updated_at", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + onupdate=sa.text("now()"), + nullable=False, + ), + sa.ForeignKeyConstraint( + ["instance_id"], ["tool_instances.id"], ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_terminal_sessions_instance_id"), + "terminal_sessions", + ["instance_id"], + unique=False, + ) + + +def downgrade() -> None: + op.drop_index( + op.f("ix_terminal_sessions_instance_id"), + table_name="terminal_sessions", + ) + op.drop_table("terminal_sessions") diff --git a/apps/api/src/api/terminal.py b/apps/api/src/api/terminal.py index 1da1643..8dfc4db 100644 --- a/apps/api/src/api/terminal.py +++ b/apps/api/src/api/terminal.py @@ -1,16 +1,20 @@ """WebSocket terminal endpoint for tool instances.""" import asyncio +import json import logging import uuid +from contextlib import suppress from fastapi import APIRouter, Depends, HTTPException, WebSocket, status +from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from src.auth.dependencies import get_db_session +from src.auth.dependencies import get_current_user_id, get_db_session +from src.models.terminal_session import TerminalSessionModel from src.models.tool_instance import ToolInstance from src.models.tool_type import ToolType -from src.services.terminal_manager import terminal_manager +from src.services.terminal_manager import MaxSessionsExceededError, terminal_manager router = APIRouter() logger = logging.getLogger(__name__) @@ -19,32 +23,58 @@ logger = logging.getLogger(__name__) class SessionRef: """Mutable reference to a terminal session, allowing updates during reset.""" - def __init__(self, session): + def __init__(self, session, slot_session_id: str | None = None): self.session = session + self.slot_session_id = slot_session_id or session.session_id @router.websocket( "/ws/tool-instances/{instance_id}/terminal", ) -async def terminal_websocket( +async def terminal_websocket_default( websocket: WebSocket, instance_id: str, db_session: AsyncSession = Depends(get_db_session), ) -> None: - """WebSocket endpoint for terminal access to a tool instance. + """WebSocket endpoint for terminal access (default session alias). - Provides an interactive terminal session inside a running tool instance container. - Sessions persist across WebSocket disconnections. + Backward-compatible route that maps to the default session. + """ + await _handle_terminal_websocket(websocket, instance_id, None, db_session) + + +@router.websocket( + "/ws/tool-instances/{instance_id}/terminal/{session_id}", +) +async def terminal_websocket_specific( + websocket: WebSocket, + instance_id: str, + session_id: str, + db_session: AsyncSession = Depends(get_db_session), +) -> None: + """WebSocket endpoint for a specific terminal session.""" + await _handle_terminal_websocket(websocket, instance_id, session_id, db_session) + + +async def _handle_terminal_websocket( + websocket: WebSocket, + instance_id: str, + target_session_id: str | None, + db_session: AsyncSession, +) -> None: + """Shared WebSocket handler for terminal sessions. Args: websocket: The WebSocket connection. instance_id: UUID string of the tool instance. + target_session_id: Specific session ID (slot key). None means default session. db_session: Database session. - - Returns: - None. Communicates via WebSocket messages. """ - logger.debug("Terminal WebSocket connection attempt for instance %s", instance_id) + logger.debug( + "Terminal WebSocket connection attempt for instance %s (session=%s)", + instance_id, + target_session_id or "default", + ) await websocket.accept() logger.debug("Terminal WebSocket accepted for instance %s", instance_id) @@ -59,7 +89,9 @@ async def terminal_websocket( # Authenticate user from session cookie user_id = await _get_user_from_websocket(websocket, db_session) if user_id is None: - logger.warning("Unauthorized terminal access attempt for instance %s", instance_id) + logger.warning( + "Unauthorized terminal access attempt for instance %s", instance_id + ) await websocket.close(code=4003, reason="Unauthorized") return @@ -71,12 +103,21 @@ async def terminal_websocket( return if instance.owner_id != user_id: - logger.warning("Forbidden terminal access for instance %s by user %s", instance_id, user_id) + logger.warning( + "Forbidden terminal access for instance %s by user %s", + instance_id, + user_id, + ) await websocket.close(code=4003, reason="Forbidden") return if instance.status != "running" or not instance.container_id: - logger.warning("Instance %s not running (status=%s, container_id=%s)", instance_id, instance.status, instance.container_id) + logger.warning( + "Instance %s not running (status=%s, container_id=%s)", + instance_id, + instance.status, + instance.container_id, + ) await websocket.close(code=4004, reason="Instance not running") return @@ -86,16 +127,50 @@ async def terminal_websocket( tool_type = await db_session.get(ToolType, instance.tool_type_id) startup_command = tool_type.startup_command if tool_type else None if startup_command: - logger.debug("Using startup command for instance %s: %s", instance_id, startup_command) + logger.debug( + "Using startup command for instance %s: %s", + instance_id, + startup_command, + ) + + session = None # Get or create terminal session try: - session = await terminal_manager.get_or_create_session( - instance_uuid, - instance.container_id, - startup_command=startup_command, + if target_session_id is None: + # Default session alias + session = await terminal_manager.get_or_create_session( + instance_uuid, + instance.container_id, + startup_command=startup_command, + ) + slot_session_id = "default" + else: + # Specific session + session = terminal_manager.get_session( + instance_id, + target_session_id, + ) + if session is None: + logger.warning( + "Session %s not found for instance %s", + target_session_id, + instance_id, + ) + await websocket.close(code=4004, reason="Session not found") + return + # Determine slot key for reset scoping + key = terminal_manager._find_key_by_internal_id( + instance_id, session.session_id + ) + slot_session_id = key[1] if key else target_session_id + + logger.debug( + "Terminal session ready for instance %s (session_id=%s, slot=%s)", + instance_id, + session.session_id, + slot_session_id, ) - logger.debug("Terminal session ready for instance %s (session_id=%s)", instance_id, session.session_id) # Attach WebSocket to session await terminal_manager.attach_websocket(session, websocket) @@ -106,11 +181,13 @@ async def terminal_websocket( logger.debug("Sent connected status for instance %s", instance_id) # Use mutable session reference so loops can survive reset - session_ref = SessionRef(session) + session_ref = SessionRef(session, slot_session_id) # Start I/O loops and heartbeat read_task = asyncio.create_task(_read_loop(session_ref, websocket)) - write_task = asyncio.create_task(_write_loop(session_ref, websocket, instance_id)) + write_task = asyncio.create_task( + _write_loop(session_ref, websocket, instance_id) + ) heartbeat_task = asyncio.create_task(_heartbeat_loop(websocket)) logger.debug("Started terminal loops for instance %s", instance_id) @@ -119,24 +196,33 @@ async def terminal_websocket( [read_task, write_task, heartbeat_task], return_when=asyncio.FIRST_COMPLETED, ) - - logger.debug("Terminal loop completed for instance %s, done=%s", instance_id, len(done)) - + + logger.debug( + "Terminal loop completed for instance %s, done=%s", + instance_id, + len(done), + ) + # Cancel remaining tasks for task in pending: task.cancel() except Exception as exc: - logger.error("Terminal session error for instance %s: %s", instance_id, str(exc), exc_info=True) + logger.error( + "Terminal session error for instance %s: %s", + instance_id, + str(exc), + exc_info=True, + ) await websocket.close(code=4000, reason=f"Error: {exc}") finally: # Detach WebSocket, don't kill session - try: - if 'session' in locals(): + with suppress(Exception): + if session is not None: await terminal_manager.detach_websocket(session, websocket) - logger.debug("WebSocket detached from session for instance %s", instance_id) - except Exception: - pass + logger.debug( + "WebSocket detached from session for instance %s", instance_id + ) async def _read_loop(session_ref: SessionRef, websocket) -> None: @@ -175,38 +261,54 @@ async def _write_loop(session_ref: SessionRef, websocket, instance_id: str) -> N text = message["text"] if text.startswith("{"): # Control message (JSON) - import json try: ctrl = json.loads(text) msg_type = ctrl.get("type") - + if msg_type == "resize": cols = ctrl.get("cols", 80) rows = ctrl.get("rows", 24) - logger.debug(f"Received resize message for instance {instance_id}: {cols}x{rows}") + logger.debug( + "Received resize message for instance %s: %sx%s", + instance_id, + cols, + rows, + ) await session.resize(cols, rows) elif msg_type == "reset": - # Reset terminal session - logger.debug("Resetting terminal session for instance %s", session.instance_id) - await websocket.send_json({"type": "status", "status": "resetting"}) - - # Reset the session + # Reset terminal session (scoped to current slot) + logger.debug( + "Resetting terminal session for instance %s (slot=%s)", + session.instance_id, + session_ref.slot_session_id, + ) + await websocket.send_json( + {"type": "status", "status": "resetting"} + ) + + # Reset the session scoped to its slot new_session = await terminal_manager.reset_session( session.instance_id, session.container_id, startup_command=session.startup_command, + session_id=session_ref.slot_session_id, + name=session.name, ) - - # Update the mutable session reference so read_loop uses the new session + + # Update the mutable session reference session_ref.session = new_session - + # Attach to new session - await terminal_manager.attach_websocket(new_session, websocket) - await websocket.send_json({"type": "status", "status": "connected"}) - + await terminal_manager.attach_websocket( + new_session, websocket + ) + await websocket.send_json( + {"type": "status", "status": "connected"} + ) + # Continue the loop with the new session continue - + except json.JSONDecodeError: # Not a valid JSON control message, treat as regular input await session.write_input(text.encode("utf-8")) @@ -232,56 +334,347 @@ async def _heartbeat_loop(websocket: WebSocket) -> None: pass -@router.post( - "/projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/terminal/reset", - summary="Reset terminal session", - description="Reset the terminal session for a tool instance, killing the current shell and starting fresh.", -) -async def reset_terminal_session( - project_id: uuid.UUID, - repo_id: uuid.UUID, +async def _get_terminal_instance( instance_id: uuid.UUID, - db_session: AsyncSession = Depends(get_db_session), -) -> dict: - """Reset the terminal session for an instance. + user_id: uuid.UUID, + db_session: AsyncSession, +) -> ToolInstance: + """Fetch instance and validate auth, ownership, and running status. Args: - project_id: UUID of the project. - repo_id: UUID of the repository. instance_id: UUID of the tool instance. + user_id: ID of the authenticated user. db_session: Database session. Returns: - Dictionary with status message. + The validated ToolInstance. + + Raises: + HTTPException: If instance not found, not owned, or not running. """ - # Get instance and verify it exists and is running instance = await db_session.get(ToolInstance, instance_id) if instance is None: raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Instance not found" + status_code=status.HTTP_404_NOT_FOUND, detail="Instance not found" + ) + + if instance.owner_id != user_id: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Not authorized to access this instance", ) if instance.status != "running" or not instance.container_id: raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Instance is not running" + status_code=status.HTTP_400_BAD_REQUEST, detail="Instance is not running" + ) + + return instance + + +@router.get( + "/instances/{instance_id}/terminal/sessions", + summary="List terminal sessions", + description="List terminal sessions for a tool instance with live WebSocket state.", +) +async def list_terminal_sessions( + instance_id: uuid.UUID, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """List terminal sessions for an instance. + + Args: + instance_id: UUID of the tool instance. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with sessions list. + """ + await _get_terminal_instance(instance_id, user_id, db_session) + + # Query active DB rows for this instance + result = await db_session.execute( + select(TerminalSessionModel) + .where(TerminalSessionModel.instance_id == instance_id) + .where(TerminalSessionModel.status != "closed") + .order_by(TerminalSessionModel.created_at.asc()) + ) + db_rows = result.scalars().all() + + # Build response with live has_websockets flag + sessions = [] + for row in db_rows: + live_session = terminal_manager.get_session(str(instance_id), str(row.id)) + sessions.append( + { + "id": str(row.id), + "name": row.name, + "status": row.status, + "has_websockets": live_session.has_websockets() + if live_session + else False, + "created_at": row.created_at.isoformat() if row.created_at else None, + "last_activity_at": row.last_activity_at.isoformat() + if row.last_activity_at + else None, + } + ) + + return {"sessions": sessions} + + +@router.post( + "/instances/{instance_id}/terminal/sessions", + summary="Create terminal session", + description="Create a new terminal session for a running tool instance.", + status_code=status.HTTP_201_CREATED, +) +async def create_terminal_session( + instance_id: uuid.UUID, + data: dict, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """Create a new terminal session. + + Args: + instance_id: UUID of the tool instance. + data: Request body with optional name. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with new session details. + + Raises: + HTTPException: 409 if max sessions reached. + """ + instance = await _get_terminal_instance(instance_id, user_id, db_session) + assert instance.container_id is not None + + # Fetch tool type to get startup_command + tool_type = await db_session.get(ToolType, instance.tool_type_id) + startup_command = tool_type.startup_command if tool_type else None + + name = data.get("name") + + try: + session = await terminal_manager.create_session( + instance_id, + instance.container_id, + startup_command=startup_command, + name=name, + ) + except MaxSessionsExceededError: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, + detail="Maximum of 5 terminal sessions reached for this instance", + ) from None + + return { + "id": session.session_id, + "name": session.name, + "status": session.status, + "created_at": session.last_activity, + } + + +@router.delete( + "/instances/{instance_id}/terminal/sessions/{session_id}", + summary="Close terminal session", + description="Close a specific terminal session.", +) +async def close_terminal_session( + instance_id: uuid.UUID, + session_id: str, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """Close a terminal session. + + Args: + instance_id: UUID of the tool instance. + session_id: ID of the session to close. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with closure status. + """ + await _get_terminal_instance(instance_id, user_id, db_session) + + # Find the session by internal ID to determine its slot key + key = terminal_manager._find_key_by_internal_id(str(instance_id), session_id) + if ( + key is None + and terminal_manager.get_session(str(instance_id), session_id) is not None + ): + key = (str(instance_id), session_id) + + if key is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Session not found" + ) + + await terminal_manager.close_session(key[0], key[1]) + + return {"status": "closed", "session_id": session_id} + + +@router.post( + "/instances/{instance_id}/terminal/sessions/{session_id}/reset", + summary="Reset terminal session", + description="Reset a specific terminal session, killing the current shell and starting fresh.", +) +async def reset_specific_terminal_session( + instance_id: uuid.UUID, + session_id: str, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """Reset a specific terminal session. + + Args: + instance_id: UUID of the tool instance. + session_id: ID of the session to reset. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with reset session details. + """ + instance = await _get_terminal_instance(instance_id, user_id, db_session) + assert instance.container_id is not None + + # Determine slot key for reset + key = terminal_manager._find_key_by_internal_id(str(instance_id), session_id) + if ( + key is None + and terminal_manager.get_session(str(instance_id), session_id) is not None + ): + key = (str(instance_id), session_id) + + if key is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Session not found" ) # Fetch tool type to get startup_command tool_type = await db_session.get(ToolType, instance.tool_type_id) startup_command = tool_type.startup_command if tool_type else None + # Preserve name if possible + live_session = terminal_manager.get_session(str(instance_id), session_id) + name = live_session.name if live_session else None + + new_session = await terminal_manager.reset_session( + instance_id, + instance.container_id, + startup_command=startup_command, + session_id=key[1], + name=name, + ) + + return { + "id": new_session.session_id, + "name": new_session.name, + "status": new_session.status, + } + + +@router.post( + "/instances/{instance_id}/terminal/sessions/{session_id}/rename", + summary="Rename terminal session", + description="Rename a specific terminal session.", +) +async def rename_terminal_session( + instance_id: uuid.UUID, + session_id: str, + data: dict, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """Rename a terminal session. + + Args: + instance_id: UUID of the tool instance. + session_id: ID of the session to rename. + data: Request body with new name. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with updated session details. + """ + await _get_terminal_instance(instance_id, user_id, db_session) + + new_name = data.get("name") + if not new_name or not isinstance(new_name, str): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail="Name is required" + ) + + # Update in-memory session name if live + live_session = terminal_manager.get_session(str(instance_id), session_id) + if live_session: + live_session.name = new_name + + # Update DB row + db_row = await db_session.get(TerminalSessionModel, uuid.UUID(session_id)) + if db_row is None: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Session not found" + ) + + db_row.name = new_name + await db_session.commit() + + return {"id": str(db_row.id), "name": new_name} + + +@router.post( + "/instances/{instance_id}/terminal/reset", + summary="Reset terminal session (legacy alias)", + description="Reset the default terminal session for a tool instance. Preserved for backward compatibility.", +) +async def reset_terminal_session( + instance_id: uuid.UUID, + user_id: uuid.UUID = Depends(get_current_user_id), + db_session: AsyncSession = Depends(get_db_session), +) -> dict: + """Reset the default terminal session for an instance (legacy alias). + + Args: + instance_id: UUID of the tool instance. + user_id: ID of the authenticated user. + db_session: Database session. + + Returns: + Dictionary with status message. + """ + instance = await _get_terminal_instance(instance_id, user_id, db_session) + assert instance.container_id is not None + + # Fetch tool type to get startup_command + tool_type = await db_session.get(ToolType, instance.tool_type_id) + startup_command = tool_type.startup_command if tool_type else None + try: - # Reset the session + # Reset the default session new_session = await terminal_manager.reset_session( instance_id, instance.container_id, startup_command=startup_command, ) - - logger.info("Terminal session reset for instance %s (new session_id=%s)", instance_id, new_session.session_id) - + + logger.info( + "Terminal session reset for instance %s (new session_id=%s)", + instance_id, + new_session.session_id, + ) + return { "status": "success", "message": "Terminal session reset successfully", @@ -289,11 +682,16 @@ async def reset_terminal_session( "session_id": new_session.session_id, } except Exception as exc: - logger.error("Failed to reset terminal session for instance %s: %s", instance_id, str(exc), exc_info=True) + logger.error( + "Failed to reset terminal session for instance %s: %s", + instance_id, + str(exc), + exc_info=True, + ) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"Failed to reset terminal session: {exc}" - ) + detail=f"Failed to reset terminal session: {exc}", + ) from exc async def _get_user_from_websocket( diff --git a/apps/api/src/main.py b/apps/api/src/main.py index c2dfc23..3b19ed2 100644 --- a/apps/api/src/main.py +++ b/apps/api/src/main.py @@ -25,6 +25,7 @@ from src.api.tool_types import router as tool_types_router from src.api.user_config import router as user_config_router from src.api.users import router as users_router from src.config import Settings +from src.models.terminal_session import TerminalSessionModel # noqa: F401 – Alembic model discovery from src.database import init_database from src.logging_config import ( ExceptionLoggingMiddleware, diff --git a/apps/api/src/models/__init__.py b/apps/api/src/models/__init__.py index f6b8e31..79e88ff 100644 --- a/apps/api/src/models/__init__.py +++ b/apps/api/src/models/__init__.py @@ -4,6 +4,7 @@ from src.models.config_profile import ConfigProfile, ConfigProfileInclude from src.models.git_repository import GitRepository from src.models.project import Project from src.models.ssh_key import SSHKey +from src.models.terminal_session import TerminalSessionModel from src.models.tool_definition_manifest import ToolDefinitionManifest from src.models.tool_instance import ToolInstance from src.models.tool_type import ToolType @@ -18,6 +19,7 @@ __all__ = [ "GitRepository", "Project", "SSHKey", + "TerminalSessionModel", "ToolDefinitionManifest", "ToolInstance", "ToolType", diff --git a/apps/api/src/models/terminal_session.py b/apps/api/src/models/terminal_session.py new file mode 100644 index 0000000..20e6f3a --- /dev/null +++ b/apps/api/src/models/terminal_session.py @@ -0,0 +1,37 @@ +"""Terminal session database model.""" + +import uuid +from datetime import datetime + +from sqlalchemy import DateTime, ForeignKey, String +from sqlalchemy import Uuid as UUID +from sqlalchemy.orm import Mapped, mapped_column + +from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin + + +class TerminalSessionModel(UUIDPrimaryKeyMixin, TimestampMixin, Base): + """Database model for terminal session metadata.""" + + __tablename__ = "terminal_sessions" + + instance_id: Mapped[uuid.UUID] = mapped_column( + UUID(), + ForeignKey("tool_instances.id", ondelete="CASCADE"), + nullable=False, + index=True, + ) + name: Mapped[str | None] = mapped_column(String(255), nullable=True) + status: Mapped[str] = mapped_column( + String(50), + nullable=False, + default="active", + ) + last_activity_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), + nullable=True, + ) + closed_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), + nullable=True, + ) diff --git a/apps/api/src/services/terminal_manager.py b/apps/api/src/services/terminal_manager.py index f83eac1..5ee12a4 100644 --- a/apps/api/src/services/terminal_manager.py +++ b/apps/api/src/services/terminal_manager.py @@ -3,20 +3,37 @@ import asyncio import logging import uuid +from datetime import datetime, timezone from fastapi import WebSocket +from src.database import SessionLocal +from src.models.terminal_session import TerminalSessionModel from src.services.terminal_session import TerminalSession logger = logging.getLogger(__name__) +class MaxSessionsExceededError(Exception): + """Raised when the maximum number of terminal sessions per instance is reached.""" + + def __init__(self, instance_id: str, max_sessions: int = 5) -> None: + self.instance_id = instance_id + self.max_sessions = max_sessions + super().__init__( + f"Maximum of {max_sessions} terminal sessions reached for instance {instance_id}" + ) + + class TerminalManager: """Manages active terminal sessions with persistence support.""" + # Maximum sessions per tool instance + MAX_SESSIONS_PER_INSTANCE = 5 + def __init__(self) -> None: - # Track sessions by instance_id for persistence - self._sessions: dict[str, TerminalSession] = {} + # Track sessions by (instance_id, session_id) for multi-session support + self._sessions: dict[tuple[str, str], TerminalSession] = {} self._idle_check_task: asyncio.Task | None = None self._start_idle_check() @@ -42,16 +59,131 @@ class TerminalManager: async def _cleanup_idle_sessions(self) -> None: """Clean up sessions that have been idle for too long.""" - idle_sessions = [] - for instance_id, session in list(self._sessions.items()): + idle_keys = [] + for (instance_id, session_id), session in list(self._sessions.items()): if session.is_idle(): - idle_sessions.append(instance_id) - - for instance_id in idle_sessions: - logger.info("Cleaning up idle terminal session for instance %s", instance_id) - session = self._sessions.pop(instance_id, None) + idle_keys.append((instance_id, session_id)) + + for key in idle_keys: + instance_id, session_id = key + logger.info( + "Cleaning up idle terminal session %s for instance %s", + session_id, + instance_id, + ) + session = self._sessions.pop(key, None) if session: await session.close() + # Update DB status fire-and-forget + asyncio.create_task(self._mark_closed_in_db(session_id)) + + async def _insert_db_session_row( + self, + session_id: str, + instance_id: uuid.UUID, + name: str, + ) -> None: + """Insert a TerminalSessionModel row into the database.""" + try: + async with SessionLocal() as db_session: + db_row = TerminalSessionModel( + id=uuid.UUID(session_id), + instance_id=instance_id, + name=name, + status="active", + created_at=datetime.now(timezone.utc), + last_activity_at=datetime.now(timezone.utc), + ) + db_session.add(db_row) + await db_session.commit() + logger.debug( + "Inserted terminal session row %s for instance %s", + session_id, + instance_id, + ) + except Exception as exc: + logger.error("Failed to insert terminal session row: %s", exc) + + async def _mark_closed_in_db(self, session_id: str) -> None: + """Mark a terminal session as closed in the database.""" + try: + async with SessionLocal() as db_session: + db_row = await db_session.get( + TerminalSessionModel, uuid.UUID(session_id) + ) + if db_row: + db_row.status = "closed" + db_row.closed_at = datetime.now(timezone.utc) + await db_session.commit() + logger.debug( + "Marked terminal session %s as closed in DB", session_id + ) + except Exception as exc: + logger.error("Failed to mark terminal session as closed in DB: %s", exc) + + def _count_sessions_for_instance(self, instance_id_str: str) -> int: + """Count active in-memory sessions for a given instance.""" + return sum(1 for (iid, _sid) in self._sessions if iid == instance_id_str) + + async def create_session( + self, + instance_id: uuid.UUID, + container_id: str, + startup_command: str | None = None, + name: str | None = None, + ) -> TerminalSession: + """Create a new terminal session for an instance. + + Enforces a maximum of MAX_SESSIONS_PER_INSTANCE sessions per instance. + Inserts a DB row fire-and-forget. + + Args: + instance_id: UUID of the tool instance. + container_id: Docker container ID. + startup_command: Optional startup command to run. + name: Optional session name (auto-generated if omitted). + + Returns: + The newly created TerminalSession. + + Raises: + MaxSessionsExceededError: If the instance already has max sessions. + """ + instance_id_str = str(instance_id) + + if ( + self._count_sessions_for_instance(instance_id_str) + >= self.MAX_SESSIONS_PER_INSTANCE + ): + raise MaxSessionsExceededError( + instance_id_str, self.MAX_SESSIONS_PER_INSTANCE + ) + + session_id = str(uuid.uuid4()) + session = TerminalSession( + session_id=session_id, + instance_id=instance_id, + container_id=container_id, + startup_command=startup_command, + name=name, + ) + await session.start(startup_command=startup_command) + + key = (instance_id_str, session_id) + self._sessions[key] = session + + # Fire-and-forget DB insert + asyncio.create_task( + self._insert_db_session_row(session_id, instance_id, session.name) + ) + + logger.info( + "Created terminal session %s for instance %s (name=%s)", + session_id, + instance_id, + session.name, + ) + return session async def get_or_create_session( self, @@ -59,61 +191,146 @@ class TerminalManager: container_id: str, startup_command: str | None = None, ) -> TerminalSession: - """Get existing session or create a new one.""" + """Get existing session or create a new one. + + Backward-compatible alias that uses 'default' as the session_id. + """ # Ensure idle check is running (lazy start) self._start_idle_check() - + instance_id_str = str(instance_id) - - # Check for existing session - if instance_id_str in self._sessions: - session = self._sessions[instance_id_str] - + key = (instance_id_str, "default") + + # Check for existing default session + if key in self._sessions: + session = self._sessions[key] + # Check if session is still alive if session.is_alive(): - logger.debug("Reattaching to existing terminal session for instance %s", instance_id) + logger.debug( + "Reattaching to existing terminal session for instance %s", + instance_id, + ) return session else: # Session died, clean it up - logger.debug("Existing session for instance %s is dead, cleaning up", instance_id) + logger.debug( + "Existing session for instance %s is dead, cleaning up", + instance_id, + ) await session.close() - del self._sessions[instance_id_str] - - # Create new session - logger.info("Creating new terminal session for instance %s", instance_id) + del self._sessions[key] + + # Create new default session + logger.info( + "Creating new default terminal session for instance %s", instance_id + ) session_id = str(uuid.uuid4()) - session = TerminalSession(session_id, instance_id, container_id, startup_command=startup_command) + session = TerminalSession( + session_id=session_id, + instance_id=instance_id, + container_id=container_id, + startup_command=startup_command, + name="Session 1", + ) await session.start(startup_command=startup_command) - self._sessions[instance_id_str] = session - + self._sessions[key] = session + + # Fire-and-forget DB insert + asyncio.create_task( + self._insert_db_session_row(session_id, instance_id, session.name) + ) + return session + def get_session( + self, + instance_id: str, + session_id: str, + ) -> TerminalSession | None: + """Lookup a session by composite key, or by internal session_id.""" + session = self._sessions.get((instance_id, session_id)) + if session is not None: + return session + # Fallback: search by internal TerminalSession.session_id + for (iid, _sid), sess in self._sessions.items(): + if iid == instance_id and sess.session_id == session_id: + return sess + return None + + def _find_key_by_internal_id( + self, + instance_id: str, + internal_session_id: str, + ) -> tuple[str, str] | None: + """Find the manager dict key for a session by its internal session_id.""" + for (iid, sid), session in self._sessions.items(): + if iid == instance_id and session.session_id == internal_session_id: + return (iid, sid) + return None + + def get_sessions_for_instance( + self, + instance_id: str, + ) -> list[TerminalSession]: + """Return all in-memory sessions for a given instance.""" + return [ + session + for (iid, _sid), session in self._sessions.items() + if iid == instance_id + ] + + async def close_session( + self, + instance_id: str, + session_id: str, + ) -> None: + """Close a specific session and update its DB status.""" + key = (instance_id, session_id) + session = self._sessions.pop(key, None) + if session: + await session.close() + # Fire-and-forget DB update + asyncio.create_task(self._mark_closed_in_db(session_id)) + logger.info( + "Closed terminal session %s for instance %s", + session_id, + instance_id, + ) + async def attach_websocket( self, session: TerminalSession, websocket: WebSocket, ) -> None: - """Attach a WebSocket to an existing session.""" - # Handle concurrent connections - close existing ones + """Attach a WebSocket to an existing session. + + Closes existing WebSocket connections only for this specific session. + """ + # Handle concurrent connections - close existing ones within the same session if session.has_websockets(): - logger.debug("Closing existing WebSocket connections for instance %s", session.instance_id) + logger.debug( + "Closing existing WebSocket connections for session %s (instance %s)", + session.session_id, + session.instance_id, + ) for ws in list(session._websockets): try: await ws.close(code=4000, reason="New connection established") except Exception: - pass + pass # noqa: S110 session._websockets.clear() - + # Attach new WebSocket session.attach_websocket(websocket) - + # Replay buffer buffer = session.get_buffer() if buffer: try: await websocket.send_bytes(buffer) except Exception: - pass + pass # noqa: S110 async def detach_websocket( self, @@ -128,23 +345,60 @@ class TerminalManager: instance_id: uuid.UUID, container_id: str, startup_command: str | None = None, + session_id: str | None = None, + name: str | None = None, ) -> TerminalSession: - """Reset a session by killing it and creating a new one.""" + """Reset a session by killing it and creating a new one. + + Args: + instance_id: UUID of the tool instance. + container_id: Docker container ID. + startup_command: Optional startup command. + session_id: Specific session to reset. If None, resets the default session. + name: Optional name to preserve for the new session. + + Returns: + The newly created TerminalSession. + """ instance_id_str = str(instance_id) - + target_session_id = session_id or "default" + key = (instance_id_str, target_session_id) + + # Preserve old name if not provided + old_name = name + if old_name is None and key in self._sessions: + old_name = self._sessions[key].name + # Close existing session if any - if instance_id_str in self._sessions: - logger.debug("Resetting terminal session for instance %s", instance_id) - old_session = self._sessions.pop(instance_id_str) + if key in self._sessions: + logger.debug( + "Resetting terminal session %s for instance %s", + target_session_id, + instance_id, + ) + old_session = self._sessions.pop(key) await old_session.close() - - # Create new session - session_id = str(uuid.uuid4()) - session = TerminalSession(session_id, instance_id, container_id, startup_command=startup_command) - await session.start(startup_command=startup_command) - self._sessions[instance_id_str] = session - - return session + # Fire-and-forget DB update for old session + asyncio.create_task(self._mark_closed_in_db(old_session.session_id)) + + # Create new session preserving the same session_id slot + new_session_id = str(uuid.uuid4()) + new_session = TerminalSession( + session_id=new_session_id, + instance_id=instance_id, + container_id=container_id, + startup_command=startup_command, + name=old_name or ("Session 1" if target_session_id == "default" else None), + ) + await new_session.start(startup_command=startup_command) + self._sessions[key] = new_session + + # Fire-and-forget DB insert + asyncio.create_task( + self._insert_db_session_row(new_session_id, instance_id, new_session.name) + ) + + return new_session async def close_all(self) -> None: """Close all active sessions.""" @@ -152,7 +406,7 @@ class TerminalManager: self._sessions.clear() for session in sessions: await session.close() - + if self._idle_check_task and not self._idle_check_task.done(): self._idle_check_task.cancel() diff --git a/apps/api/src/services/terminal_session.py b/apps/api/src/services/terminal_session.py index e27c999..1297a4a 100644 --- a/apps/api/src/services/terminal_session.py +++ b/apps/api/src/services/terminal_session.py @@ -18,18 +18,28 @@ logger = logging.getLogger(__name__) class TerminalSession: """Manages a single terminal session connected to a docker container. - + Supports persistent sessions that survive WebSocket disconnections. Multiple WebSocket connections can attach/detach from the same session. """ # Circular buffer size (10KB) BUFFER_SIZE = 10 * 1024 - + # Idle timeout in seconds (30 minutes) IDLE_TIMEOUT = 30 * 60 - def __init__(self, session_id: str, instance_id: uuid.UUID, container_id: str, startup_command: str | None = None) -> None: + # Session number counter per instance_id for auto-naming + _instance_counters: dict[str, int] = {} + + def __init__( + self, + session_id: str, + instance_id: uuid.UUID, + container_id: str, + startup_command: str | None = None, + name: str | None = None, + ) -> None: self.session_id = session_id self.instance_id = instance_id self.container_id = container_id @@ -38,37 +48,52 @@ class TerminalSession: self._closed = False self._master_fd: int | None = None self._slave_fd: int | None = None - + # Circular buffer for output replay self._output_buffer: deque[bytes] = deque(maxlen=self.BUFFER_SIZE) self._buffer_size = 0 - + # WebSocket connections self._websockets: set[Any] = set() - + # Activity tracking self.last_activity = time.time() - + # Terminal size self._cols = 80 self._rows = 24 + # Session metadata + self.name = name or self._generate_name(str(instance_id)) + self.status: str = "active" + + @classmethod + def _generate_name(cls, instance_id: str) -> str: + """Generate an auto-incremented session name for the instance.""" + count = cls._instance_counters.get(instance_id, 0) + 1 + cls._instance_counters[instance_id] = count + return f"Session {count}" + async def start(self, startup_command: str | None = None) -> None: """Start the docker exec process with a shell using a PTY.""" # Create a pseudo-terminal on the host self._master_fd, self._slave_fd = pty.openpty() - + # Set the terminal size initially self._set_terminal_size(self._cols, self._rows) - logger.debug(f"Starting terminal session {self.session_id} for container {self.container_id} with initial size {self._cols}x{self._rows}") - + logger.debug( + f"Starting terminal session {self.session_id} for container {self.container_id} with initial size {self._cols}x{self._rows}" + ) + # Build the shell command if startup_command: shell_cmd = f'bash -c "{startup_command}" || true; exec bash -il' - logger.debug(f"Using startup command for session {self.session_id}: {startup_command}") + logger.debug( + f"Using startup command for session {self.session_id}: {startup_command}" + ) else: shell_cmd = "bash -il" - + # Start docker exec with the slave fd as stdin/stdout/stderr # Using -it because the slave fd IS a TTY self.process = await asyncio.create_subprocess_exec( @@ -85,11 +110,11 @@ class TerminalSession: stdout=self._slave_fd, stderr=self._slave_fd, ) - + # Close slave fd in parent process os.close(self._slave_fd) self._slave_fd = None - + self.last_activity = time.time() def _set_terminal_size(self, cols: int, rows: int) -> None: @@ -99,7 +124,7 @@ class TerminalSession: return # TIOCSWINSZ = 0x5414 on Linux TIOCSWINSZ = 0x5414 - size = struct.pack('HHHH', rows, cols, 0, 0) + size = struct.pack("HHHH", rows, cols, 0, 0) try: fcntl.ioctl(self._master_fd, TIOCSWINSZ, size) logger.debug(f"Resized PTY to {cols}x{rows} (fd={self._master_fd})") @@ -127,7 +152,7 @@ class TerminalSession: """Add data to circular buffer, maintaining size limit.""" self._output_buffer.append(data) self._buffer_size += len(data) - + # Trim if exceeds max size while self._buffer_size > self.BUFFER_SIZE and self._output_buffer: removed = self._output_buffer.popleft() @@ -152,16 +177,16 @@ class TerminalSession: if self._closed: logger.warning("Cannot resize: session is closed") return - + # Only resize if dimensions actually changed if cols == self._cols and rows == self._rows: return - + self._cols = cols self._rows = rows logger.debug(f"resize() called for session {self.session_id}: {cols}x{rows}") self._set_terminal_size(cols, rows) - + # Docker exec -it creates its own PTY inside the container, # so host PTY resize doesn't propagate to the container shell. # Send SIGWINCH to the docker exec process on the host. @@ -170,14 +195,19 @@ class TerminalSession: if self.process and self.process.pid: try: os.kill(self.process.pid, signal.SIGWINCH) - logger.debug(f"Sent SIGWINCH to docker exec process {self.process.pid} for session {self.session_id}") + logger.debug( + f"Sent SIGWINCH to docker exec process {self.process.pid} for session {self.session_id}" + ) except ProcessLookupError: - logger.warning(f"docker exec process {self.process.pid} not found for session {self.session_id}") + logger.warning( + f"docker exec process {self.process.pid} not found for session {self.session_id}" + ) except Exception as e: logger.warning(f"Failed to send SIGWINCH: {e}") async def reset(self) -> None: """Reset the session by killing the process and clearing state.""" + self.status = "resetting" await self.close() self._closed = False self._output_buffer.clear() @@ -186,18 +216,20 @@ class TerminalSession: self.process = None self._master_fd = None self._slave_fd = None + self.status = "active" async def close(self) -> None: """Close the session and cleanup.""" if self._closed: return self._closed = True + self.status = "closed" if self._master_fd is not None: try: os.close(self._master_fd) except OSError: - pass + pass # noqa: S110 self._master_fd = None if self.process is not None: @@ -240,7 +272,7 @@ class TerminalSession: await ws.send_bytes(data) except Exception: dead_sockets.add(ws) - + # Clean up dead sockets for ws in dead_sockets: self._websockets.discard(ws) diff --git a/apps/api/tests/api/test_terminal_ws_multi.py b/apps/api/tests/api/test_terminal_ws_multi.py new file mode 100644 index 0000000..ccbb1d1 --- /dev/null +++ b/apps/api/tests/api/test_terminal_ws_multi.py @@ -0,0 +1,67 @@ +"""Integration tests for multi-session terminal WebSocket and REST API.""" + +import pytest +from fastapi.testclient import TestClient +from src.main import app + + +@pytest.fixture +def client(): + return TestClient(app) + + +class TestTerminalWebSocketMultiSession: + """Tests for multi-session WebSocket routing.""" + + def test_specific_session_websocket_route_exists(self, client): + """The specific session WebSocket route should be registered.""" + # We can't easily test WebSocket without auth, but we can verify + # the route exists by checking for a 403 (no auth cookie) + response = client.get("/ws/tool-instances/test-instance/terminal/test-session") + # WebSocket endpoint returns 403 when accessed via HTTP GET + assert response.status_code in (403, 404) + + def test_default_session_alias_route_exists(self, client): + """The default session alias route should still exist.""" + response = client.get("/ws/tool-instances/test-instance/terminal") + assert response.status_code in (403, 404) + + +class TestTerminalRestApi: + """Tests for REST API endpoints.""" + + def test_list_sessions_requires_auth(self, client): + """List sessions endpoint requires authentication.""" + response = client.get("/instances/test/terminal/sessions") + assert response.status_code == 401 + + def test_create_session_requires_auth(self, client): + """Create session endpoint requires authentication.""" + response = client.post( + "/instances/test/terminal/sessions", + json={}, + ) + assert response.status_code == 401 + + def test_close_session_requires_auth(self, client): + """Close session endpoint requires authentication.""" + response = client.delete("/instances/test/terminal/sessions/test-session") + assert response.status_code == 401 + + def test_reset_session_requires_auth(self, client): + """Reset session endpoint requires authentication.""" + response = client.post("/instances/test/terminal/sessions/test-session/reset") + assert response.status_code == 401 + + def test_rename_session_requires_auth(self, client): + """Rename session endpoint requires authentication.""" + response = client.post( + "/instances/test/terminal/sessions/test-session/rename", + json={"name": "New Name"}, + ) + assert response.status_code == 401 + + def test_legacy_reset_alias_requires_auth(self, client): + """Legacy reset endpoint still requires auth.""" + response = client.post("/instances/test/terminal/reset") + assert response.status_code == 401 diff --git a/apps/api/tests/services/test_terminal_manager_multi.py b/apps/api/tests/services/test_terminal_manager_multi.py new file mode 100644 index 0000000..ad3dbf3 --- /dev/null +++ b/apps/api/tests/services/test_terminal_manager_multi.py @@ -0,0 +1,203 @@ +"""Unit tests for TerminalManager multi-session support.""" + +import asyncio +import uuid +from unittest.mock import AsyncMock, patch + +import pytest + +from src.services.terminal_manager import MaxSessionsExceededError, TerminalManager +from src.services.terminal_session import TerminalSession + + +@pytest.fixture +def manager() -> TerminalManager: + """Provide a fresh TerminalManager instance for each test.""" + tm = TerminalManager() + # Cancel the background idle check to avoid side effects + if tm._idle_check_task and not tm._idle_check_task.done(): + tm._idle_check_task.cancel() + return tm + + +@pytest.fixture +def mock_terminal_session(monkeypatch) -> None: + """Monkeypatch TerminalSession.start and is_alive for unit tests.""" + + async def fake_start(self, startup_command=None): + self.last_activity = __import__("time").time() + + monkeypatch.setattr(TerminalSession, "start", fake_start) + monkeypatch.setattr(TerminalSession, "is_alive", lambda self: True) + + +@pytest.fixture +def instance_id() -> uuid.UUID: + return uuid.uuid4() + + +class FakeWebSocket: + """Minimal fake WebSocket for testing attach/detach behavior.""" + + def __init__(self, name: str = "ws") -> None: + self.name = name + self.closed = False + self.close_code: int | None = None + self.close_reason: str | None = None + self._sent: list[bytes] = [] + + async def close(self, code: int = 1000, reason: str = "") -> None: + self.closed = True + self.close_code = code + self.close_reason = reason + + async def send_bytes(self, data: bytes) -> None: + self._sent.append(data) + + +@pytest.mark.asyncio +async def test_create_session_increases_count( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """Creating sessions increments the per-instance count.""" + assert len(manager.get_sessions_for_instance(str(instance_id))) == 0 + + session1 = await manager.create_session(instance_id, "container-1") + assert len(manager.get_sessions_for_instance(str(instance_id))) == 1 + assert session1.session_id in [ + s.session_id for s in manager.get_sessions_for_instance(str(instance_id)) + ] + + session2 = await manager.create_session(instance_id, "container-1") + assert len(manager.get_sessions_for_instance(str(instance_id))) == 2 + + # Verify sessions are distinct + assert session1.session_id != session2.session_id + + +@pytest.mark.asyncio +async def test_create_session_enforces_max_5( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """The 6th session creation raises MaxSessionsExceededError.""" + for i in range(5): + await manager.create_session(instance_id, f"container-{i}") + + assert len(manager.get_sessions_for_instance(str(instance_id))) == 5 + + with pytest.raises(MaxSessionsExceededError): + await manager.create_session(instance_id, "container-overflow") + + +@pytest.mark.asyncio +async def test_get_sessions_for_instance_filters_by_instance( + manager: TerminalManager, + mock_terminal_session, +) -> None: + """get_sessions_for_instance returns only sessions for the requested instance.""" + instance_a = uuid.uuid4() + instance_b = uuid.uuid4() + + await manager.create_session(instance_a, "container-a") + await manager.create_session(instance_a, "container-a2") + await manager.create_session(instance_b, "container-b") + + assert len(manager.get_sessions_for_instance(str(instance_a))) == 2 + assert len(manager.get_sessions_for_instance(str(instance_b))) == 1 + + +@pytest.mark.asyncio +async def test_close_session_removes_from_dict( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """close_session removes the key from _sessions and marks DB closed.""" + session = await manager.create_session(instance_id, "container-1") + session_id = session.session_id + + assert manager.get_session(str(instance_id), session_id) is not None + + with patch.object(manager, "_mark_closed_in_db", new=AsyncMock()) as mock_mark: + await manager.close_session(str(instance_id), session_id) + # Give the fire-and-forget task a chance to be scheduled + await asyncio.sleep(0) + + assert manager.get_session(str(instance_id), session_id) is None + mock_mark.assert_called_once_with(session_id) + + +@pytest.mark.asyncio +async def test_attach_websocket_only_closes_same_session( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """Attaching to session A must not close WebSockets on session B.""" + session_a = await manager.create_session(instance_id, "container-1") + session_b = await manager.create_session(instance_id, "container-1") + + ws_a1 = FakeWebSocket("ws-a1") + ws_b1 = FakeWebSocket("ws-b1") + + # Manually attach websockets (simulate prior connections) + session_a.attach_websocket(ws_a1) + session_b.attach_websocket(ws_b1) + + # Now attach a new websocket to session_a + ws_a2 = FakeWebSocket("ws-a2") + await manager.attach_websocket(session_a, ws_a2) + + # ws_a1 should have been closed because it's on the same session + assert ws_a1.closed is True + + # ws_b1 should NOT have been closed because it's on a different session + assert ws_b1.closed is False + + # ws_a2 should be attached and receive buffer + assert ws_a2 in session_a._websockets + + +@pytest.mark.asyncio +async def test_default_session_keyed_separately( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """Default session uses 'default' session_id and does not collide with named sessions.""" + default_session = await manager.get_or_create_session(instance_id, "container-1") + explicit_session = await manager.create_session(instance_id, "container-1") + + # Both should exist + assert manager.get_session(str(instance_id), "default") is default_session + assert ( + manager.get_session(str(instance_id), explicit_session.session_id) + is explicit_session + ) + + # They should be different objects + assert default_session.session_id != explicit_session.session_id + + +@pytest.mark.asyncio +async def test_idle_cleanup_updates_db_status( + manager: TerminalManager, + mock_terminal_session, + instance_id: uuid.UUID, +) -> None: + """Idle cleanup removes sessions from dict and calls DB update.""" + session = await manager.create_session(instance_id, "container-1") + session_id = session.session_id + + # Make session appear idle (no websockets, old last_activity) + session.last_activity = 0 + + with patch.object(manager, "_mark_closed_in_db", new=AsyncMock()) as mock_mark: + await manager._cleanup_idle_sessions() + + assert manager.get_session(str(instance_id), session_id) is None + mock_mark.assert_called_once_with(session_id) diff --git a/apps/web/.pi-lens/cache/review-graph.json b/apps/web/.pi-lens/cache/review-graph.json deleted file mode 100644 index 9f71352..0000000 --- a/apps/web/.pi-lens/cache/review-graph.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"v2","builtAt":"2026-05-28T11:55:01.908Z","signature":"/home/alex/projects/headquarter/apps/web/.eslintrc.cjs:368:1779050260295.8674|/home/alex/projects/headquarter/apps/web/src/api/client.ts:1626:1779958621197.4604|/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:3739:1779478139563.111|/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:2502:1779469007691.0808|/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:4079:1779873890492.833|/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:350:1779050260296.2366|/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:7403:1779884227739.155|/home/alex/projects/headquarter/apps/web/src/api/profile.ts:880:1779051171239.6877|/home/alex/projects/headquarter/apps/web/src/api/projects.ts:1276:1779050260296.2366|/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:4795:1779958621198.4604|/home/alex/projects/headquarter/apps/web/src/api/settings.ts:781:1779283023155.8516|/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:1368:1779486648673.2014|/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:2094:1779468979582.398|/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:2540:1779969046480.7527|/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:6355:1779478139563.111|/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:2795:1779970190986.5713|/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:4715:1779700778730.3628|/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:1361:1779199463974.141|/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:4363:1779211094143.865|/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:2707:1779195365883.247|/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:17540:1779645590026.5527|/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx:762:1779710790599.268|/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:6466:1779211175763.9336|/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:7688:1779888860314.6736|/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:8063:1779483719123.56|/home/alex/projects/headquarter/apps/web/src/components/icon.tsx:2806:1779912877496.9204|/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:17415:1779650970344.7566|/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:26028:1779969298902.8604|/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:3865:1779211039223.4932|/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:2203:1779699728563.322|/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:2583:1779703873671.9841|/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:5046:1779958621198.4604|/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx:385:1779703895033.7395|/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:2164:1779958621198.4604|/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:2620:1779703154443.2212|/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:885:1779700188704.066|/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:2658:1779626577162.5774|/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:3626:1779626567953.6814|/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:1320:1779050260297.322|/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:546:1779050260297.322|/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:3989:1779474860196.355|/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:2935:1779474860212.3547|/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:11360:1779485424989.0652|/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:11045:1779700843613.6272|/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:3783:1779624338276.7373|/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:963:1779196943685.3203|/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:3034:1779619372214.5903|/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:2641:1779700587192.5288|/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:1925:1779211122539.5408|/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:17778:1779958621198.4604|/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:1667:1779703959646|/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx:1337:1779210479843.7842|/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:1029:1779708947297.703|/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:1449:1779614194650.1113|/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:4595:1779711443685.635|/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:550:1779614165882.4216|/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:4159:1779619315924.23|/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:633:1779112495652.6404|/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:2021:1779614180923.2595|/home/alex/projects/headquarter/apps/web/src/main.tsx:550:1779216096682.4463|/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:48869:1779958621207.4604|/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:2355:1779711297334.298|/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:9442:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:8308:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:4121:1779711297335.0742|/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:1118:1779711297335.2217|/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:5558:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:4383:1779711297335.5564|/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:6046:1779711297335.7217|/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:7064:1779711297335.9092|/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:17194:1779711297336.0974|/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:7904:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:5483:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:9795:1779958621208.4604|/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:1289:1779711297337.0588|/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:14350:1779711297338.2292|/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:61554:1779970269083.6685|/home/alex/projects/headquarter/apps/web/src/router.tsx:2635:1779647089669.214|/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:1666:1779050260297.5068|/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:1164:1779277256559.1477|/home/alex/projects/headquarter/apps/web/src/test/setup.ts:43:1779050260297.5068|/home/alex/projects/headquarter/apps/web/src/types.ts:308:1779051155846.8645|/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:428:1779708863270.6814|/home/alex/projects/headquarter/apps/web/src/utils/icons.ts:2632:1779217560829.7283|/home/alex/projects/headquarter/apps/web/src/utils/language.ts:1815:1779199128936.8345|/home/alex/projects/headquarter/apps/web/vite.config.ts:246:1779050260297.5068","fileSignatures":[["/home/alex/projects/headquarter/apps/web/.eslintrc.cjs","368:1779050260295.8674"],["/home/alex/projects/headquarter/apps/web/src/api/client.ts","1626:1779958621197.4604"],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","3739:1779478139563.111"],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","2502:1779469007691.0808"],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","4079:1779873890492.833"],["/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","350:1779050260296.2366"],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","7403:1779884227739.155"],["/home/alex/projects/headquarter/apps/web/src/api/profile.ts","880:1779051171239.6877"],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts","1276:1779050260296.2366"],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","4795:1779958621198.4604"],["/home/alex/projects/headquarter/apps/web/src/api/settings.ts","781:1779283023155.8516"],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","1368:1779486648673.2014"],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","2094:1779468979582.398"],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","2540:1779969046480.7527"],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","6355:1779478139563.111"],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","2795:1779970190986.5713"],["/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","4715:1779700778730.3628"],["/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","1361:1779199463974.141"],["/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","4363:1779211094143.865"],["/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","2707:1779195365883.247"],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","17540:1779645590026.5527"],["/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","762:1779710790599.268"],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","6466:1779211175763.9336"],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","7688:1779888860314.6736"],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","8063:1779483719123.56"],["/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","2806:1779912877496.9204"],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","17415:1779650970344.7566"],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","26028:1779969298902.8604"],["/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","3865:1779211039223.4932"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","2203:1779699728563.322"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","2583:1779703873671.9841"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","5046:1779958621198.4604"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","385:1779703895033.7395"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","2164:1779958621198.4604"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","2620:1779703154443.2212"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","885:1779700188704.066"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","2658:1779626577162.5774"],["/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","3626:1779626567953.6814"],["/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","1320:1779050260297.322"],["/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","546:1779050260297.322"],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","3989:1779474860196.355"],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","2935:1779474860212.3547"],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","11360:1779485424989.0652"],["/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","11045:1779700843613.6272"],["/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","3783:1779624338276.7373"],["/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","963:1779196943685.3203"],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","3034:1779619372214.5903"],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","2641:1779700587192.5288"],["/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","1925:1779211122539.5408"],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","17778:1779958621198.4604"],["/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","1667:1779703959646"],["/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","1337:1779210479843.7842"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","1029:1779708947297.703"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","1449:1779614194650.1113"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","4595:1779711443685.635"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","550:1779614165882.4216"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","4159:1779619315924.23"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","633:1779112495652.6404"],["/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","2021:1779614180923.2595"],["/home/alex/projects/headquarter/apps/web/src/main.tsx","550:1779216096682.4463"],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","48869:1779958621207.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","2355:1779711297334.298"],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","9442:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","8308:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","4121:1779711297335.0742"],["/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","1118:1779711297335.2217"],["/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","5558:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","4383:1779711297335.5564"],["/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","6046:1779711297335.7217"],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","7064:1779711297335.9092"],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","17194:1779711297336.0974"],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","7904:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","5483:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","9795:1779958621208.4604"],["/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","1289:1779711297337.0588"],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","14350:1779711297338.2292"],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","61554:1779970269083.6685"],["/home/alex/projects/headquarter/apps/web/src/router.tsx","2635:1779647089669.214"],["/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","1666:1779050260297.5068"],["/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","1164:1779277256559.1477"],["/home/alex/projects/headquarter/apps/web/src/test/setup.ts","43:1779050260297.5068"],["/home/alex/projects/headquarter/apps/web/src/types.ts","308:1779051155846.8645"],["/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","428:1779708863270.6814"],["/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","2632:1779217560829.7283"],["/home/alex/projects/headquarter/apps/web/src/utils/language.ts","1815:1779199128936.8345"],["/home/alex/projects/headquarter/apps/web/vite.config.ts","246:1779050260297.5068"]],"nodes":[["file:/home/alex/projects/headquarter/apps/web/.eslintrc.cjs",{"id":"file:/home/alex/projects/headquarter/apps/web/.eslintrc.cjs","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/.eslintrc.cjs","metadata":{"lineCount":17,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/client.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/client.ts","metadata":{"lineCount":52,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["external:axios",{"id":"external:axios","kind":"external","language":"jsts","metadata":{"source":"axios"}}],["/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect",{"id":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/client.ts","symbolName":"shouldSkipAuthRedirect","symbolKind":"function","exported":true,"metadata":{"line":13,"column":39,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["external:path.startsWith",{"id":"external:path.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"path.startsWith"}}],["/home/alex/projects/headquarter/apps/web/src/api/client.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/client.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":26,"column":3,"cyclomaticComplexity":8,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["symbol-name:shouldSkipAuthRedirect",{"id":"symbol-name:shouldSkipAuthRedirect","kind":"symbol","language":"jsts","symbolName":"shouldSkipAuthRedirect","metadata":{"unresolvedName":"shouldSkipAuthRedirect"}}],["external:window.location.assign",{"id":"external:window.location.assign","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.location.assign"}}],["external:Promise.reject",{"id":"external:Promise.reject","kind":"external","language":"jsts","metadata":{"unresolvedName":"Promise.reject"}}],["external:error.message?.includes",{"id":"external:error.message?.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"error.message?.includes"}}],["external:retryCount.get",{"id":"external:retryCount.get","kind":"external","language":"jsts","metadata":{"unresolvedName":"retryCount.get"}}],["external:retryCount.set",{"id":"external:retryCount.set","kind":"external","language":"jsts","metadata":{"unresolvedName":"retryCount.set"}}],["symbol-name:setTimeout",{"id":"symbol-name:setTimeout","kind":"symbol","language":"jsts","symbolName":"setTimeout","metadata":{"unresolvedName":"setTimeout"}}],["symbol-name:apiClient",{"id":"symbol-name:apiClient","kind":"symbol","language":"jsts","symbolName":"apiClient","metadata":{"unresolvedName":"apiClient"}}],["file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","metadata":{"lineCount":132,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:vitest",{"id":"external:vitest","kind":"external","language":"jsts","metadata":{"source":"vitest"}}],["file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","metadata":{"lineCount":96,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":123,"column":26,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["symbol-name:describe",{"id":"symbol-name:describe","kind":"symbol","language":"jsts","symbolName":"describe","metadata":{"unresolvedName":"describe"}}],["symbol-name:it",{"id":"symbol-name:it","kind":"symbol","language":"jsts","symbolName":"it","metadata":{"unresolvedName":"it"}}],["external:mockGet.mockResolvedValue",{"id":"external:mockGet.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}}],["symbol-name:listConfigFolders",{"id":"symbol-name:listConfigFolders","kind":"symbol","language":"jsts","symbolName":"listConfigFolders","metadata":{"unresolvedName":"listConfigFolders"}}],["external:expect(result[0].name).toBe",{"id":"external:expect(result[0].name).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].name).toBe"}}],["symbol-name:expect",{"id":"symbol-name:expect","kind":"symbol","language":"jsts","symbolName":"expect","metadata":{"unresolvedName":"expect"}}],["external:expect(result[0].files).toEqual",{"id":"external:expect(result[0].files).toEqual","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].files).toEqual"}}],["external:expect(mockGet).toHaveBeenCalledWith",{"id":"external:expect(mockGet).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}}],["external:mockPost.mockResolvedValue",{"id":"external:mockPost.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}}],["symbol-name:createConfigFolder",{"id":"symbol-name:createConfigFolder","kind":"symbol","language":"jsts","symbolName":"createConfigFolder","metadata":{"unresolvedName":"createConfigFolder"}}],["external:expect(result.name).toBe",{"id":"external:expect(result.name).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.name).toBe"}}],["external:expect(mockPost).toHaveBeenCalledWith",{"id":"external:expect(mockPost).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}}],["external:expect.objectContaining",{"id":"external:expect.objectContaining","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect.objectContaining"}}],["external:mockPut.mockResolvedValue",{"id":"external:mockPut.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}}],["symbol-name:updateConfigFolder",{"id":"symbol-name:updateConfigFolder","kind":"symbol","language":"jsts","symbolName":"updateConfigFolder","metadata":{"unresolvedName":"updateConfigFolder"}}],["external:expect(result.files).toEqual",{"id":"external:expect(result.files).toEqual","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.files).toEqual"}}],["external:expect(mockPut).toHaveBeenCalledWith",{"id":"external:expect(mockPut).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}}],["external:mockDelete.mockResolvedValue",{"id":"external:mockDelete.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}}],["symbol-name:deleteConfigFolder",{"id":"symbol-name:deleteConfigFolder","kind":"symbol","language":"jsts","symbolName":"deleteConfigFolder","metadata":{"unresolvedName":"deleteConfigFolder"}}],["external:expect(mockDelete).toHaveBeenCalledWith",{"id":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"listConfigFolders","symbolKind":"function","exported":true,"metadata":{"line":37,"column":34,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:apiClient.get",{"id":"external:apiClient.get","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiClient.get"}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:getConfigFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:getConfigFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"getConfigFolder","symbolKind":"function","exported":true,"metadata":{"line":42,"column":32,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"createConfigFolder","symbolKind":"function","exported":true,"metadata":{"line":47,"column":35,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:apiClient.post",{"id":"external:apiClient.post","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiClient.post"}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"updateConfigFolder","symbolKind":"function","exported":true,"metadata":{"line":54,"column":35,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:apiClient.put",{"id":"external:apiClient.put","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiClient.put"}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"deleteConfigFolder","symbolKind":"function","exported":true,"metadata":{"line":62,"column":35,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:apiClient.delete",{"id":"external:apiClient.delete","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiClient.delete"}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:addProjectOverride",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:addProjectOverride","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"addProjectOverride","symbolKind":"function","exported":true,"metadata":{"line":66,"column":35,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateProjectOverride",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateProjectOverride","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"updateProjectOverride","symbolKind":"function","exported":true,"metadata":{"line":78,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteProjectOverride",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteProjectOverride","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","symbolName":"deleteProjectOverride","symbolKind":"function","exported":true,"metadata":{"line":90,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","metadata":{"lineCount":157,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"listConfigProfiles","symbolKind":"function","exported":true,"metadata":{"line":94,"column":35,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:getConfigProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:getConfigProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"getConfigProfile","symbolKind":"function","exported":true,"metadata":{"line":104,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"createConfigProfile","symbolKind":"function","exported":true,"metadata":{"line":109,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"updateConfigProfile","symbolKind":"function","exported":true,"metadata":{"line":116,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"deleteConfigProfile","symbolKind":"function","exported":true,"metadata":{"line":124,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"updateProfileIncludes","symbolKind":"function","exported":true,"metadata":{"line":128,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"previewConfigProfile","symbolKind":"function","exported":true,"metadata":{"line":139,"column":37,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:resolveDefaultProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:resolveDefaultProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","symbolName":"resolveDefaultProfile","symbolKind":"function","exported":true,"metadata":{"line":148,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","metadata":{"lineCount":14,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary",{"id":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","symbolName":"getDashboardSummary","symbolKind":"function","exported":true,"metadata":{"line":10,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","metadata":{"lineCount":300,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"parseGitUrl","symbolKind":"function","exported":true,"metadata":{"line":33,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"listRepositories","symbolKind":"function","exported":true,"metadata":{"line":38,"column":1,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listAllUserRepositories",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listAllUserRepositories","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"listAllUserRepositories","symbolKind":"function","exported":true,"metadata":{"line":50,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"createRepository","symbolKind":"function","exported":true,"metadata":{"line":55,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createExternalRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createExternalRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"createExternalRepository","symbolKind":"function","exported":true,"metadata":{"line":63,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"deleteRepository","symbolKind":"function","exported":true,"metadata":{"line":70,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:updateRepositorySshKey",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:updateRepositorySshKey","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"updateRepositorySshKey","symbolKind":"function","exported":true,"metadata":{"line":74,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:apiClient.patch",{"id":"external:apiClient.patch","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiClient.patch"}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"listRepositoryBranches","symbolKind":"function","exported":true,"metadata":{"line":97,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"getRepositoryHistory","symbolKind":"function","exported":true,"metadata":{"line":125,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:searchParams.set",{"id":"external:searchParams.set","kind":"external","language":"jsts","metadata":{"unresolvedName":"searchParams.set"}}],["symbol-name:String",{"id":"symbol-name:String","kind":"symbol","language":"jsts","symbolName":"String","metadata":{"unresolvedName":"String"}}],["external:searchParams.toString",{"id":"external:searchParams.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"searchParams.toString"}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"getCommitDetail","symbolKind":"function","exported":true,"metadata":{"line":159,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"getRepositoryStatus","symbolKind":"function","exported":true,"metadata":{"line":183,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"createBranch","symbolKind":"function","exported":true,"metadata":{"line":193,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteBranch",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteBranch","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"deleteBranch","symbolKind":"function","exported":true,"metadata":{"line":206,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"checkoutBranch","symbolKind":"function","exported":true,"metadata":{"line":218,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"commitChanges","symbolKind":"function","exported":true,"metadata":{"line":235,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"fetchRepository","symbolKind":"function","exported":true,"metadata":{"line":248,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"pullRepository","symbolKind":"function","exported":true,"metadata":{"line":258,"column":1,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"pushRepository","symbolKind":"function","exported":true,"metadata":{"line":270,"column":1,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches",{"id":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","symbolName":"mergeBranches","symbolKind":"function","exported":true,"metadata":{"line":287,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts","metadata":{"lineCount":31,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/types.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/types.ts","metadata":{"lineCount":19,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/api/profile.ts:getProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:getProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts","symbolName":"getProfile","symbolKind":"function","exported":true,"metadata":{"line":11,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts","symbolName":"updateProfile","symbolKind":"function","exported":true,"metadata":{"line":16,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar",{"id":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts","symbolName":"uploadAvatar","symbolKind":"function","exported":true,"metadata":{"line":21,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["external:formData.append",{"id":"external:formData.append","kind":"external","language":"jsts","metadata":{"unresolvedName":"formData.append"}}],["file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","metadata":{"lineCount":52,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects",{"id":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","symbolName":"listProjects","symbolKind":"function","exported":true,"metadata":{"line":18,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject",{"id":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","symbolName":"createProject","symbolKind":"function","exported":true,"metadata":{"line":23,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject",{"id":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","symbolName":"updateProject","symbolKind":"function","exported":true,"metadata":{"line":30,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject",{"id":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","symbolName":"deleteProject","symbolKind":"function","exported":true,"metadata":{"line":38,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/projects.ts:setDefaultSSHKey",{"id":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:setDefaultSSHKey","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts","symbolName":"setDefaultSSHKey","symbolKind":"function","exported":true,"metadata":{"line":42,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","metadata":{"lineCount":180,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"listInstances","symbolKind":"function","exported":true,"metadata":{"line":37,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"createInstance","symbolKind":"function","exported":true,"metadata":{"line":47,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"startInstance","symbolKind":"function","exported":true,"metadata":{"line":71,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["symbol-name:startInstance",{"id":"symbol-name:startInstance","kind":"symbol","language":"jsts","symbolName":"startInstance","metadata":{"unresolvedName":"startInstance"}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"stopInstance","symbolKind":"function","exported":true,"metadata":{"line":95,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"restartInstance","symbolKind":"function","exported":true,"metadata":{"line":106,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["symbol-name:restartInstance",{"id":"symbol-name:restartInstance","kind":"symbol","language":"jsts","symbolName":"restartInstance","metadata":{"unresolvedName":"restartInstance"}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"deleteInstance","symbolKind":"function","exported":true,"metadata":{"line":130,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"getUserSessions","symbolKind":"function","exported":true,"metadata":{"line":142,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"checkInstanceHealth","symbolKind":"function","exported":true,"metadata":{"line":159,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel",{"id":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","symbolName":"recreateInstanceTunnel","symbolKind":"function","exported":true,"metadata":{"line":170,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization","auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts","metadata":{"lineCount":28,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts","symbolName":"getUserConfig","symbolKind":"function","exported":true,"metadata":{"line":19,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts","symbolName":"updateUserConfig","symbolKind":"function","exported":true,"metadata":{"line":24,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","metadata":{"lineCount":54,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys",{"id":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","symbolName":"listSSHKeys","symbolKind":"function","exported":true,"metadata":{"line":14,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey",{"id":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","symbolName":"createSSHKey","symbolKind":"function","exported":true,"metadata":{"line":19,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey",{"id":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","symbolName":"deleteSSHKey","symbolKind":"function","exported":true,"metadata":{"line":24,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload",{"id":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","symbolName":"signPayload","symbolKind":"function","exported":true,"metadata":{"line":45,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature",{"id":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","symbolName":"verifySignature","symbolKind":"function","exported":true,"metadata":{"line":50,"column":1,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","metadata":{"lineCount":75,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","symbolName":"listToolConfigs","symbolKind":"function","exported":true,"metadata":{"line":32,"column":32,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["external:params.append",{"id":"external:params.append","kind":"external","language":"jsts","metadata":{"unresolvedName":"params.append"}}],["external:params.toString",{"id":"external:params.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"params.toString"}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","symbolName":"createToolConfig","symbolKind":"function","exported":true,"metadata":{"line":46,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","symbolName":"updateToolConfig","symbolKind":"function","exported":true,"metadata":{"line":53,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","symbolName":"deleteToolConfig","symbolKind":"function","exported":true,"metadata":{"line":64,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:getToolConfigDefaults",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:getToolConfigDefaults","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","symbolName":"getToolConfigDefaults","symbolKind":"function","exported":true,"metadata":{"line":68,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","metadata":{"lineCount":82,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"listToolDefinitions","symbolKind":"function","exported":true,"metadata":{"line":51,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:getToolDefinition",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:getToolDefinition","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"getToolDefinition","symbolKind":"function","exported":true,"metadata":{"line":58,"column":34,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:createToolDefinition",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:createToolDefinition","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"createToolDefinition","symbolKind":"function","exported":true,"metadata":{"line":63,"column":37,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:updateToolDefinition",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:updateToolDefinition","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"updateToolDefinition","symbolKind":"function","exported":true,"metadata":{"line":68,"column":37,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:deleteToolDefinition",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:deleteToolDefinition","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"deleteToolDefinition","symbolKind":"function","exported":true,"metadata":{"line":73,"column":37,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","symbolName":"compileToolDefinition","symbolKind":"function","exported":true,"metadata":{"line":78,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","metadata":{"lineCount":228,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":219,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["symbol-name:listToolTypes",{"id":"symbol-name:listToolTypes","kind":"symbol","language":"jsts","symbolName":"listToolTypes","metadata":{"unresolvedName":"listToolTypes"}}],["external:expect(result[0].definition_type).toBe",{"id":"external:expect(result[0].definition_type).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].definition_type).toBe"}}],["external:expect(result[0].dockerfile_template).toBe",{"id":"external:expect(result[0].dockerfile_template).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBe"}}],["external:expect(result[0].readiness_probe).toEqual",{"id":"external:expect(result[0].readiness_probe).toEqual","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].readiness_probe).toEqual"}}],["external:expect(result[0].dockerfile_template).toBeNull",{"id":"external:expect(result[0].dockerfile_template).toBeNull","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBeNull"}}],["symbol-name:createToolType",{"id":"symbol-name:createToolType","kind":"symbol","language":"jsts","symbolName":"createToolType","metadata":{"unresolvedName":"createToolType"}}],["external:expect(result.definition_type).toBe",{"id":"external:expect(result.definition_type).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}}],["external:expect(result.readiness_probe).toEqual",{"id":"external:expect(result.readiness_probe).toEqual","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.readiness_probe).toEqual"}}],["symbol-name:validateToolType",{"id":"symbol-name:validateToolType","kind":"symbol","language":"jsts","symbolName":"validateToolType","metadata":{"unresolvedName":"validateToolType"}}],["external:expect(result.valid).toBe",{"id":"external:expect(result.valid).toBe","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.valid).toBe"}}],["external:expect(result.errors).toContain",{"id":"external:expect(result.errors).toContain","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(result.errors).toContain"}}],["symbol-name:updateToolType",{"id":"symbol-name:updateToolType","kind":"symbol","language":"jsts","symbolName":"updateToolType","metadata":{"unresolvedName":"updateToolType"}}],["symbol-name:deleteToolType",{"id":"symbol-name:deleteToolType","kind":"symbol","language":"jsts","symbolName":"deleteToolType","metadata":{"unresolvedName":"deleteToolType"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","metadata":{"lineCount":142,"featureKind":"library","trustBoundaries":["user-input","process-exec"]}}],["external:react",{"id":"external:react","kind":"external","language":"jsts","metadata":{"source":"react"}}],["external:react-router-dom",{"id":"external:react-router-dom","kind":"external","language":"jsts","metadata":{"source":"react-router-dom"}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","metadata":{"lineCount":24,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","metadata":{"lineCount":64,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","metadata":{"lineCount":45,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","metadata":{"lineCount":22,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","metadata":{"lineCount":168,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","metadata":{"lineCount":88,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","metadata":{"lineCount":181,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:SessionItem",{"id":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:SessionItem","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","symbolName":"SessionItem","symbolKind":"function","exported":false,"metadata":{"line":23,"column":21,"cyclomaticComplexity":5,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["user-input","process-exec","auth"]}}],["/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell",{"id":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","symbolName":"AppShell","symbolKind":"function","exported":true,"metadata":{"line":41,"column":25,"cyclomaticComplexity":13,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["user-input","process-exec"]}}],["symbol-name:useTheme",{"id":"symbol-name:useTheme","kind":"symbol","language":"jsts","symbolName":"useTheme","metadata":{"unresolvedName":"useTheme"}}],["symbol-name:useAuth",{"id":"symbol-name:useAuth","kind":"symbol","language":"jsts","symbolName":"useAuth","metadata":{"unresolvedName":"useAuth"}}],["symbol-name:useSessions",{"id":"symbol-name:useSessions","kind":"symbol","language":"jsts","symbolName":"useSessions","metadata":{"unresolvedName":"useSessions"}}],["symbol-name:useLocation",{"id":"symbol-name:useLocation","kind":"symbol","language":"jsts","symbolName":"useLocation","metadata":{"unresolvedName":"useLocation"}}],["symbol-name:useMobileViewport",{"id":"symbol-name:useMobileViewport","kind":"symbol","language":"jsts","symbolName":"useMobileViewport","metadata":{"unresolvedName":"useMobileViewport"}}],["external:location.pathname.includes",{"id":"external:location.pathname.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"location.pathname.includes"}}],["symbol-name:useCallback",{"id":"symbol-name:useCallback","kind":"symbol","language":"jsts","symbolName":"useCallback","metadata":{"unresolvedName":"useCallback"}}],["symbol-name:getUserSessions",{"id":"symbol-name:getUserSessions","kind":"symbol","language":"jsts","symbolName":"getUserSessions","metadata":{"unresolvedName":"getUserSessions"}}],["symbol-name:setAllSessions",{"id":"symbol-name:setAllSessions","kind":"symbol","language":"jsts","symbolName":"setAllSessions","metadata":{"unresolvedName":"setAllSessions"}}],["symbol-name:useEffect",{"id":"symbol-name:useEffect","kind":"symbol","language":"jsts","symbolName":"useEffect","metadata":{"unresolvedName":"useEffect"}}],["symbol-name:loadSessions",{"id":"symbol-name:loadSessions","kind":"symbol","language":"jsts","symbolName":"loadSessions","metadata":{"unresolvedName":"loadSessions"}}],["symbol-name:setInterval",{"id":"symbol-name:setInterval","kind":"symbol","language":"jsts","symbolName":"setInterval","metadata":{"unresolvedName":"setInterval"}}],["symbol-name:clearInterval",{"id":"symbol-name:clearInterval","kind":"symbol","language":"jsts","symbolName":"clearInterval","metadata":{"unresolvedName":"clearInterval"}}],["symbol-name:logout",{"id":"symbol-name:logout","kind":"symbol","language":"jsts","symbolName":"logout","metadata":{"unresolvedName":"logout"}}],["external:NAV_ITEMS.map",{"id":"external:NAV_ITEMS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"NAV_ITEMS.map"}}],["external:sessions.filter",{"id":"external:sessions.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"sessions.filter"}}],["external:sessions.map",{"id":"external:sessions.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"sessions.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":101,"column":28,"cyclomaticComplexity":4,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["user-input","process-exec"]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","metadata":{"lineCount":57,"featureKind":"library","trustBoundaries":[]}}],["external:react-simple-code-editor",{"id":"external:react-simple-code-editor","kind":"external","language":"jsts","metadata":{"source":"react-simple-code-editor"}}],["file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts","metadata":{"lineCount":91,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor",{"id":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","symbolName":"CodeEditor","symbolKind":"function","exported":true,"metadata":{"line":12,"column":54,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:loadLanguage",{"id":"symbol-name:loadLanguage","kind":"symbol","language":"jsts","symbolName":"loadLanguage","metadata":{"unresolvedName":"loadLanguage"}}],["symbol-name:highlight",{"id":"symbol-name:highlight","kind":"symbol","language":"jsts","symbolName":"highlight","metadata":{"unresolvedName":"highlight"}}],["external:input\n .split(\"\\n\")\n .map",{"id":"external:input\n .split(\"\\n\")\n .map","kind":"external","language":"jsts","metadata":{"unresolvedName":"input\n .split(\"\\n\")\n .map"}}],["external:input\n .split",{"id":"external:input\n .split","kind":"external","language":"jsts","metadata":{"unresolvedName":"input\n .split"}}],["symbol-name:highlightCode",{"id":"symbol-name:highlightCode","kind":"symbol","language":"jsts","symbolName":"highlightCode","metadata":{"unresolvedName":"highlightCode"}}],["/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":18,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:highlight",{"id":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:highlight","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","symbolName":"highlight","symbolKind":"function","exported":false,"metadata":{"line":19,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","metadata":{"lineCount":160,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog",{"id":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","symbolName":"CommitDialog","symbolKind":"function","exported":true,"metadata":{"line":14,"column":58,"cyclomaticComplexity":19,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useState",{"id":"symbol-name:useState","kind":"symbol","language":"jsts","symbolName":"useState","metadata":{"unresolvedName":"useState"}}],["external:originalContent.split",{"id":"external:originalContent.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"originalContent.split"}}],["external:newContent.split",{"id":"external:newContent.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"newContent.split"}}],["external:Math.max",{"id":"external:Math.max","kind":"external","language":"jsts","metadata":{"unresolvedName":"Math.max"}}],["external:diff.push",{"id":"external:diff.push","kind":"external","language":"jsts","metadata":{"unresolvedName":"diff.push"}}],["external:message.trim",{"id":"external:message.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"message.trim"}}],["symbol-name:setError",{"id":"symbol-name:setError","kind":"symbol","language":"jsts","symbolName":"setError","metadata":{"unresolvedName":"setError"}}],["symbol-name:setLoading",{"id":"symbol-name:setLoading","kind":"symbol","language":"jsts","symbolName":"setLoading","metadata":{"unresolvedName":"setLoading"}}],["symbol-name:onCommit",{"id":"symbol-name:onCommit","kind":"symbol","language":"jsts","symbolName":"onCommit","metadata":{"unresolvedName":"onCommit"}}],["symbol-name:generateDiff",{"id":"symbol-name:generateDiff","kind":"symbol","language":"jsts","symbolName":"generateDiff","metadata":{"unresolvedName":"generateDiff"}}],["external:diff.some",{"id":"external:diff.some","kind":"external","language":"jsts","metadata":{"unresolvedName":"diff.some"}}],["external:diff.map",{"id":"external:diff.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"diff.map"}}],["symbol-name:setMessage",{"id":"symbol-name:setMessage","kind":"symbol","language":"jsts","symbolName":"setMessage","metadata":{"unresolvedName":"setMessage"}}],["/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff",{"id":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","symbolName":"generateDiff","symbolKind":"function","exported":false,"metadata":{"line":28,"column":24,"cyclomaticComplexity":7,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","symbolName":"handleCommit","symbolKind":"function","exported":false,"metadata":{"line":53,"column":24,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","metadata":{"lineCount":103,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel",{"id":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","symbolName":"CommitPanel","symbolKind":"function","exported":true,"metadata":{"line":15,"column":28,"cyclomaticComplexity":7,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:commitChanges",{"id":"symbol-name:commitChanges","kind":"symbol","language":"jsts","symbolName":"commitChanges","metadata":{"unresolvedName":"commitChanges"}}],["external:modified.map",{"id":"external:modified.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"modified.map"}}],["external:added.map",{"id":"external:added.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"added.map"}}],["external:deleted.map",{"id":"external:deleted.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"deleted.map"}}],["external:untracked.map",{"id":"external:untracked.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"untracked.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","symbolName":"handleCommit","symbolKind":"function","exported":false,"metadata":{"line":31,"column":24,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","metadata":{"lineCount":522,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"CreateSessionForm","symbolKind":"function","exported":true,"metadata":{"line":27,"column":34,"cyclomaticComplexity":76,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["symbol-name:listSSHKeys",{"id":"symbol-name:listSSHKeys","kind":"symbol","language":"jsts","symbolName":"listSSHKeys","metadata":{"unresolvedName":"listSSHKeys"}}],["symbol-name:setSshKeys",{"id":"symbol-name:setSshKeys","kind":"symbol","language":"jsts","symbolName":"setSshKeys","metadata":{"unresolvedName":"setSshKeys"}}],["symbol-name:loadKeys",{"id":"symbol-name:loadKeys","kind":"symbol","language":"jsts","symbolName":"loadKeys","metadata":{"unresolvedName":"loadKeys"}}],["symbol-name:setConfigProfiles",{"id":"symbol-name:setConfigProfiles","kind":"symbol","language":"jsts","symbolName":"setConfigProfiles","metadata":{"unresolvedName":"setConfigProfiles"}}],["symbol-name:setSelectedConfigProfile",{"id":"symbol-name:setSelectedConfigProfile","kind":"symbol","language":"jsts","symbolName":"setSelectedConfigProfile","metadata":{"unresolvedName":"setSelectedConfigProfile"}}],["symbol-name:listConfigProfiles",{"id":"symbol-name:listConfigProfiles","kind":"symbol","language":"jsts","symbolName":"listConfigProfiles","metadata":{"unresolvedName":"listConfigProfiles"}}],["external:profiles.find",{"id":"external:profiles.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"profiles.find"}}],["symbol-name:loadProfiles",{"id":"symbol-name:loadProfiles","kind":"symbol","language":"jsts","symbolName":"loadProfiles","metadata":{"unresolvedName":"loadProfiles"}}],["symbol-name:setBranches",{"id":"symbol-name:setBranches","kind":"symbol","language":"jsts","symbolName":"setBranches","metadata":{"unresolvedName":"setBranches"}}],["symbol-name:setIsLoadingBranches",{"id":"symbol-name:setIsLoadingBranches","kind":"symbol","language":"jsts","symbolName":"setIsLoadingBranches","metadata":{"unresolvedName":"setIsLoadingBranches"}}],["symbol-name:listRepositoryBranches",{"id":"symbol-name:listRepositoryBranches","kind":"symbol","language":"jsts","symbolName":"listRepositoryBranches","metadata":{"unresolvedName":"listRepositoryBranches"}}],["symbol-name:setBranch",{"id":"symbol-name:setBranch","kind":"symbol","language":"jsts","symbolName":"setBranch","metadata":{"unresolvedName":"setBranch"}}],["symbol-name:setBaseBranch",{"id":"symbol-name:setBaseBranch","kind":"symbol","language":"jsts","symbolName":"setBaseBranch","metadata":{"unresolvedName":"setBaseBranch"}}],["symbol-name:loadBranches",{"id":"symbol-name:loadBranches","kind":"symbol","language":"jsts","symbolName":"loadBranches","metadata":{"unresolvedName":"loadBranches"}}],["external:repositories.filter",{"id":"external:repositories.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"repositories.filter"}}],["external:event.preventDefault",{"id":"external:event.preventDefault","kind":"external","language":"jsts","metadata":{"unresolvedName":"event.preventDefault"}}],["external:repositories.find",{"id":"external:repositories.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"repositories.find"}}],["symbol-name:setStatus",{"id":"symbol-name:setStatus","kind":"symbol","language":"jsts","symbolName":"setStatus","metadata":{"unresolvedName":"setStatus"}}],["symbol-name:setProgress",{"id":"symbol-name:setProgress","kind":"symbol","language":"jsts","symbolName":"setProgress","metadata":{"unresolvedName":"setProgress"}}],["symbol-name:createInstance",{"id":"symbol-name:createInstance","kind":"symbol","language":"jsts","symbolName":"createInstance","metadata":{"unresolvedName":"createInstance"}}],["symbol-name:setSelectedProject",{"id":"symbol-name:setSelectedProject","kind":"symbol","language":"jsts","symbolName":"setSelectedProject","metadata":{"unresolvedName":"setSelectedProject"}}],["symbol-name:setSelectedRepo",{"id":"symbol-name:setSelectedRepo","kind":"symbol","language":"jsts","symbolName":"setSelectedRepo","metadata":{"unresolvedName":"setSelectedRepo"}}],["symbol-name:setSelectedToolType",{"id":"symbol-name:setSelectedToolType","kind":"symbol","language":"jsts","symbolName":"setSelectedToolType","metadata":{"unresolvedName":"setSelectedToolType"}}],["symbol-name:setDisplayName",{"id":"symbol-name:setDisplayName","kind":"symbol","language":"jsts","symbolName":"setDisplayName","metadata":{"unresolvedName":"setDisplayName"}}],["symbol-name:setCloneMode",{"id":"symbol-name:setCloneMode","kind":"symbol","language":"jsts","symbolName":"setCloneMode","metadata":{"unresolvedName":"setCloneMode"}}],["symbol-name:setIsCreatingNewBranch",{"id":"symbol-name:setIsCreatingNewBranch","kind":"symbol","language":"jsts","symbolName":"setIsCreatingNewBranch","metadata":{"unresolvedName":"setIsCreatingNewBranch"}}],["symbol-name:setNewBranchName",{"id":"symbol-name:setNewBranchName","kind":"symbol","language":"jsts","symbolName":"setNewBranchName","metadata":{"unresolvedName":"setNewBranchName"}}],["symbol-name:onSuccess",{"id":"symbol-name:onSuccess","kind":"symbol","language":"jsts","symbolName":"onSuccess","metadata":{"unresolvedName":"onSuccess"}}],["symbol-name:renderStep",{"id":"symbol-name:renderStep","kind":"symbol","language":"jsts","symbolName":"renderStep","metadata":{"unresolvedName":"renderStep"}}],["external:projects.find",{"id":"external:projects.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"projects.find"}}],["symbol-name:onProjectChange",{"id":"symbol-name:onProjectChange","kind":"symbol","language":"jsts","symbolName":"onProjectChange","metadata":{"unresolvedName":"onProjectChange"}}],["external:projects.map",{"id":"external:projects.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"projects.map"}}],["external:availableRepos.map",{"id":"external:availableRepos.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"availableRepos.map"}}],["external:toolTypes.map",{"id":"external:toolTypes.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypes.map"}}],["external:configProfiles.map",{"id":"external:configProfiles.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"configProfiles.map"}}],["external:branches.map",{"id":"external:branches.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"branches.map"}}],["external:sshKeys.find",{"id":"external:sshKeys.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"sshKeys.find"}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":447,"column":23,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"loadKeys","symbolKind":"function","exported":false,"metadata":{"line":66,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"loadProfiles","symbolKind":"function","exported":false,"metadata":{"line":85,"column":26,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"loadBranches","symbolKind":"function","exported":false,"metadata":{"line":108,"column":26,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":131,"column":24,"cyclomaticComplexity":21,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:renderStep",{"id":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:renderStep","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","symbolName":"renderStep","symbolKind":"function","exported":false,"metadata":{"line":203,"column":22,"cyclomaticComplexity":3,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","metadata":{"lineCount":35,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","metadata":{"lineCount":242,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","metadata":{"lineCount":78,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"FileEditor","symbolKind":"function","exported":true,"metadata":{"line":16,"column":54,"cyclomaticComplexity":33,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useSearchParams",{"id":"symbol-name:useSearchParams","kind":"symbol","language":"jsts","symbolName":"useSearchParams","metadata":{"unresolvedName":"useSearchParams"}}],["external:searchParams.get",{"id":"external:searchParams.get","kind":"external","language":"jsts","metadata":{"unresolvedName":"searchParams.get"}}],["symbol-name:setContent",{"id":"symbol-name:setContent","kind":"symbol","language":"jsts","symbolName":"setContent","metadata":{"unresolvedName":"setContent"}}],["symbol-name:setOriginalContent",{"id":"symbol-name:setOriginalContent","kind":"symbol","language":"jsts","symbolName":"setOriginalContent","metadata":{"unresolvedName":"setOriginalContent"}}],["symbol-name:setIsBinary",{"id":"symbol-name:setIsBinary","kind":"symbol","language":"jsts","symbolName":"setIsBinary","metadata":{"unresolvedName":"setIsBinary"}}],["symbol-name:setLanguage",{"id":"symbol-name:setLanguage","kind":"symbol","language":"jsts","symbolName":"setLanguage","metadata":{"unresolvedName":"setLanguage"}}],["symbol-name:detectLanguage",{"id":"symbol-name:detectLanguage","kind":"symbol","language":"jsts","symbolName":"detectLanguage","metadata":{"unresolvedName":"detectLanguage"}}],["symbol-name:loadFile",{"id":"symbol-name:loadFile","kind":"symbol","language":"jsts","symbolName":"loadFile","metadata":{"unresolvedName":"loadFile"}}],["symbol-name:setMode",{"id":"symbol-name:setMode","kind":"symbol","language":"jsts","symbolName":"setMode","metadata":{"unresolvedName":"setMode"}}],["symbol-name:setShowCommitDialog",{"id":"symbol-name:setShowCommitDialog","kind":"symbol","language":"jsts","symbolName":"setShowCommitDialog","metadata":{"unresolvedName":"setShowCommitDialog"}}],["symbol-name:setSaving",{"id":"symbol-name:setSaving","kind":"symbol","language":"jsts","symbolName":"setSaving","metadata":{"unresolvedName":"setSaving"}}],["external:e.preventDefault",{"id":"external:e.preventDefault","kind":"external","language":"jsts","metadata":{"unresolvedName":"e.preventDefault"}}],["symbol-name:handleEdit",{"id":"symbol-name:handleEdit","kind":"symbol","language":"jsts","symbolName":"handleEdit","metadata":{"unresolvedName":"handleEdit"}}],["symbol-name:handleCancel",{"id":"symbol-name:handleCancel","kind":"symbol","language":"jsts","symbolName":"handleCancel","metadata":{"unresolvedName":"handleCancel"}}],["symbol-name:handleSave",{"id":"symbol-name:handleSave","kind":"symbol","language":"jsts","symbolName":"handleSave","metadata":{"unresolvedName":"handleSave"}}],["external:window.addEventListener",{"id":"external:window.addEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.addEventListener"}}],["external:window.removeEventListener",{"id":"external:window.removeEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.removeEventListener"}}],["external:filePath.split(\"/\").map",{"id":"external:filePath.split(\"/\").map","kind":"external","language":"jsts","metadata":{"unresolvedName":"filePath.split(\"/\").map"}}],["external:filePath.split",{"id":"external:filePath.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"filePath.split"}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":123,"column":13,"cyclomaticComplexity":11,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"handleEdit","symbolKind":"function","exported":false,"metadata":{"line":77,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"handleCancel","symbolKind":"function","exported":false,"metadata":{"line":82,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"handleSave","symbolKind":"function","exported":false,"metadata":{"line":88,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"handleCommit","symbolKind":"function","exported":false,"metadata":{"line":96,"column":24,"cyclomaticComplexity":6,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown",{"id":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","symbolName":"handleKeyDown","symbolKind":"function","exported":false,"metadata":{"line":124,"column":27,"cyclomaticComplexity":11,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","metadata":{"lineCount":226,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"GitMountEditor","symbolKind":"function","exported":true,"metadata":{"line":10,"column":31,"cyclomaticComplexity":15,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:onChange",{"id":"symbol-name:onChange","kind":"symbol","language":"jsts","symbolName":"onChange","metadata":{"unresolvedName":"onChange"}}],["symbol-name:setNewMount",{"id":"symbol-name:setNewMount","kind":"symbol","language":"jsts","symbolName":"setNewMount","metadata":{"unresolvedName":"setNewMount"}}],["symbol-name:setEditingIndex",{"id":"symbol-name:setEditingIndex","kind":"symbol","language":"jsts","symbolName":"setEditingIndex","metadata":{"unresolvedName":"setEditingIndex"}}],["external:mounts.filter",{"id":"external:mounts.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"mounts.filter"}}],["external:path.includes",{"id":"external:path.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"path.includes"}}],["external:url.startsWith",{"id":"external:url.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"url.startsWith"}}],["external:mounts.map",{"id":"external:mounts.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"mounts.map"}}],["symbol-name:handleUpdate",{"id":"symbol-name:handleUpdate","kind":"symbol","language":"jsts","symbolName":"handleUpdate","metadata":{"unresolvedName":"handleUpdate"}}],["symbol-name:handleRemove",{"id":"symbol-name:handleRemove","kind":"symbol","language":"jsts","symbolName":"handleRemove","metadata":{"unresolvedName":"handleRemove"}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"handleAdd","symbolKind":"function","exported":false,"metadata":{"line":19,"column":21,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"handleUpdate","symbolKind":"function","exported":false,"metadata":{"line":24,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"handleRemove","symbolKind":"function","exported":false,"metadata":{"line":31,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"validatePath","symbolKind":"function","exported":false,"metadata":{"line":35,"column":24,"cyclomaticComplexity":6,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"validateUrl","symbolKind":"function","exported":false,"metadata":{"line":42,"column":23,"cyclomaticComplexity":6,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"GitMountForm","symbolKind":"function","exported":false,"metadata":{"line":126,"column":22,"cyclomaticComplexity":17,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setForm",{"id":"symbol-name:setForm","kind":"symbol","language":"jsts","symbolName":"setForm","metadata":{"unresolvedName":"setForm"}}],["symbol-name:setErrors",{"id":"symbol-name:setErrors","kind":"symbol","language":"jsts","symbolName":"setErrors","metadata":{"unresolvedName":"setErrors"}}],["symbol-name:validateUrl",{"id":"symbol-name:validateUrl","kind":"symbol","language":"jsts","symbolName":"validateUrl","metadata":{"unresolvedName":"validateUrl"}}],["symbol-name:validatePath",{"id":"symbol-name:validatePath","kind":"symbol","language":"jsts","symbolName":"validatePath","metadata":{"unresolvedName":"validatePath"}}],["external:Object.keys",{"id":"external:Object.keys","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.keys"}}],["symbol-name:onSave",{"id":"symbol-name:onSave","kind":"symbol","language":"jsts","symbolName":"onSave","metadata":{"unresolvedName":"onSave"}}],["symbol-name:handleChange",{"id":"symbol-name:handleChange","kind":"symbol","language":"jsts","symbolName":"handleChange","metadata":{"unresolvedName":"handleChange"}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"handleChange","symbolKind":"function","exported":false,"metadata":{"line":130,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":133,"column":17,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":141,"column":24,"cyclomaticComplexity":7,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","metadata":{"lineCount":277,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","metadata":{"lineCount":145,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"GitToolbar","symbolKind":"function","exported":true,"metadata":{"line":26,"column":27,"cyclomaticComplexity":34,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:getRepositoryStatus",{"id":"symbol-name:getRepositoryStatus","kind":"symbol","language":"jsts","symbolName":"getRepositoryStatus","metadata":{"unresolvedName":"getRepositoryStatus"}}],["symbol-name:loadStatus",{"id":"symbol-name:loadStatus","kind":"symbol","language":"jsts","symbolName":"loadStatus","metadata":{"unresolvedName":"loadStatus"}}],["symbol-name:fetchRepository",{"id":"symbol-name:fetchRepository","kind":"symbol","language":"jsts","symbolName":"fetchRepository","metadata":{"unresolvedName":"fetchRepository"}}],["symbol-name:pullRepository",{"id":"symbol-name:pullRepository","kind":"symbol","language":"jsts","symbolName":"pullRepository","metadata":{"unresolvedName":"pullRepository"}}],["symbol-name:onRefresh",{"id":"symbol-name:onRefresh","kind":"symbol","language":"jsts","symbolName":"onRefresh","metadata":{"unresolvedName":"onRefresh"}}],["symbol-name:pushRepository",{"id":"symbol-name:pushRepository","kind":"symbol","language":"jsts","symbolName":"pushRepository","metadata":{"unresolvedName":"pushRepository"}}],["symbol-name:checkoutBranch",{"id":"symbol-name:checkoutBranch","kind":"symbol","language":"jsts","symbolName":"checkoutBranch","metadata":{"unresolvedName":"checkoutBranch"}}],["symbol-name:onBranchChange",{"id":"symbol-name:onBranchChange","kind":"symbol","language":"jsts","symbolName":"onBranchChange","metadata":{"unresolvedName":"onBranchChange"}}],["external:newBranchName.trim",{"id":"external:newBranchName.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"newBranchName.trim"}}],["symbol-name:createBranch",{"id":"symbol-name:createBranch","kind":"symbol","language":"jsts","symbolName":"createBranch","metadata":{"unresolvedName":"createBranch"}}],["symbol-name:setShowNewBranch",{"id":"symbol-name:setShowNewBranch","kind":"symbol","language":"jsts","symbolName":"setShowNewBranch","metadata":{"unresolvedName":"setShowNewBranch"}}],["symbol-name:setNewBranchBase",{"id":"symbol-name:setNewBranchBase","kind":"symbol","language":"jsts","symbolName":"setNewBranchBase","metadata":{"unresolvedName":"setNewBranchBase"}}],["symbol-name:handleCheckout",{"id":"symbol-name:handleCheckout","kind":"symbol","language":"jsts","symbolName":"handleCheckout","metadata":{"unresolvedName":"handleCheckout"}}],["symbol-name:setShowMergeDialog",{"id":"symbol-name:setShowMergeDialog","kind":"symbol","language":"jsts","symbolName":"setShowMergeDialog","metadata":{"unresolvedName":"setShowMergeDialog"}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":269,"column":18,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"handleFetch","symbolKind":"function","exported":false,"metadata":{"line":61,"column":23,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"handlePull","symbolKind":"function","exported":false,"metadata":{"line":74,"column":22,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"handlePush","symbolKind":"function","exported":false,"metadata":{"line":88,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"handleCheckout","symbolKind":"function","exported":false,"metadata":{"line":100,"column":26,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch",{"id":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","symbolName":"handleCreateBranch","symbolKind":"function","exported":false,"metadata":{"line":113,"column":30,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:@phosphor-icons/react",{"id":"external:@phosphor-icons/react","kind":"external","language":"jsts","metadata":{"source":"@phosphor-icons/react"}}],["/home/alex/projects/headquarter/apps/web/src/components/icon.tsx:Icon",{"id":"/home/alex/projects/headquarter/apps/web/src/components/icon.tsx:Icon","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","symbolName":"Icon","symbolKind":"function","exported":true,"metadata":{"line":141,"column":42,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","metadata":{"lineCount":466,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"InstanceList","symbolKind":"function","exported":true,"metadata":{"line":28,"column":29,"cyclomaticComplexity":47,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useNavigate",{"id":"symbol-name:useNavigate","kind":"symbol","language":"jsts","symbolName":"useNavigate","metadata":{"unresolvedName":"useNavigate"}}],["symbol-name:listInstances",{"id":"symbol-name:listInstances","kind":"symbol","language":"jsts","symbolName":"listInstances","metadata":{"unresolvedName":"listInstances"}}],["symbol-name:setInstances",{"id":"symbol-name:setInstances","kind":"symbol","language":"jsts","symbolName":"setInstances","metadata":{"unresolvedName":"setInstances"}}],["symbol-name:loadInstances",{"id":"symbol-name:loadInstances","kind":"symbol","language":"jsts","symbolName":"loadInstances","metadata":{"unresolvedName":"loadInstances"}}],["external:instances.filter",{"id":"external:instances.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"instances.filter"}}],["external:i.url?.startsWith",{"id":"external:i.url?.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"i.url?.startsWith"}}],["symbol-name:checkInstanceHealth",{"id":"symbol-name:checkInstanceHealth","kind":"symbol","language":"jsts","symbolName":"checkInstanceHealth","metadata":{"unresolvedName":"checkInstanceHealth"}}],["symbol-name:setHealthStatus",{"id":"symbol-name:setHealthStatus","kind":"symbol","language":"jsts","symbolName":"setHealthStatus","metadata":{"unresolvedName":"setHealthStatus"}}],["external:Date.now",{"id":"external:Date.now","kind":"external","language":"jsts","metadata":{"unresolvedName":"Date.now"}}],["symbol-name:checkHealth",{"id":"symbol-name:checkHealth","kind":"symbol","language":"jsts","symbolName":"checkHealth","metadata":{"unresolvedName":"checkHealth"}}],["symbol-name:setShowCreate",{"id":"symbol-name:setShowCreate","kind":"symbol","language":"jsts","symbolName":"setShowCreate","metadata":{"unresolvedName":"setShowCreate"}}],["symbol-name:setBusyInstanceId",{"id":"symbol-name:setBusyInstanceId","kind":"symbol","language":"jsts","symbolName":"setBusyInstanceId","metadata":{"unresolvedName":"setBusyInstanceId"}}],["symbol-name:setProfileSelectInstanceId",{"id":"symbol-name:setProfileSelectInstanceId","kind":"symbol","language":"jsts","symbolName":"setProfileSelectInstanceId","metadata":{"unresolvedName":"setProfileSelectInstanceId"}}],["symbol-name:setSelectedProfileForAction",{"id":"symbol-name:setSelectedProfileForAction","kind":"symbol","language":"jsts","symbolName":"setSelectedProfileForAction","metadata":{"unresolvedName":"setSelectedProfileForAction"}}],["symbol-name:stopInstance",{"id":"symbol-name:stopInstance","kind":"symbol","language":"jsts","symbolName":"stopInstance","metadata":{"unresolvedName":"stopInstance"}}],["symbol-name:setStopConfirmId",{"id":"symbol-name:setStopConfirmId","kind":"symbol","language":"jsts","symbolName":"setStopConfirmId","metadata":{"unresolvedName":"setStopConfirmId"}}],["symbol-name:confirm",{"id":"symbol-name:confirm","kind":"symbol","language":"jsts","symbolName":"confirm","metadata":{"unresolvedName":"confirm"}}],["symbol-name:deleteInstance",{"id":"symbol-name:deleteInstance","kind":"symbol","language":"jsts","symbolName":"deleteInstance","metadata":{"unresolvedName":"deleteInstance"}}],["external:prev.filter",{"id":"external:prev.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"prev.filter"}}],["symbol-name:recreateInstanceTunnel",{"id":"symbol-name:recreateInstanceTunnel","kind":"symbol","language":"jsts","symbolName":"recreateInstanceTunnel","metadata":{"unresolvedName":"recreateInstanceTunnel"}}],["external:instance.url?.startsWith",{"id":"external:instance.url?.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"instance.url?.startsWith"}}],["external:instances.map",{"id":"external:instances.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"instances.map"}}],["symbol-name:getStatusColor",{"id":"symbol-name:getStatusColor","kind":"symbol","language":"jsts","symbolName":"getStatusColor","metadata":{"unresolvedName":"getStatusColor"}}],["symbol-name:isTunnelUnhealthy",{"id":"symbol-name:isTunnelUnhealthy","kind":"symbol","language":"jsts","symbolName":"isTunnelUnhealthy","metadata":{"unresolvedName":"isTunnelUnhealthy"}}],["external:configProfiles.find",{"id":"external:configProfiles.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"configProfiles.find"}}],["external:instance.tool_type_interfaces.includes",{"id":"external:instance.tool_type_interfaces.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"instance.tool_type_interfaces.includes"}}],["external:instance.url.startsWith",{"id":"external:instance.url.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"instance.url.startsWith"}}],["symbol-name:handleRecreateTunnel",{"id":"symbol-name:handleRecreateTunnel","kind":"symbol","language":"jsts","symbolName":"handleRecreateTunnel","metadata":{"unresolvedName":"handleRecreateTunnel"}}],["symbol-name:navigate",{"id":"symbol-name:navigate","kind":"symbol","language":"jsts","symbolName":"navigate","metadata":{"unresolvedName":"navigate"}}],["symbol-name:handleStart",{"id":"symbol-name:handleStart","kind":"symbol","language":"jsts","symbolName":"handleStart","metadata":{"unresolvedName":"handleStart"}}],["external:toolTypes.find",{"id":"external:toolTypes.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypes.find"}}],["symbol-name:loadConfigProfiles",{"id":"symbol-name:loadConfigProfiles","kind":"symbol","language":"jsts","symbolName":"loadConfigProfiles","metadata":{"unresolvedName":"loadConfigProfiles"}}],["symbol-name:handleStop",{"id":"symbol-name:handleStop","kind":"symbol","language":"jsts","symbolName":"handleStop","metadata":{"unresolvedName":"handleStop"}}],["symbol-name:handleRestart",{"id":"symbol-name:handleRestart","kind":"symbol","language":"jsts","symbolName":"handleRestart","metadata":{"unresolvedName":"handleRestart"}}],["symbol-name:handleDelete",{"id":"symbol-name:handleDelete","kind":"symbol","language":"jsts","symbolName":"handleDelete","metadata":{"unresolvedName":"handleDelete"}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":414,"column":34,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"checkHealth","symbolKind":"function","exported":false,"metadata":{"line":70,"column":25,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleCreateSuccess","symbolKind":"function","exported":false,"metadata":{"line":95,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleStart","symbolKind":"function","exported":false,"metadata":{"line":109,"column":23,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleStop","symbolKind":"function","exported":false,"metadata":{"line":123,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleRestart","symbolKind":"function","exported":false,"metadata":{"line":136,"column":25,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":150,"column":24,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"handleRecreateTunnel","symbolKind":"function","exported":false,"metadata":{"line":164,"column":32,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:getStatusColor",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:getStatusColor","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"getStatusColor","symbolKind":"function","exported":false,"metadata":{"line":176,"column":26,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy",{"id":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","symbolName":"isTunnelUnhealthy","symbolKind":"function","exported":false,"metadata":{"line":190,"column":29,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","metadata":{"lineCount":662,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","metadata":{"lineCount":10,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"ManifestEditor","symbolKind":"function","exported":true,"metadata":{"line":29,"column":31,"cyclomaticComplexity":44,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setBaseImage",{"id":"symbol-name:setBaseImage","kind":"symbol","language":"jsts","symbolName":"setBaseImage","metadata":{"unresolvedName":"setBaseImage"}}],["symbol-name:setBaseDefinitionId",{"id":"symbol-name:setBaseDefinitionId","kind":"symbol","language":"jsts","symbolName":"setBaseDefinitionId","metadata":{"unresolvedName":"setBaseDefinitionId"}}],["symbol-name:setAptPackages",{"id":"symbol-name:setAptPackages","kind":"symbol","language":"jsts","symbolName":"setAptPackages","metadata":{"unresolvedName":"setAptPackages"}}],["external:((pkgs.apt as string[]) || []).map",{"id":"external:((pkgs.apt as string[]) || []).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"((pkgs.apt as string[]) || []).map"}}],["symbol-name:setNpmPackages",{"id":"symbol-name:setNpmPackages","kind":"symbol","language":"jsts","symbolName":"setNpmPackages","metadata":{"unresolvedName":"setNpmPackages"}}],["external:((pkgs.npm_global as string[]) || []).map",{"id":"external:((pkgs.npm_global as string[]) || []).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"((pkgs.npm_global as string[]) || []).map"}}],["symbol-name:setPipPackages",{"id":"symbol-name:setPipPackages","kind":"symbol","language":"jsts","symbolName":"setPipPackages","metadata":{"unresolvedName":"setPipPackages"}}],["external:((pkgs.pip as string[]) || []).map",{"id":"external:((pkgs.pip as string[]) || []).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"((pkgs.pip as string[]) || []).map"}}],["symbol-name:setNodeVersion",{"id":"symbol-name:setNodeVersion","kind":"symbol","language":"jsts","symbolName":"setNodeVersion","metadata":{"unresolvedName":"setNodeVersion"}}],["symbol-name:setUserName",{"id":"symbol-name:setUserName","kind":"symbol","language":"jsts","symbolName":"setUserName","metadata":{"unresolvedName":"setUserName"}}],["symbol-name:setUserUid",{"id":"symbol-name:setUserUid","kind":"symbol","language":"jsts","symbolName":"setUserUid","metadata":{"unresolvedName":"setUserUid"}}],["symbol-name:setUserGid",{"id":"symbol-name:setUserGid","kind":"symbol","language":"jsts","symbolName":"setUserGid","metadata":{"unresolvedName":"setUserGid"}}],["symbol-name:setEnvVars",{"id":"symbol-name:setEnvVars","kind":"symbol","language":"jsts","symbolName":"setEnvVars","metadata":{"unresolvedName":"setEnvVars"}}],["external:Object.entries(env).map",{"id":"external:Object.entries(env).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(env).map"}}],["external:Object.entries",{"id":"external:Object.entries","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries"}}],["symbol-name:setBuildScripts",{"id":"symbol-name:setBuildScripts","kind":"symbol","language":"jsts","symbolName":"setBuildScripts","metadata":{"unresolvedName":"setBuildScripts"}}],["symbol-name:setStartupScripts",{"id":"symbol-name:setStartupScripts","kind":"symbol","language":"jsts","symbolName":"setStartupScripts","metadata":{"unresolvedName":"setStartupScripts"}}],["symbol-name:setMounts",{"id":"symbol-name:setMounts","kind":"symbol","language":"jsts","symbolName":"setMounts","metadata":{"unresolvedName":"setMounts"}}],["symbol-name:setCommand",{"id":"symbol-name:setCommand","kind":"symbol","language":"jsts","symbolName":"setCommand","metadata":{"unresolvedName":"setCommand"}}],["symbol-name:setWorkingDir",{"id":"symbol-name:setWorkingDir","kind":"symbol","language":"jsts","symbolName":"setWorkingDir","metadata":{"unresolvedName":"setWorkingDir"}}],["symbol-name:setStdinOpen",{"id":"symbol-name:setStdinOpen","kind":"symbol","language":"jsts","symbolName":"setStdinOpen","metadata":{"unresolvedName":"setStdinOpen"}}],["symbol-name:setTty",{"id":"symbol-name:setTty","kind":"symbol","language":"jsts","symbolName":"setTty","metadata":{"unresolvedName":"setTty"}}],["external:aptPackages.map((p) => p.name).filter",{"id":"external:aptPackages.map((p) => p.name).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"aptPackages.map((p) => p.name).filter"}}],["external:aptPackages.map",{"id":"external:aptPackages.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"aptPackages.map"}}],["external:npmPackages.map((p) => p.name).filter",{"id":"external:npmPackages.map((p) => p.name).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"npmPackages.map((p) => p.name).filter"}}],["external:npmPackages.map",{"id":"external:npmPackages.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"npmPackages.map"}}],["external:pipPackages.map((p) => p.name).filter",{"id":"external:pipPackages.map((p) => p.name).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"pipPackages.map((p) => p.name).filter"}}],["external:pipPackages.map",{"id":"external:pipPackages.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"pipPackages.map"}}],["external:envVars.forEach",{"id":"external:envVars.forEach","kind":"external","language":"jsts","metadata":{"unresolvedName":"envVars.forEach"}}],["external:buildScripts.filter",{"id":"external:buildScripts.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"buildScripts.filter"}}],["external:startupScripts.filter",{"id":"external:startupScripts.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"startupScripts.filter"}}],["symbol-name:parseInt",{"id":"symbol-name:parseInt","kind":"symbol","language":"jsts","symbolName":"parseInt","metadata":{"unresolvedName":"parseInt"}}],["external:command.filter",{"id":"external:command.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"command.filter"}}],["symbol-name:buildManifest",{"id":"symbol-name:buildManifest","kind":"symbol","language":"jsts","symbolName":"buildManifest","metadata":{"unresolvedName":"buildManifest"}}],["symbol-name:setPreviewError",{"id":"symbol-name:setPreviewError","kind":"symbol","language":"jsts","symbolName":"setPreviewError","metadata":{"unresolvedName":"setPreviewError"}}],["symbol-name:setPreviewLoading",{"id":"symbol-name:setPreviewLoading","kind":"symbol","language":"jsts","symbolName":"setPreviewLoading","metadata":{"unresolvedName":"setPreviewLoading"}}],["symbol-name:compileToolDefinition",{"id":"symbol-name:compileToolDefinition","kind":"symbol","language":"jsts","symbolName":"compileToolDefinition","metadata":{"unresolvedName":"compileToolDefinition"}}],["symbol-name:setPreview",{"id":"symbol-name:setPreview","kind":"symbol","language":"jsts","symbolName":"setPreview","metadata":{"unresolvedName":"setPreview"}}],["symbol-name:extractErrorMessage",{"id":"symbol-name:extractErrorMessage","kind":"symbol","language":"jsts","symbolName":"extractErrorMessage","metadata":{"unresolvedName":"extractErrorMessage"}}],["external:aptPackages.filter",{"id":"external:aptPackages.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"aptPackages.filter"}}],["external:npmPackages.filter",{"id":"external:npmPackages.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"npmPackages.filter"}}],["external:pipPackages.filter",{"id":"external:pipPackages.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"pipPackages.filter"}}],["external:envVars.filter",{"id":"external:envVars.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"envVars.filter"}}],["external:baseDefinitions.map",{"id":"external:baseDefinitions.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"baseDefinitions.map"}}],["symbol-name:updateAptPackage",{"id":"symbol-name:updateAptPackage","kind":"symbol","language":"jsts","symbolName":"updateAptPackage","metadata":{"unresolvedName":"updateAptPackage"}}],["symbol-name:removeAptPackage",{"id":"symbol-name:removeAptPackage","kind":"symbol","language":"jsts","symbolName":"removeAptPackage","metadata":{"unresolvedName":"removeAptPackage"}}],["symbol-name:updateNpmPackage",{"id":"symbol-name:updateNpmPackage","kind":"symbol","language":"jsts","symbolName":"updateNpmPackage","metadata":{"unresolvedName":"updateNpmPackage"}}],["symbol-name:removeNpmPackage",{"id":"symbol-name:removeNpmPackage","kind":"symbol","language":"jsts","symbolName":"removeNpmPackage","metadata":{"unresolvedName":"removeNpmPackage"}}],["symbol-name:updatePipPackage",{"id":"symbol-name:updatePipPackage","kind":"symbol","language":"jsts","symbolName":"updatePipPackage","metadata":{"unresolvedName":"updatePipPackage"}}],["symbol-name:removePipPackage",{"id":"symbol-name:removePipPackage","kind":"symbol","language":"jsts","symbolName":"removePipPackage","metadata":{"unresolvedName":"removePipPackage"}}],["external:envVars.map",{"id":"external:envVars.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"envVars.map"}}],["symbol-name:updateEnvVar",{"id":"symbol-name:updateEnvVar","kind":"symbol","language":"jsts","symbolName":"updateEnvVar","metadata":{"unresolvedName":"updateEnvVar"}}],["symbol-name:removeEnvVar",{"id":"symbol-name:removeEnvVar","kind":"symbol","language":"jsts","symbolName":"removeEnvVar","metadata":{"unresolvedName":"removeEnvVar"}}],["external:buildScripts.map",{"id":"external:buildScripts.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"buildScripts.map"}}],["symbol-name:updateBuildScript",{"id":"symbol-name:updateBuildScript","kind":"symbol","language":"jsts","symbolName":"updateBuildScript","metadata":{"unresolvedName":"updateBuildScript"}}],["symbol-name:removeBuildScript",{"id":"symbol-name:removeBuildScript","kind":"symbol","language":"jsts","symbolName":"removeBuildScript","metadata":{"unresolvedName":"removeBuildScript"}}],["external:startupScripts.map",{"id":"external:startupScripts.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"startupScripts.map"}}],["symbol-name:updateStartupScript",{"id":"symbol-name:updateStartupScript","kind":"symbol","language":"jsts","symbolName":"updateStartupScript","metadata":{"unresolvedName":"updateStartupScript"}}],["symbol-name:removeStartupScript",{"id":"symbol-name:removeStartupScript","kind":"symbol","language":"jsts","symbolName":"removeStartupScript","metadata":{"unresolvedName":"removeStartupScript"}}],["symbol-name:updateMount",{"id":"symbol-name:updateMount","kind":"symbol","language":"jsts","symbolName":"updateMount","metadata":{"unresolvedName":"updateMount"}}],["symbol-name:removeMount",{"id":"symbol-name:removeMount","kind":"symbol","language":"jsts","symbolName":"removeMount","metadata":{"unresolvedName":"removeMount"}}],["external:command.join",{"id":"external:command.join","kind":"external","language":"jsts","metadata":{"unresolvedName":"command.join"}}],["external:e.target.value.split",{"id":"external:e.target.value.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"e.target.value.split"}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":262,"column":25,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"handlePreview","symbolKind":"function","exported":false,"metadata":{"line":142,"column":25,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateAptPackage","symbolKind":"function","exported":false,"metadata":{"line":165,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateNpmPackage","symbolKind":"function","exported":false,"metadata":{"line":173,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updatePipPackage","symbolKind":"function","exported":false,"metadata":{"line":181,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateEnvVar",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateEnvVar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateEnvVar","symbolKind":"function","exported":false,"metadata":{"line":189,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateBuildScript","symbolKind":"function","exported":false,"metadata":{"line":197,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateStartupScript","symbolKind":"function","exported":false,"metadata":{"line":205,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateMount",{"id":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateMount","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","symbolName":"updateMount","symbolKind":"function","exported":false,"metadata":{"line":227,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog",{"id":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","symbolName":"MergeDialog","symbolKind":"function","exported":true,"metadata":{"line":16,"column":28,"cyclomaticComplexity":10,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:branches.filter",{"id":"external:branches.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"branches.filter"}}],["symbol-name:setSuccess",{"id":"symbol-name:setSuccess","kind":"symbol","language":"jsts","symbolName":"setSuccess","metadata":{"unresolvedName":"setSuccess"}}],["symbol-name:mergeBranches",{"id":"symbol-name:mergeBranches","kind":"symbol","language":"jsts","symbolName":"mergeBranches","metadata":{"unresolvedName":"mergeBranches"}}],["symbol-name:onMerge",{"id":"symbol-name:onMerge","kind":"symbol","language":"jsts","symbolName":"onMerge","metadata":{"unresolvedName":"onMerge"}}],["symbol-name:onClose",{"id":"symbol-name:onClose","kind":"symbol","language":"jsts","symbolName":"onClose","metadata":{"unresolvedName":"onClose"}}],["external:e.stopPropagation",{"id":"external:e.stopPropagation","kind":"external","language":"jsts","metadata":{"unresolvedName":"e.stopPropagation"}}],["symbol-name:setSourceBranch",{"id":"symbol-name:setSourceBranch","kind":"symbol","language":"jsts","symbolName":"setSourceBranch","metadata":{"unresolvedName":"setSourceBranch"}}],["external:availableBranches.map",{"id":"external:availableBranches.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"availableBranches.map"}}],["symbol-name:setCommitMessage",{"id":"symbol-name:setCommitMessage","kind":"symbol","language":"jsts","symbolName":"setCommitMessage","metadata":{"unresolvedName":"setCommitMessage"}}],["/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge",{"id":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","symbolName":"handleMerge","symbolKind":"function","exported":false,"metadata":{"line":35,"column":23,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":52,"column":18,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","metadata":{"lineCount":89,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","symbolName":"MobileActionSheet","symbolKind":"function","exported":true,"metadata":{"line":20,"column":1,"cyclomaticComplexity":7,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useRef",{"id":"symbol-name:useRef","kind":"symbol","language":"jsts","symbolName":"useRef","metadata":{"unresolvedName":"useRef"}}],["external:document.addEventListener",{"id":"external:document.addEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.addEventListener"}}],["external:document.removeEventListener",{"id":"external:document.removeEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.removeEventListener"}}],["external:actions.map",{"id":"external:actions.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"actions.map"}}],["external:action.onClick",{"id":"external:action.onClick","kind":"external","language":"jsts","metadata":{"unresolvedName":"action.onClick"}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":67,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:handleEscape",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:handleEscape","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","symbolName":"handleEscape","symbolKind":"function","exported":false,"metadata":{"line":40,"column":26,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","metadata":{"lineCount":96,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","symbolName":"MobileDetailView","symbolKind":"function","exported":true,"metadata":{"line":18,"column":66,"cyclomaticComplexity":9,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:JSON.stringify",{"id":"external:JSON.stringify","kind":"external","language":"jsts","metadata":{"unresolvedName":"JSON.stringify"}}],["external:fields.map",{"id":"external:fields.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"fields.map"}}],["symbol-name:renderValue",{"id":"symbol-name:renderValue","kind":"symbol","language":"jsts","symbolName":"renderValue","metadata":{"unresolvedName":"renderValue"}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","symbolName":"renderValue","symbolKind":"function","exported":false,"metadata":{"line":26,"column":23,"cyclomaticComplexity":8,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","metadata":{"lineCount":162,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","symbolName":"MobileEditView","symbolKind":"function","exported":true,"metadata":{"line":23,"column":62,"cyclomaticComplexity":18,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:fields?.forEach",{"id":"external:fields?.forEach","kind":"external","language":"jsts","metadata":{"unresolvedName":"fields?.forEach"}}],["symbol-name:setFormData",{"id":"symbol-name:setFormData","kind":"symbol","language":"jsts","symbolName":"setFormData","metadata":{"unresolvedName":"setFormData"}}],["external:fields?.map",{"id":"external:fields?.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"fields?.map"}}],["external:field.options?.map",{"id":"external:field.options?.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"field.options?.map"}}],["symbol-name:Boolean",{"id":"symbol-name:Boolean","kind":"symbol","language":"jsts","symbolName":"Boolean","metadata":{"unresolvedName":"Boolean"}}],["symbol-name:Number",{"id":"symbol-name:Number","kind":"symbol","language":"jsts","symbolName":"Number","metadata":{"unresolvedName":"Number"}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":34,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleChange",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","symbolName":"handleChange","symbolKind":"function","exported":false,"metadata":{"line":41,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":45,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","metadata":{"lineCount":23,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx:MobileFAB",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx:MobileFAB","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","symbolName":"MobileFAB","symbolKind":"function","exported":true,"metadata":{"line":8,"column":52,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","metadata":{"lineCount":77,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","symbolName":"MobileListView","symbolKind":"function","exported":true,"metadata":{"line":22,"column":62,"cyclomaticComplexity":5,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:onSearch",{"id":"symbol-name:onSearch","kind":"symbol","language":"jsts","symbolName":"onSearch","metadata":{"unresolvedName":"onSearch"}}],["external:items.map",{"id":"external:items.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"items.map"}}],["symbol-name:onItemClick",{"id":"symbol-name:onItemClick","kind":"symbol","language":"jsts","symbolName":"onItemClick","metadata":{"unresolvedName":"onItemClick"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","metadata":{"lineCount":63,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","symbolName":"MobileNav","symbolKind":"function","exported":true,"metadata":{"line":26,"column":52,"cyclomaticComplexity":8,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setToolsSheetOpen",{"id":"symbol-name:setToolsSheetOpen","kind":"symbol","language":"jsts","symbolName":"setToolsSheetOpen","metadata":{"unresolvedName":"setToolsSheetOpen"}}],["external:MOBILE_NAV_ITEMS.map",{"id":"external:MOBILE_NAV_ITEMS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"MOBILE_NAV_ITEMS.map"}}],["symbol-name:handleNavClick",{"id":"symbol-name:handleNavClick","kind":"symbol","language":"jsts","symbolName":"handleNavClick","metadata":{"unresolvedName":"handleNavClick"}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","symbolName":"handleNavClick","symbolKind":"function","exported":false,"metadata":{"line":34,"column":26,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":43,"column":31,"cyclomaticComplexity":6,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","metadata":{"lineCount":34,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","symbolName":"MobilePageHeader","symbolKind":"function","exported":true,"metadata":{"line":11,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","metadata":{"lineCount":95,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:MobileTerminalHeader",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:MobileTerminalHeader","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","symbolName":"MobileTerminalHeader","symbolKind":"function","exported":true,"metadata":{"line":14,"column":74,"cyclomaticComplexity":7,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:onFontSizeChange",{"id":"symbol-name:onFontSizeChange","kind":"symbol","language":"jsts","symbolName":"onFontSizeChange","metadata":{"unresolvedName":"onFontSizeChange"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","metadata":{"lineCount":117,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","metadata":{"lineCount":641,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","metadata":{"lineCount":97,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","metadata":{"lineCount":115,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","metadata":{"lineCount":69,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","metadata":{"lineCount":69,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","metadata":{"lineCount":141,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","symbolName":"MobileTerminalWrapper","symbolKind":"function","exported":true,"metadata":{"line":19,"column":76,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useVirtualKeyboard",{"id":"symbol-name:useVirtualKeyboard","kind":"symbol","language":"jsts","symbolName":"useVirtualKeyboard","metadata":{"unresolvedName":"useVirtualKeyboard"}}],["symbol-name:useAutoHide",{"id":"symbol-name:useAutoHide","kind":"symbol","language":"jsts","symbolName":"useAutoHide","metadata":{"unresolvedName":"useAutoHide"}}],["external:headerAutoHide.toggle",{"id":"external:headerAutoHide.toggle","kind":"external","language":"jsts","metadata":{"unresolvedName":"headerAutoHide.toggle"}}],["symbol-name:setTerminalRef",{"id":"symbol-name:setTerminalRef","kind":"symbol","language":"jsts","symbolName":"setTerminalRef","metadata":{"unresolvedName":"setTerminalRef"}}],["external:terminalRef?.sendData",{"id":"external:terminalRef?.sendData","kind":"external","language":"jsts","metadata":{"unresolvedName":"terminalRef?.sendData"}}],["external:terminalRef?.changeFontSize",{"id":"external:terminalRef?.changeFontSize","kind":"external","language":"jsts","metadata":{"unresolvedName":"terminalRef?.changeFontSize"}}],["symbol-name:setShowPanel",{"id":"symbol-name:setShowPanel","kind":"symbol","language":"jsts","symbolName":"setShowPanel","metadata":{"unresolvedName":"setShowPanel"}}],["external:terminalRef?.focusInput",{"id":"external:terminalRef?.focusInput","kind":"external","language":"jsts","metadata":{"unresolvedName":"terminalRef?.focusInput"}}],["/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":52,"column":5,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","metadata":{"lineCount":50,"featureKind":"library","trustBoundaries":[]}}],["external:@testing-library/react",{"id":"external:@testing-library/react","kind":"external","language":"jsts","metadata":{"source":"@testing-library/react"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","metadata":{"lineCount":20,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":28,"column":50,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:mockUseAuth.mockReturnValue",{"id":"external:mockUseAuth.mockReturnValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockUseAuth.mockReturnValue"}}],["symbol-name:render",{"id":"symbol-name:render","kind":"symbol","language":"jsts","symbolName":"render","metadata":{"unresolvedName":"render"}}],["external:expect(screen.getByText(\"Checking session...\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Checking session...\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Checking session...\")).toBeInTheDocument"}}],["external:screen.getByText",{"id":"external:screen.getByText","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByText"}}],["external:expect(screen.getByText(\"login page\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"login page\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"login page\")).toBeInTheDocument"}}],["/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute",{"id":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","symbolName":"ProtectedRoute","symbolKind":"function","exported":true,"metadata":{"line":5,"column":31,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:encodeURIComponent",{"id":"symbol-name:encodeURIComponent","kind":"symbol","language":"jsts","symbolName":"encodeURIComponent","metadata":{"unresolvedName":"encodeURIComponent"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","metadata":{"lineCount":115,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","metadata":{"lineCount":100,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":99,"column":19,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["external:vi.importActual",{"id":"external:vi.importActual","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.importActual"}}],["symbol-name:cleanup",{"id":"symbol-name:cleanup","kind":"symbol","language":"jsts","symbolName":"cleanup","metadata":{"unresolvedName":"cleanup"}}],["external:vi.restoreAllMocks",{"id":"external:vi.restoreAllMocks","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.restoreAllMocks"}}],["external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue",{"id":"external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue"}}],["external:vi.spyOn",{"id":"external:vi.spyOn","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn"}}],["external:vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue",{"id":"external:vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue"}}],["symbol-name:waitFor",{"id":"symbol-name:waitFor","kind":"symbol","language":"jsts","symbolName":"waitFor","metadata":{"unresolvedName":"waitFor"}}],["external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}}],["external:fireEvent.click",{"id":"external:fireEvent.click","kind":"external","language":"jsts","metadata":{"unresolvedName":"fireEvent.click"}}],["external:screen.getByRole",{"id":"external:screen.getByRole","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByRole"}}],["external:fireEvent.change",{"id":"external:fireEvent.change","kind":"external","language":"jsts","metadata":{"unresolvedName":"fireEvent.change"}}],["external:screen.getByPlaceholderText",{"id":"external:screen.getByPlaceholderText","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByPlaceholderText"}}],["external:expect(createMock).toHaveBeenCalledWith",{"id":"external:expect(createMock).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}}],["external:expect(listMock).toHaveBeenCalledTimes",{"id":"external:expect(listMock).toHaveBeenCalledTimes","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","metadata":{"lineCount":344,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","symbolName":"RepositoriesSettingsTab","symbolKind":"function","exported":true,"metadata":{"line":8,"column":50,"cyclomaticComplexity":11,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["symbol-name:useParams",{"id":"symbol-name:useParams","kind":"symbol","language":"jsts","symbolName":"useParams","metadata":{"unresolvedName":"useParams"}}],["symbol-name:listRepositories",{"id":"symbol-name:listRepositories","kind":"symbol","language":"jsts","symbolName":"listRepositories","metadata":{"unresolvedName":"listRepositories"}}],["symbol-name:setRepositories",{"id":"symbol-name:setRepositories","kind":"symbol","language":"jsts","symbolName":"setRepositories","metadata":{"unresolvedName":"setRepositories"}}],["symbol-name:loadRepositories",{"id":"symbol-name:loadRepositories","kind":"symbol","language":"jsts","symbolName":"loadRepositories","metadata":{"unresolvedName":"loadRepositories"}}],["external:window.confirm",{"id":"external:window.confirm","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.confirm"}}],["symbol-name:deleteRepository",{"id":"symbol-name:deleteRepository","kind":"symbol","language":"jsts","symbolName":"deleteRepository","metadata":{"unresolvedName":"deleteRepository"}}],["external:current.filter",{"id":"external:current.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"current.filter"}}],["external:repositories.map",{"id":"external:repositories.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"repositories.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":32,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":36,"column":24,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"RepositoryCreateDialog","symbolKind":"function","exported":true,"metadata":{"line":18,"column":39,"cyclomaticComplexity":40,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["symbol-name:clearTimeout",{"id":"symbol-name:clearTimeout","kind":"symbol","language":"jsts","symbolName":"clearTimeout","metadata":{"unresolvedName":"clearTimeout"}}],["symbol-name:setUrlValidation",{"id":"symbol-name:setUrlValidation","kind":"symbol","language":"jsts","symbolName":"setUrlValidation","metadata":{"unresolvedName":"setUrlValidation"}}],["external:advancedUrl.trim",{"id":"external:advancedUrl.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"advancedUrl.trim"}}],["symbol-name:parseGitUrl",{"id":"symbol-name:parseGitUrl","kind":"symbol","language":"jsts","symbolName":"parseGitUrl","metadata":{"unresolvedName":"parseGitUrl"}}],["symbol-name:setCreateMode",{"id":"symbol-name:setCreateMode","kind":"symbol","language":"jsts","symbolName":"setCreateMode","metadata":{"unresolvedName":"setCreateMode"}}],["symbol-name:setFormName",{"id":"symbol-name:setFormName","kind":"symbol","language":"jsts","symbolName":"setFormName","metadata":{"unresolvedName":"setFormName"}}],["symbol-name:setOwner",{"id":"symbol-name:setOwner","kind":"symbol","language":"jsts","symbolName":"setOwner","metadata":{"unresolvedName":"setOwner"}}],["symbol-name:setRepoName",{"id":"symbol-name:setRepoName","kind":"symbol","language":"jsts","symbolName":"setRepoName","metadata":{"unresolvedName":"setRepoName"}}],["symbol-name:setAdvancedUrl",{"id":"symbol-name:setAdvancedUrl","kind":"symbol","language":"jsts","symbolName":"setAdvancedUrl","metadata":{"unresolvedName":"setAdvancedUrl"}}],["symbol-name:setUseAdvancedUrl",{"id":"symbol-name:setUseAdvancedUrl","kind":"symbol","language":"jsts","symbolName":"setUseAdvancedUrl","metadata":{"unresolvedName":"setUseAdvancedUrl"}}],["symbol-name:setFormError",{"id":"symbol-name:setFormError","kind":"symbol","language":"jsts","symbolName":"setFormError","metadata":{"unresolvedName":"setFormError"}}],["symbol-name:setSelectedSshKey",{"id":"symbol-name:setSelectedSshKey","kind":"symbol","language":"jsts","symbolName":"setSelectedSshKey","metadata":{"unresolvedName":"setSelectedSshKey"}}],["symbol-name:resetForm",{"id":"symbol-name:resetForm","kind":"symbol","language":"jsts","symbolName":"resetForm","metadata":{"unresolvedName":"resetForm"}}],["external:formName.trim",{"id":"external:formName.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"formName.trim"}}],["external:owner.trim",{"id":"external:owner.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"owner.trim"}}],["external:repoName.trim",{"id":"external:repoName.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"repoName.trim"}}],["symbol-name:createRepository",{"id":"symbol-name:createRepository","kind":"symbol","language":"jsts","symbolName":"createRepository","metadata":{"unresolvedName":"createRepository"}}],["symbol-name:handleClose",{"id":"symbol-name:handleClose","kind":"symbol","language":"jsts","symbolName":"handleClose","metadata":{"unresolvedName":"handleClose"}}],["symbol-name:onCreated",{"id":"symbol-name:onCreated","kind":"symbol","language":"jsts","symbolName":"onCreated","metadata":{"unresolvedName":"onCreated"}}],["external:sshKeys.map",{"id":"external:sshKeys.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"sshKeys.map"}}],["symbol-name:getUrlInputClass",{"id":"symbol-name:getUrlInputClass","kind":"symbol","language":"jsts","symbolName":"getUrlInputClass","metadata":{"unresolvedName":"getUrlInputClass"}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":87,"column":12,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"loadKeys","symbolKind":"function","exported":false,"metadata":{"line":43,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"resetForm","symbolKind":"function","exported":false,"metadata":{"line":94,"column":21,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"handleClose","symbolKind":"function","exported":false,"metadata":{"line":106,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":111,"column":24,"cyclomaticComplexity":10,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"handleUseSuggestedUrl","symbolKind":"function","exported":false,"metadata":{"line":155,"column":33,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:getUrlInputClass",{"id":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:getUrlInputClass","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","symbolName":"getUrlInputClass","symbolKind":"function","exported":false,"metadata":{"line":163,"column":28,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","metadata":{"lineCount":339,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard",{"id":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","symbolName":"SessionCard","symbolKind":"function","exported":true,"metadata":{"line":39,"column":1,"cyclomaticComplexity":38,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["external:session.tool_type_interfaces?.includes",{"id":"external:session.tool_type_interfaces?.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"session.tool_type_interfaces?.includes"}}],["symbol-name:setShowStopConfirm",{"id":"symbol-name:setShowStopConfirm","kind":"symbol","language":"jsts","symbolName":"setShowStopConfirm","metadata":{"unresolvedName":"setShowStopConfirm"}}],["symbol-name:onStop",{"id":"symbol-name:onStop","kind":"symbol","language":"jsts","symbolName":"onStop","metadata":{"unresolvedName":"onStop"}}],["symbol-name:setShowDeleteConfirm",{"id":"symbol-name:setShowDeleteConfirm","kind":"symbol","language":"jsts","symbolName":"setShowDeleteConfirm","metadata":{"unresolvedName":"setShowDeleteConfirm"}}],["symbol-name:onDelete",{"id":"symbol-name:onDelete","kind":"symbol","language":"jsts","symbolName":"onDelete","metadata":{"unresolvedName":"onDelete"}}],["external:[\"running\", \"building\", \"starting\", \"probing\", \"pending\", \"unhealthy\"].includes",{"id":"external:[\"running\", \"building\", \"starting\", \"probing\", \"pending\", \"unhealthy\"].includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"[\"running\", \"building\", \"starting\", \"probing\", \"pending\", \"unhealthy\"].includes"}}],["external:new Date(session.created_at).toLocaleString",{"id":"external:new Date(session.created_at).toLocaleString","kind":"external","language":"jsts","metadata":{"unresolvedName":"new Date(session.created_at).toLocaleString"}}],["symbol-name:onOpen",{"id":"symbol-name:onOpen","kind":"symbol","language":"jsts","symbolName":"onOpen","metadata":{"unresolvedName":"onOpen"}}],["symbol-name:setShowActionSheet",{"id":"symbol-name:setShowActionSheet","kind":"symbol","language":"jsts","symbolName":"setShowActionSheet","metadata":{"unresolvedName":"setShowActionSheet"}}],["symbol-name:onStart",{"id":"symbol-name:onStart","kind":"symbol","language":"jsts","symbolName":"onStart","metadata":{"unresolvedName":"onStart"}}],["symbol-name:onRecreateTunnel",{"id":"symbol-name:onRecreateTunnel","kind":"symbol","language":"jsts","symbolName":"onRecreateTunnel","metadata":{"unresolvedName":"onRecreateTunnel"}}],["/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop",{"id":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","symbolName":"handleStop","symbolKind":"function","exported":false,"metadata":{"line":59,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":68,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","metadata":{"lineCount":126,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList",{"id":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","symbolName":"SessionList","symbolKind":"function","exported":true,"metadata":{"line":24,"column":1,"cyclomaticComplexity":9,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["external:activeStatuses.includes",{"id":"external:activeStatuses.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"activeStatuses.includes"}}],["external:sessions\n .filter((s) => recentStatuses.includes(s.status))\n .slice",{"id":"external:sessions\n .filter((s) => recentStatuses.includes(s.status))\n .slice","kind":"external","language":"jsts","metadata":{"unresolvedName":"sessions\n .filter((s) => recentStatuses.includes(s.status))\n .slice"}}],["external:sessions\n .filter",{"id":"external:sessions\n .filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"sessions\n .filter"}}],["external:recentStatuses.includes",{"id":"external:recentStatuses.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"recentStatuses.includes"}}],["external:activeSessions.map",{"id":"external:activeSessions.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"activeSessions.map"}}],["external:recentSessions.map",{"id":"external:recentSessions.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"recentSessions.map"}}],["file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","metadata":{"lineCount":44,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout",{"id":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","symbolName":"SettingsTabLayout","symbolKind":"function","exported":true,"metadata":{"line":16,"column":68,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:tabs.map",{"id":"external:tabs.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"tabs.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","symbolName":"SpecialKeysPanel","symbolKind":"function","exported":true,"metadata":{"line":38,"column":66,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:getSequenceWithModifier",{"id":"symbol-name:getSequenceWithModifier","kind":"symbol","language":"jsts","symbolName":"getSequenceWithModifier","metadata":{"unresolvedName":"getSequenceWithModifier"}}],["symbol-name:onSend",{"id":"symbol-name:onSend","kind":"symbol","language":"jsts","symbolName":"onSend","metadata":{"unresolvedName":"onSend"}}],["symbol-name:onModifierChange",{"id":"symbol-name:onModifierChange","kind":"symbol","language":"jsts","symbolName":"onModifierChange","metadata":{"unresolvedName":"onModifierChange"}}],["symbol-name:requestAnimationFrame",{"id":"symbol-name:requestAnimationFrame","kind":"symbol","language":"jsts","symbolName":"requestAnimationFrame","metadata":{"unresolvedName":"requestAnimationFrame"}}],["symbol-name:onKeepFocus",{"id":"symbol-name:onKeepFocus","kind":"symbol","language":"jsts","symbolName":"onKeepFocus","metadata":{"unresolvedName":"onKeepFocus"}}],["external:EXPANDED_KEYS.map",{"id":"external:EXPANDED_KEYS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"EXPANDED_KEYS.map"}}],["symbol-name:handlePointerDown",{"id":"symbol-name:handlePointerDown","kind":"symbol","language":"jsts","symbolName":"handlePointerDown","metadata":{"unresolvedName":"handlePointerDown"}}],["external:F_KEYS.map",{"id":"external:F_KEYS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"F_KEYS.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","symbolName":"handlePointerDown","symbolKind":"function","exported":false,"metadata":{"line":48,"column":29,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":70,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","symbolName":"handleOverlayPointerDown","symbolKind":"function","exported":false,"metadata":{"line":66,"column":36,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","symbolName":"SpecialKeysStrip","symbolKind":"function","exported":true,"metadata":{"line":24,"column":66,"cyclomaticComplexity":11,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:onMoreClick",{"id":"symbol-name:onMoreClick","kind":"symbol","language":"jsts","symbolName":"onMoreClick","metadata":{"unresolvedName":"onMoreClick"}}],["external:PRIMARY_KEYS.map",{"id":"external:PRIMARY_KEYS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"PRIMARY_KEYS.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","symbolName":"handlePointerDown","symbolKind":"function","exported":false,"metadata":{"line":32,"column":29,"cyclomaticComplexity":6,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":61,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown",{"id":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","symbolName":"handleMorePointerDown","symbolKind":"function","exported":false,"metadata":{"line":58,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter",{"id":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","symbolName":"SyntaxHighlighter","symbolKind":"function","exported":true,"metadata":{"line":12,"column":68,"cyclomaticComplexity":3,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setHighlighted",{"id":"symbol-name:setHighlighted","kind":"symbol","language":"jsts","symbolName":"setHighlighted","metadata":{"unresolvedName":"setHighlighted"}}],["external:navigator.clipboard.writeText",{"id":"external:navigator.clipboard.writeText","kind":"external","language":"jsts","metadata":{"unresolvedName":"navigator.clipboard.writeText"}}],["symbol-name:setCopied",{"id":"symbol-name:setCopied","kind":"symbol","language":"jsts","symbolName":"setCopied","metadata":{"unresolvedName":"setCopied"}}],["external:code.split",{"id":"external:code.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"code.split"}}],["external:lines.map",{"id":"external:lines.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"lines.map"}}],["/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":20,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight",{"id":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","symbolName":"highlight","symbolKind":"function","exported":false,"metadata":{"line":21,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy",{"id":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","symbolName":"handleCopy","symbolKind":"function","exported":false,"metadata":{"line":28,"column":22,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:xterm",{"id":"external:xterm","kind":"external","language":"jsts","metadata":{"source":"xterm"}}],["external:xterm-addon-fit",{"id":"external:xterm-addon-fit","kind":"external","language":"jsts","metadata":{"source":"xterm-addon-fit"}}],["external:xterm-addon-web-links",{"id":"external:xterm-addon-web-links","kind":"external","language":"jsts","metadata":{"source":"xterm-addon-web-links"}}],["external:xterm/css/xterm.css",{"id":"external:xterm/css/xterm.css","kind":"external","language":"jsts","metadata":{"source":"xterm/css/xterm.css"}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"TerminalComponent","symbolKind":"function","exported":true,"metadata":{"line":37,"column":59,"cyclomaticComplexity":92,"maxNestingDepth":8,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:localStorage.getItem",{"id":"external:localStorage.getItem","kind":"external","language":"jsts","metadata":{"unresolvedName":"localStorage.getItem"}}],["external:Math.min",{"id":"external:Math.min","kind":"external","language":"jsts","metadata":{"unresolvedName":"Math.min"}}],["external:apiUrl.replace(/^https?:\\/\\//, \"\").replace",{"id":"external:apiUrl.replace(/^https?:\\/\\//, \"\").replace","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiUrl.replace(/^https?:\\/\\//, \"\").replace"}}],["external:apiUrl.replace",{"id":"external:apiUrl.replace","kind":"external","language":"jsts","metadata":{"unresolvedName":"apiUrl.replace"}}],["external:ws.send",{"id":"external:ws.send","kind":"external","language":"jsts","metadata":{"unresolvedName":"ws.send"}}],["external:window.clearInterval",{"id":"external:window.clearInterval","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.clearInterval"}}],["external:window.setInterval",{"id":"external:window.setInterval","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.setInterval"}}],["external:ws.close",{"id":"external:ws.close","kind":"external","language":"jsts","metadata":{"unresolvedName":"ws.close"}}],["external:event.data.arrayBuffer().then",{"id":"external:event.data.arrayBuffer().then","kind":"external","language":"jsts","metadata":{"unresolvedName":"event.data.arrayBuffer().then"}}],["external:event.data.arrayBuffer",{"id":"external:event.data.arrayBuffer","kind":"external","language":"jsts","metadata":{"unresolvedName":"event.data.arrayBuffer"}}],["external:termRef.current?.write",{"id":"external:termRef.current?.write","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current?.write"}}],["external:JSON.parse",{"id":"external:JSON.parse","kind":"external","language":"jsts","metadata":{"unresolvedName":"JSON.parse"}}],["external:termRef.current.clear",{"id":"external:termRef.current.clear","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current.clear"}}],["external:fitAddonRef.current.fit",{"id":"external:fitAddonRef.current.fit","kind":"external","language":"jsts","metadata":{"unresolvedName":"fitAddonRef.current.fit"}}],["external:currentWs.send",{"id":"external:currentWs.send","kind":"external","language":"jsts","metadata":{"unresolvedName":"currentWs.send"}}],["external:Math.pow",{"id":"external:Math.pow","kind":"external","language":"jsts","metadata":{"unresolvedName":"Math.pow"}}],["symbol-name:connectWebSocket",{"id":"symbol-name:connectWebSocket","kind":"symbol","language":"jsts","symbolName":"connectWebSocket","metadata":{"unresolvedName":"connectWebSocket"}}],["symbol-name:calculateFontSize",{"id":"symbol-name:calculateFontSize","kind":"symbol","language":"jsts","symbolName":"calculateFontSize","metadata":{"unresolvedName":"calculateFontSize"}}],["external:term.loadAddon",{"id":"external:term.loadAddon","kind":"external","language":"jsts","metadata":{"unresolvedName":"term.loadAddon"}}],["external:termRef.current.refresh",{"id":"external:termRef.current.refresh","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current.refresh"}}],["external:term.open",{"id":"external:term.open","kind":"external","language":"jsts","metadata":{"unresolvedName":"term.open"}}],["symbol-name:fitTerminal",{"id":"symbol-name:fitTerminal","kind":"symbol","language":"jsts","symbolName":"fitTerminal","metadata":{"unresolvedName":"fitTerminal"}}],["external:document.fonts.ready.then",{"id":"external:document.fonts.ready.then","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.fonts.ready.then"}}],["external:term.onData",{"id":"external:term.onData","kind":"external","language":"jsts","metadata":{"unresolvedName":"term.onData"}}],["symbol-name:applyModifierToChar",{"id":"symbol-name:applyModifierToChar","kind":"symbol","language":"jsts","symbolName":"applyModifierToChar","metadata":{"unresolvedName":"applyModifierToChar"}}],["external:resizeObserver.observe",{"id":"external:resizeObserver.observe","kind":"external","language":"jsts","metadata":{"unresolvedName":"resizeObserver.observe"}}],["external:termRef.current?.focus",{"id":"external:termRef.current?.focus","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current?.focus"}}],["external:handleFontSizeChangeRef.current",{"id":"external:handleFontSizeChangeRef.current","kind":"external","language":"jsts","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}}],["external:onTerminalReadyRef.current",{"id":"external:onTerminalReadyRef.current","kind":"external","language":"jsts","metadata":{"unresolvedName":"onTerminalReadyRef.current"}}],["external:resizeObserver.disconnect",{"id":"external:resizeObserver.disconnect","kind":"external","language":"jsts","metadata":{"unresolvedName":"resizeObserver.disconnect"}}],["external:term.dispose",{"id":"external:term.dispose","kind":"external","language":"jsts","metadata":{"unresolvedName":"term.dispose"}}],["external:wsRef.current.send",{"id":"external:wsRef.current.send","kind":"external","language":"jsts","metadata":{"unresolvedName":"wsRef.current.send"}}],["symbol-name:onTerminalReady",{"id":"symbol-name:onTerminalReady","kind":"symbol","language":"jsts","symbolName":"onTerminalReady","metadata":{"unresolvedName":"onTerminalReady"}}],["symbol-name:setFontSize",{"id":"symbol-name:setFontSize","kind":"symbol","language":"jsts","symbolName":"setFontSize","metadata":{"unresolvedName":"setFontSize"}}],["external:localStorage.setItem",{"id":"external:localStorage.setItem","kind":"external","language":"jsts","metadata":{"unresolvedName":"localStorage.setItem"}}],["external:newSize.toString",{"id":"external:newSize.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"newSize.toString"}}],["external:termRef.current.getSelection",{"id":"external:termRef.current.getSelection","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current.getSelection"}}],["external:document.createElement",{"id":"external:document.createElement","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.createElement"}}],["external:document.body.appendChild",{"id":"external:document.body.appendChild","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.body.appendChild"}}],["external:textarea.select",{"id":"external:textarea.select","kind":"external","language":"jsts","metadata":{"unresolvedName":"textarea.select"}}],["external:document.execCommand",{"id":"external:document.execCommand","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.execCommand"}}],["external:document.body.removeChild",{"id":"external:document.body.removeChild","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.body.removeChild"}}],["external:navigator.clipboard.readText",{"id":"external:navigator.clipboard.readText","kind":"external","language":"jsts","metadata":{"unresolvedName":"navigator.clipboard.readText"}}],["external:termRef.current.focus",{"id":"external:termRef.current.focus","kind":"external","language":"jsts","metadata":{"unresolvedName":"termRef.current.focus"}}],["symbol-name:handleFontSizeChange",{"id":"symbol-name:handleFontSizeChange","kind":"symbol","language":"jsts","symbolName":"handleFontSizeChange","metadata":{"unresolvedName":"handleFontSizeChange"}}],["symbol-name:setShowResetConfirm",{"id":"symbol-name:setShowResetConfirm","kind":"symbol","language":"jsts","symbolName":"setShowResetConfirm","metadata":{"unresolvedName":"setShowResetConfirm"}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":614,"column":17,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"fitTerminal","symbolKind":"function","exported":false,"metadata":{"line":264,"column":23,"cyclomaticComplexity":10,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"doInitialFit","symbolKind":"function","exported":false,"metadata":{"line":293,"column":24,"cyclomaticComplexity":5,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handleWindowResize","symbolKind":"function","exported":false,"metadata":{"line":356,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"sendData","symbolKind":"function","exported":false,"metadata":{"line":424,"column":21,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"focusInput","symbolKind":"function","exported":false,"metadata":{"line":429,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"changeFontSize","symbolKind":"function","exported":false,"metadata":{"line":432,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleVisibilityChange",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleVisibilityChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handleVisibilityChange","symbolKind":"function","exported":false,"metadata":{"line":387,"column":34,"cyclomaticComplexity":5,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handleFontSizeChange","symbolKind":"function","exported":false,"metadata":{"line":439,"column":31,"cyclomaticComplexity":7,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handleCopy","symbolKind":"function","exported":false,"metadata":{"line":471,"column":21,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handlePaste","symbolKind":"function","exported":false,"metadata":{"line":489,"column":22,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleTerminalClick",{"id":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleTerminalClick","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","symbolName":"handleTerminalClick","symbolKind":"function","exported":false,"metadata":{"line":501,"column":30,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet",{"id":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","symbolName":"ToolsBottomSheet","symbolKind":"function","exported":true,"metadata":{"line":14,"column":66,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:TOOLS_ITEMS.map",{"id":"external:TOOLS_ITEMS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"TOOLS_ITEMS.map"}}],["symbol-name:handleSelect",{"id":"symbol-name:handleSelect","kind":"symbol","language":"jsts","symbolName":"handleSelect","metadata":{"unresolvedName":"handleSelect"}}],["/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect",{"id":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","symbolName":"handleSelect","symbolKind":"function","exported":false,"metadata":{"line":23,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","metadata":{"lineCount":49,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx:WorkspaceHeader",{"id":"/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx:WorkspaceHeader","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","symbolName":"WorkspaceHeader","symbolKind":"function","exported":true,"metadata":{"line":16,"column":32,"cyclomaticComplexity":3,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","metadata":{"lineCount":43,"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","symbolName":"useAsyncData","symbolKind":"function","exported":true,"metadata":{"line":12,"column":1,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["symbol-name:fetcher",{"id":"symbol-name:fetcher","kind":"symbol","language":"jsts","symbolName":"fetcher","metadata":{"unresolvedName":"fetcher"}}],["symbol-name:setData",{"id":"symbol-name:setData","kind":"symbol","language":"jsts","symbolName":"setData","metadata":{"unresolvedName":"setData"}}],["symbol-name:load",{"id":"symbol-name:load","kind":"symbol","language":"jsts","symbolName":"load","metadata":{"unresolvedName":"load"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":37,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","symbolName":"useAutoHide","symbolKind":"function","exported":true,"metadata":{"line":8,"column":1,"cyclomaticComplexity":9,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setIsVisible",{"id":"symbol-name:setIsVisible","kind":"symbol","language":"jsts","symbolName":"setIsVisible","metadata":{"unresolvedName":"setIsVisible"}}],["symbol-name:hide",{"id":"symbol-name:hide","kind":"symbol","language":"jsts","symbolName":"hide","metadata":{"unresolvedName":"hide"}}],["symbol-name:show",{"id":"symbol-name:show","kind":"symbol","language":"jsts","symbolName":"show","metadata":{"unresolvedName":"show"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":55,"column":12,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","metadata":{"lineCount":159,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","symbolName":"useInstanceActions","symbolKind":"function","exported":true,"metadata":{"line":27,"column":1,"cyclomaticComplexity":15,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:window.open",{"id":"external:window.open","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.open"}}],["symbol-name:setLoadingSessionId",{"id":"symbol-name:setLoadingSessionId","kind":"symbol","language":"jsts","symbolName":"setLoadingSessionId","metadata":{"unresolvedName":"setLoadingSessionId"}}],["symbol-name:setDirtyDeleteSession",{"id":"symbol-name:setDirtyDeleteSession","kind":"symbol","language":"jsts","symbolName":"setDirtyDeleteSession","metadata":{"unresolvedName":"setDirtyDeleteSession"}}],["symbol-name:setDirtyDeleteFiles",{"id":"symbol-name:setDirtyDeleteFiles","kind":"symbol","language":"jsts","symbolName":"setDirtyDeleteFiles","metadata":{"unresolvedName":"setDirtyDeleteFiles"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":141,"column":40,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","symbolName":"useMobileViewport","symbolKind":"function","exported":true,"metadata":{"line":5,"column":1,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setIsMobile",{"id":"symbol-name:setIsMobile","kind":"symbol","language":"jsts","symbolName":"setIsMobile","metadata":{"unresolvedName":"setIsMobile"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":11,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:handleResize",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:handleResize","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","symbolName":"handleResize","symbolKind":"function","exported":false,"metadata":{"line":12,"column":26,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","symbolName":"getSequenceWithModifier","symbolKind":"function","exported":true,"metadata":{"line":106,"column":1,"cyclomaticComplexity":7,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:char.toLowerCase",{"id":"external:char.toLowerCase","kind":"external","language":"jsts","metadata":{"unresolvedName":"char.toLowerCase"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","symbolName":"applyModifierToChar","symbolKind":"function","exported":true,"metadata":{"line":130,"column":1,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","symbolName":"useTheme","symbolKind":"function","exported":true,"metadata":{"line":5,"column":1,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:getUserConfig",{"id":"symbol-name:getUserConfig","kind":"symbol","language":"jsts","symbolName":"getUserConfig","metadata":{"unresolvedName":"getUserConfig"}}],["external:document.documentElement.removeAttribute",{"id":"external:document.documentElement.removeAttribute","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}}],["external:document.documentElement.setAttribute",{"id":"external:document.documentElement.setAttribute","kind":"external","language":"jsts","metadata":{"unresolvedName":"document.documentElement.setAttribute"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":7,"column":11,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","symbolName":"useVirtualKeyboard","symbolKind":"function","exported":true,"metadata":{"line":9,"column":1,"cyclomaticComplexity":7,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setState",{"id":"symbol-name:setState","kind":"symbol","language":"jsts","symbolName":"setState","metadata":{"unresolvedName":"setState"}}],["external:visualViewport.addEventListener",{"id":"external:visualViewport.addEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"visualViewport.addEventListener"}}],["symbol-name:updateKeyboardState",{"id":"symbol-name:updateKeyboardState","kind":"symbol","language":"jsts","symbolName":"updateKeyboardState","metadata":{"unresolvedName":"updateKeyboardState"}}],["external:visualViewport.removeEventListener",{"id":"external:visualViewport.removeEventListener","kind":"external","language":"jsts","metadata":{"unresolvedName":"visualViewport.removeEventListener"}}],["/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:",{"id":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":57,"column":12,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/main.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/main.tsx","metadata":{"lineCount":21,"featureKind":"library","trustBoundaries":[]}}],["external:react-dom/client",{"id":"external:react-dom/client","kind":"external","language":"jsts","metadata":{"source":"react-dom/client"}}],["file:/home/alex/projects/headquarter/apps/web/src/router.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/router.tsx","metadata":{"lineCount":56,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/styles.css",{"id":"file:/home/alex/projects/headquarter/apps/web/src/styles.css","kind":"file","language":"css","filePath":"/home/alex/projects/headquarter/apps/web/src/styles.css"}],["file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","metadata":{"lineCount":1294,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"ConfigProfilesPage","symbolKind":"function","exported":true,"metadata":{"line":29,"column":35,"cyclomaticComplexity":132,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["external:Promise.all",{"id":"external:Promise.all","kind":"external","language":"jsts","metadata":{"unresolvedName":"Promise.all"}}],["symbol-name:listProjects",{"id":"symbol-name:listProjects","kind":"symbol","language":"jsts","symbolName":"listProjects","metadata":{"unresolvedName":"listProjects"}}],["symbol-name:setProfiles",{"id":"symbol-name:setProfiles","kind":"symbol","language":"jsts","symbolName":"setProfiles","metadata":{"unresolvedName":"setProfiles"}}],["symbol-name:setProjects",{"id":"symbol-name:setProjects","kind":"symbol","language":"jsts","symbolName":"setProjects","metadata":{"unresolvedName":"setProjects"}}],["symbol-name:setToolTypes",{"id":"symbol-name:setToolTypes","kind":"symbol","language":"jsts","symbolName":"setToolTypes","metadata":{"unresolvedName":"setToolTypes"}}],["symbol-name:loadData",{"id":"symbol-name:loadData","kind":"symbol","language":"jsts","symbolName":"loadData","metadata":{"unresolvedName":"loadData"}}],["symbol-name:setIncludedProfileIds",{"id":"symbol-name:setIncludedProfileIds","kind":"symbol","language":"jsts","symbolName":"setIncludedProfileIds","metadata":{"unresolvedName":"setIncludedProfileIds"}}],["symbol-name:setSaveStatus",{"id":"symbol-name:setSaveStatus","kind":"symbol","language":"jsts","symbolName":"setSaveStatus","metadata":{"unresolvedName":"setSaveStatus"}}],["symbol-name:setPreviewData",{"id":"symbol-name:setPreviewData","kind":"symbol","language":"jsts","symbolName":"setPreviewData","metadata":{"unresolvedName":"setPreviewData"}}],["external:profile.includes.map",{"id":"external:profile.includes.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"profile.includes.map"}}],["symbol-name:setSelectedProfileId",{"id":"symbol-name:setSelectedProfileId","kind":"symbol","language":"jsts","symbolName":"setSelectedProfileId","metadata":{"unresolvedName":"setSelectedProfileId"}}],["symbol-name:setIsCreating",{"id":"symbol-name:setIsCreating","kind":"symbol","language":"jsts","symbolName":"setIsCreating","metadata":{"unresolvedName":"setIsCreating"}}],["symbol-name:populateForm",{"id":"symbol-name:populateForm","kind":"symbol","language":"jsts","symbolName":"populateForm","metadata":{"unresolvedName":"populateForm"}}],["external:visited.has",{"id":"external:visited.has","kind":"external","language":"jsts","metadata":{"unresolvedName":"visited.has"}}],["symbol-name:getIncludedProfile",{"id":"symbol-name:getIncludedProfile","kind":"symbol","language":"jsts","symbolName":"getIncludedProfile","metadata":{"unresolvedName":"getIncludedProfile"}}],["external:nextVisited.add",{"id":"external:nextVisited.add","kind":"external","language":"jsts","metadata":{"unresolvedName":"nextVisited.add"}}],["symbol-name:wouldCreateCycle",{"id":"symbol-name:wouldCreateCycle","kind":"symbol","language":"jsts","symbolName":"wouldCreateCycle","metadata":{"unresolvedName":"wouldCreateCycle"}}],["external:profiles.filter",{"id":"external:profiles.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"profiles.filter"}}],["external:includedProfileIds.includes",{"id":"external:includedProfileIds.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"includedProfileIds.includes"}}],["external:e.dataTransfer.setData",{"id":"external:e.dataTransfer.setData","kind":"external","language":"jsts","metadata":{"unresolvedName":"e.dataTransfer.setData"}}],["symbol-name:setDragOverIndex",{"id":"symbol-name:setDragOverIndex","kind":"symbol","language":"jsts","symbolName":"setDragOverIndex","metadata":{"unresolvedName":"setDragOverIndex"}}],["external:e.dataTransfer.getData",{"id":"external:e.dataTransfer.getData","kind":"external","language":"jsts","metadata":{"unresolvedName":"e.dataTransfer.getData"}}],["external:newOrder.splice",{"id":"external:newOrder.splice","kind":"external","language":"jsts","metadata":{"unresolvedName":"newOrder.splice"}}],["external:formData.name?.trim",{"id":"external:formData.name?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"formData.name?.trim"}}],["symbol-name:createConfigProfile",{"id":"symbol-name:createConfigProfile","kind":"symbol","language":"jsts","symbolName":"createConfigProfile","metadata":{"unresolvedName":"createConfigProfile"}}],["symbol-name:updateProfileIncludes",{"id":"symbol-name:updateProfileIncludes","kind":"symbol","language":"jsts","symbolName":"updateProfileIncludes","metadata":{"unresolvedName":"updateProfileIncludes"}}],["external:(await listConfigProfiles()).find",{"id":"external:(await listConfigProfiles()).find","kind":"external","language":"jsts","metadata":{"unresolvedName":"(await listConfigProfiles()).find"}}],["symbol-name:updateConfigProfile",{"id":"symbol-name:updateConfigProfile","kind":"symbol","language":"jsts","symbolName":"updateConfigProfile","metadata":{"unresolvedName":"updateConfigProfile"}}],["symbol-name:deleteConfigProfile",{"id":"symbol-name:deleteConfigProfile","kind":"symbol","language":"jsts","symbolName":"deleteConfigProfile","metadata":{"unresolvedName":"deleteConfigProfile"}}],["symbol-name:alert",{"id":"symbol-name:alert","kind":"symbol","language":"jsts","symbolName":"alert","metadata":{"unresolvedName":"alert"}}],["symbol-name:setPreviewingId",{"id":"symbol-name:setPreviewingId","kind":"symbol","language":"jsts","symbolName":"setPreviewingId","metadata":{"unresolvedName":"setPreviewingId"}}],["symbol-name:previewConfigProfile",{"id":"symbol-name:previewConfigProfile","kind":"symbol","language":"jsts","symbolName":"previewConfigProfile","metadata":{"unresolvedName":"previewConfigProfile"}}],["external:mounts.splice",{"id":"external:mounts.splice","kind":"external","language":"jsts","metadata":{"unresolvedName":"mounts.splice"}}],["external:profiles.map",{"id":"external:profiles.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"profiles.map"}}],["symbol-name:getScopeLabel",{"id":"symbol-name:getScopeLabel","kind":"symbol","language":"jsts","symbolName":"getScopeLabel","metadata":{"unresolvedName":"getScopeLabel"}}],["symbol-name:setMobileView",{"id":"symbol-name:setMobileView","kind":"symbol","language":"jsts","symbolName":"setMobileView","metadata":{"unresolvedName":"setMobileView"}}],["external:Object.entries(selectedProfile.env_vars).map(([k, v]) => `${k}=${v}`).join",{"id":"external:Object.entries(selectedProfile.env_vars).map(([k, v]) => `${k}=${v}`).join","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(selectedProfile.env_vars).map(([k, v]) => `${k}=${v}`).join"}}],["external:Object.entries(selectedProfile.env_vars).map",{"id":"external:Object.entries(selectedProfile.env_vars).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(selectedProfile.env_vars).map"}}],["external:selectedProfile.mounts.map((m) => `${m.target} (${m.mode})`).join",{"id":"external:selectedProfile.mounts.map((m) => `${m.target} (${m.mode})`).join","kind":"external","language":"jsts","metadata":{"unresolvedName":"selectedProfile.mounts.map((m) => `${m.target} (${m.mode})`).join"}}],["external:selectedProfile.mounts.map",{"id":"external:selectedProfile.mounts.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"selectedProfile.mounts.map"}}],["symbol-name:handleSubmit",{"id":"symbol-name:handleSubmit","kind":"symbol","language":"jsts","symbolName":"handleSubmit","metadata":{"unresolvedName":"handleSubmit"}}],["symbol-name:updateFormField",{"id":"symbol-name:updateFormField","kind":"symbol","language":"jsts","symbolName":"updateFormField","metadata":{"unresolvedName":"updateFormField"}}],["external:Object.entries(formData.env_vars || {}).map",{"id":"external:Object.entries(formData.env_vars || {}).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(formData.env_vars || {}).map"}}],["external:(formData.mounts || []).map",{"id":"external:(formData.mounts || []).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"(formData.mounts || []).map"}}],["external:(formData.mounts || []).filter",{"id":"external:(formData.mounts || []).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"(formData.mounts || []).filter"}}],["symbol-name:handleSelectProfile",{"id":"symbol-name:handleSelectProfile","kind":"symbol","language":"jsts","symbolName":"handleSelectProfile","metadata":{"unresolvedName":"handleSelectProfile"}}],["symbol-name:handlePreview",{"id":"symbol-name:handlePreview","kind":"symbol","language":"jsts","symbolName":"handlePreview","metadata":{"unresolvedName":"handlePreview"}}],["external:includedProfileIds.map",{"id":"external:includedProfileIds.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"includedProfileIds.map"}}],["symbol-name:handleDragStart",{"id":"symbol-name:handleDragStart","kind":"symbol","language":"jsts","symbolName":"handleDragStart","metadata":{"unresolvedName":"handleDragStart"}}],["symbol-name:handleDragOver",{"id":"symbol-name:handleDragOver","kind":"symbol","language":"jsts","symbolName":"handleDragOver","metadata":{"unresolvedName":"handleDragOver"}}],["symbol-name:handleDrop",{"id":"symbol-name:handleDrop","kind":"symbol","language":"jsts","symbolName":"handleDrop","metadata":{"unresolvedName":"handleDrop"}}],["symbol-name:removeInclude",{"id":"symbol-name:removeInclude","kind":"symbol","language":"jsts","symbolName":"removeInclude","metadata":{"unresolvedName":"removeInclude"}}],["symbol-name:availableProfilesForInclude",{"id":"symbol-name:availableProfilesForInclude","kind":"symbol","language":"jsts","symbolName":"availableProfilesForInclude","metadata":{"unresolvedName":"availableProfilesForInclude"}}],["symbol-name:addInclude",{"id":"symbol-name:addInclude","kind":"symbol","language":"jsts","symbolName":"addInclude","metadata":{"unresolvedName":"addInclude"}}],["external:availableProfilesForInclude().map",{"id":"external:availableProfilesForInclude().map","kind":"external","language":"jsts","metadata":{"unresolvedName":"availableProfilesForInclude().map"}}],["external:Object.entries(formData.files || {}).map",{"id":"external:Object.entries(formData.files || {}).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(formData.files || {}).map"}}],["symbol-name:updateFile",{"id":"symbol-name:updateFile","kind":"symbol","language":"jsts","symbolName":"updateFile","metadata":{"unresolvedName":"updateFile"}}],["symbol-name:removeFile",{"id":"symbol-name:removeFile","kind":"symbol","language":"jsts","symbolName":"removeFile","metadata":{"unresolvedName":"removeFile"}}],["external:Object.entries(mount.files).map",{"id":"external:Object.entries(mount.files).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"Object.entries(mount.files).map"}}],["symbol-name:updateMountFile",{"id":"symbol-name:updateMountFile","kind":"symbol","language":"jsts","symbolName":"updateMountFile","metadata":{"unresolvedName":"updateMountFile"}}],["symbol-name:removeMountFile",{"id":"symbol-name:removeMountFile","kind":"symbol","language":"jsts","symbolName":"removeMountFile","metadata":{"unresolvedName":"removeMountFile"}}],["symbol-name:addMountFile",{"id":"symbol-name:addMountFile","kind":"symbol","language":"jsts","symbolName":"addMountFile","metadata":{"unresolvedName":"addMountFile"}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":1262,"column":30,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"resetForm","symbolKind":"function","exported":false,"metadata":{"line":83,"column":21,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"populateForm","symbolKind":"function","exported":false,"metadata":{"line":100,"column":24,"cyclomaticComplexity":5,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleSelectProfile","symbolKind":"function","exported":false,"metadata":{"line":121,"column":31,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleCreateNew","symbolKind":"function","exported":false,"metadata":{"line":131,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"getScopeLabel","symbolKind":"function","exported":false,"metadata":{"line":140,"column":25,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"wouldCreateCycle","symbolKind":"function","exported":false,"metadata":{"line":148,"column":28,"cyclomaticComplexity":6,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"availableProfilesForInclude","symbolKind":"function","exported":false,"metadata":{"line":162,"column":39,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"addInclude","symbolKind":"function","exported":false,"metadata":{"line":173,"column":22,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"removeInclude","symbolKind":"function","exported":false,"metadata":{"line":177,"column":25,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleDragStart","symbolKind":"function","exported":false,"metadata":{"line":182,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleDragOver","symbolKind":"function","exported":false,"metadata":{"line":187,"column":26,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragLeave",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragLeave","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleDragLeave","symbolKind":"function","exported":false,"metadata":{"line":193,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleDrop","symbolKind":"function","exported":false,"metadata":{"line":197,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":213,"column":24,"cyclomaticComplexity":8,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":252,"column":24,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"handlePreview","symbolKind":"function","exported":false,"metadata":{"line":268,"column":25,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"updateFormField","symbolKind":"function","exported":false,"metadata":{"line":280,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"addEnvVar","symbolKind":"function","exported":false,"metadata":{"line":288,"column":21,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"updateEnvVar","symbolKind":"function","exported":false,"metadata":{"line":296,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"removeEnvVar","symbolKind":"function","exported":false,"metadata":{"line":308,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"addFile","symbolKind":"function","exported":false,"metadata":{"line":317,"column":19,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"updateFile","symbolKind":"function","exported":false,"metadata":{"line":325,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"removeFile","symbolKind":"function","exported":false,"metadata":{"line":337,"column":22,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"addMount","symbolKind":"function","exported":false,"metadata":{"line":346,"column":20,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"updateMount","symbolKind":"function","exported":false,"metadata":{"line":354,"column":23,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"removeMount","symbolKind":"function","exported":false,"metadata":{"line":363,"column":23,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"addMountFile","symbolKind":"function","exported":false,"metadata":{"line":372,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"updateMountFile","symbolKind":"function","exported":false,"metadata":{"line":384,"column":27,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"removeMountFile","symbolKind":"function","exported":false,"metadata":{"line":403,"column":27,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:preventDefault",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:preventDefault","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","symbolName":"preventDefault","symbolKind":"function","exported":false,"metadata":{"line":504,"column":56,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","metadata":{"lineCount":82,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","metadata":{"lineCount":267,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":75,"column":19,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:beforeEach",{"id":"symbol-name:beforeEach","kind":"symbol","language":"jsts","symbolName":"beforeEach","metadata":{"unresolvedName":"beforeEach"}}],["external:mockDashboard.mockReset",{"id":"external:mockDashboard.mockReset","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockDashboard.mockReset"}}],["external:mockSessions.mockReset",{"id":"external:mockSessions.mockReset","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockSessions.mockReset"}}],["external:mockProjects.mockReset",{"id":"external:mockProjects.mockReset","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockProjects.mockReset"}}],["external:mockRepos.mockReset",{"id":"external:mockRepos.mockReset","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockRepos.mockReset"}}],["external:mockDashboard.mockResolvedValue",{"id":"external:mockDashboard.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockDashboard.mockResolvedValue"}}],["external:mockSessions.mockResolvedValue",{"id":"external:mockSessions.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockSessions.mockResolvedValue"}}],["external:mockProjects.mockResolvedValue",{"id":"external:mockProjects.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockProjects.mockResolvedValue"}}],["external:mockRepos.mockResolvedValue",{"id":"external:mockRepos.mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockRepos.mockResolvedValue"}}],["external:expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument"}}],["external:expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan",{"id":"external:expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan"}}],["external:screen.getAllByText",{"id":"external:screen.getAllByText","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getAllByText"}}],["external:expect(screen.getByText(\"Available projects\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Available projects\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Available projects\")).toBeInTheDocument"}}],["external:mockDashboard.mockRejectedValueOnce",{"id":"external:mockDashboard.mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockDashboard.mockRejectedValueOnce"}}],["external:mockSessions.mockRejectedValueOnce",{"id":"external:mockSessions.mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockSessions.mockRejectedValueOnce"}}],["external:mockProjects.mockRejectedValueOnce",{"id":"external:mockProjects.mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"mockProjects.mockRejectedValueOnce"}}],["external:screen.getAllByRole",{"id":"external:screen.getAllByRole","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getAllByRole"}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","symbolName":"HomePage","symbolKind":"function","exported":true,"metadata":{"line":26,"column":25,"cyclomaticComplexity":17,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:Array.isArray",{"id":"external:Array.isArray","kind":"external","language":"jsts","metadata":{"unresolvedName":"Array.isArray"}}],["symbol-name:getDashboardSummary",{"id":"symbol-name:getDashboardSummary","kind":"symbol","language":"jsts","symbolName":"getDashboardSummary","metadata":{"unresolvedName":"getDashboardSummary"}}],["symbol-name:setSummary",{"id":"symbol-name:setSummary","kind":"symbol","language":"jsts","symbolName":"setSummary","metadata":{"unresolvedName":"setSummary"}}],["symbol-name:setSessions",{"id":"symbol-name:setSessions","kind":"symbol","language":"jsts","symbolName":"setSessions","metadata":{"unresolvedName":"setSessions"}}],["symbol-name:loadHome",{"id":"symbol-name:loadHome","kind":"symbol","language":"jsts","symbolName":"loadHome","metadata":{"unresolvedName":"loadHome"}}],["symbol-name:useInstanceActions",{"id":"symbol-name:useInstanceActions","kind":"symbol","language":"jsts","symbolName":"useInstanceActions","metadata":{"unresolvedName":"useInstanceActions"}}],["external:safeSessions.filter",{"id":"external:safeSessions.filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"safeSessions.filter"}}],["symbol-name:setTunnelHealth",{"id":"symbol-name:setTunnelHealth","kind":"symbol","language":"jsts","symbolName":"setTunnelHealth","metadata":{"unresolvedName":"setTunnelHealth"}}],["symbol-name:loadRepos",{"id":"symbol-name:loadRepos","kind":"symbol","language":"jsts","symbolName":"loadRepos","metadata":{"unresolvedName":"loadRepos"}}],["symbol-name:useMemo",{"id":"symbol-name:useMemo","kind":"symbol","language":"jsts","symbolName":"useMemo","metadata":{"unresolvedName":"useMemo"}}],["external:[\"running\", \"building\", \"pending\"].includes",{"id":"external:[\"running\", \"building\", \"pending\"].includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"[\"running\", \"building\", \"pending\"].includes"}}],["symbol-name:updateUserConfig",{"id":"symbol-name:updateUserConfig","kind":"symbol","language":"jsts","symbolName":"updateUserConfig","metadata":{"unresolvedName":"updateUserConfig"}}],["external:summaryCards.map",{"id":"external:summaryCards.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"summaryCards.map"}}],["external:[\"running\", \"building\", \"pending\", \"starting\", \"probing\", \"unhealthy\"].includes",{"id":"external:[\"running\", \"building\", \"pending\", \"starting\", \"probing\", \"unhealthy\"].includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"[\"running\", \"building\", \"pending\", \"starting\", \"probing\", \"unhealthy\"].includes"}}],["external:[\"stopped\", \"error\"].includes",{"id":"external:[\"stopped\", \"error\"].includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"[\"stopped\", \"error\"].includes"}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":113,"column":13,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","symbolName":"checkHealth","symbolKind":"function","exported":false,"metadata":{"line":72,"column":25,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","symbolName":"loadRepos","symbolKind":"function","exported":false,"metadata":{"line":119,"column":23,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","symbolName":"handleCreateSuccess","symbolKind":"function","exported":false,"metadata":{"line":136,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","metadata":{"lineCount":227,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","symbolName":"GitHistoryPage","symbolKind":"function","exported":true,"metadata":{"line":9,"column":31,"cyclomaticComplexity":26,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useAsyncData",{"id":"symbol-name:useAsyncData","kind":"symbol","language":"jsts","symbolName":"useAsyncData","metadata":{"unresolvedName":"useAsyncData"}}],["symbol-name:getRepositoryHistory",{"id":"symbol-name:getRepositoryHistory","kind":"symbol","language":"jsts","symbolName":"getRepositoryHistory","metadata":{"unresolvedName":"getRepositoryHistory"}}],["symbol-name:setSelectedBranch",{"id":"symbol-name:setSelectedBranch","kind":"symbol","language":"jsts","symbolName":"setSelectedBranch","metadata":{"unresolvedName":"setSelectedBranch"}}],["symbol-name:setSelectedCommit",{"id":"symbol-name:setSelectedCommit","kind":"symbol","language":"jsts","symbolName":"setSelectedCommit","metadata":{"unresolvedName":"setSelectedCommit"}}],["symbol-name:setDetailStatus",{"id":"symbol-name:setDetailStatus","kind":"symbol","language":"jsts","symbolName":"setDetailStatus","metadata":{"unresolvedName":"setDetailStatus"}}],["symbol-name:getCommitDetail",{"id":"symbol-name:getCommitDetail","kind":"symbol","language":"jsts","symbolName":"getCommitDetail","metadata":{"unresolvedName":"getCommitDetail"}}],["symbol-name:setCommitDetail",{"id":"symbol-name:setCommitDetail","kind":"symbol","language":"jsts","symbolName":"setCommitDetail","metadata":{"unresolvedName":"setCommitDetail"}}],["external:new Date(dateStr).toLocaleString",{"id":"external:new Date(dateStr).toLocaleString","kind":"external","language":"jsts","metadata":{"unresolvedName":"new Date(dateStr).toLocaleString"}}],["external:commits.map",{"id":"external:commits.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"commits.map"}}],["symbol-name:handleCommitClick",{"id":"symbol-name:handleCommitClick","kind":"symbol","language":"jsts","symbolName":"handleCommitClick","metadata":{"unresolvedName":"handleCommitClick"}}],["external:commit.refs.map",{"id":"external:commit.refs.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"commit.refs.map"}}],["external:commit.message.split",{"id":"external:commit.message.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"commit.message.split"}}],["symbol-name:formatDate",{"id":"symbol-name:formatDate","kind":"symbol","language":"jsts","symbolName":"formatDate","metadata":{"unresolvedName":"formatDate"}}],["external:commitDetail.parents.map",{"id":"external:commitDetail.parents.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"commitDetail.parents.map"}}],["external:parent.substring",{"id":"external:parent.substring","kind":"external","language":"jsts","metadata":{"unresolvedName":"parent.substring"}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":114,"column":26,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","symbolName":"handleCommitClick","symbolKind":"function","exported":false,"metadata":{"line":32,"column":29,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","symbolName":"handleCloseDetail","symbolKind":"function","exported":false,"metadata":{"line":45,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","symbolName":"formatDate","symbolKind":"function","exported":false,"metadata":{"line":51,"column":22,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","metadata":{"lineCount":122,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","symbolName":"GitRepositoriesPage","symbolKind":"function","exported":true,"metadata":{"line":14,"column":36,"cyclomaticComplexity":15,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["symbol-name:setDeleteConfirmId",{"id":"symbol-name:setDeleteConfirmId","kind":"symbol","language":"jsts","symbolName":"setDeleteConfirmId","metadata":{"unresolvedName":"setDeleteConfirmId"}}],["symbol-name:reload",{"id":"symbol-name:reload","kind":"symbol","language":"jsts","symbolName":"reload","metadata":{"unresolvedName":"reload"}}],["external:safeRepositories.map",{"id":"external:safeRepositories.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"safeRepositories.map"}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":21,"column":5,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":28,"column":24,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","metadata":{"lineCount":38,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:PlaceholderPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:PlaceholderPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","symbolName":"PlaceholderPage","symbolKind":"function","exported":true,"metadata":{"line":1,"column":32,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:NotFoundPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:NotFoundPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","symbolName":"NotFoundPage","symbolKind":"function","exported":true,"metadata":{"line":10,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","symbolName":"LoginRedirectPage","symbolKind":"function","exported":true,"metadata":{"line":23,"column":34,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["external:new URLSearchParams(window.location.search).get",{"id":"external:new URLSearchParams(window.location.search).get","kind":"external","language":"jsts","metadata":{"unresolvedName":"new URLSearchParams(window.location.search).get"}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","metadata":{"lineCount":185,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","symbolName":"ProfilePage","symbolKind":"function","exported":true,"metadata":{"line":12,"column":28,"cyclomaticComplexity":20,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setName",{"id":"symbol-name:setName","kind":"symbol","language":"jsts","symbolName":"setName","metadata":{"unresolvedName":"setName"}}],["symbol-name:setEmail",{"id":"symbol-name:setEmail","kind":"symbol","language":"jsts","symbolName":"setEmail","metadata":{"unresolvedName":"setEmail"}}],["symbol-name:setDisplayStatus",{"id":"symbol-name:setDisplayStatus","kind":"symbol","language":"jsts","symbolName":"setDisplayStatus","metadata":{"unresolvedName":"setDisplayStatus"}}],["external:name.trim",{"id":"external:name.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"name.trim"}}],["external:email.includes",{"id":"external:email.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"email.includes"}}],["symbol-name:updateProfile",{"id":"symbol-name:updateProfile","kind":"symbol","language":"jsts","symbolName":"updateProfile","metadata":{"unresolvedName":"updateProfile"}}],["external:email.trim",{"id":"external:email.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"email.trim"}}],["symbol-name:refreshSession",{"id":"symbol-name:refreshSession","kind":"symbol","language":"jsts","symbolName":"refreshSession","metadata":{"unresolvedName":"refreshSession"}}],["external:file.type.startsWith",{"id":"external:file.type.startsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"file.type.startsWith"}}],["symbol-name:uploadAvatar",{"id":"symbol-name:uploadAvatar","kind":"symbol","language":"jsts","symbolName":"uploadAvatar","metadata":{"unresolvedName":"uploadAvatar"}}],["external:profile.name.charAt(0).toUpperCase",{"id":"external:profile.name.charAt(0).toUpperCase","kind":"external","language":"jsts","metadata":{"unresolvedName":"profile.name.charAt(0).toUpperCase"}}],["external:profile.name.charAt",{"id":"external:profile.name.charAt","kind":"external","language":"jsts","metadata":{"unresolvedName":"profile.name.charAt"}}],["external:fileInputRef.current?.click",{"id":"external:fileInputRef.current?.click","kind":"external","language":"jsts","metadata":{"unresolvedName":"fileInputRef.current?.click"}}],["/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":60,"column":5,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","metadata":{"lineCount":149,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"GeneralSettings","symbolKind":"function","exported":false,"metadata":{"line":17,"column":6,"cyclomaticComplexity":7,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setDescription",{"id":"symbol-name:setDescription","kind":"symbol","language":"jsts","symbolName":"setDescription","metadata":{"unresolvedName":"setDescription"}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"handleSave","symbolKind":"function","exported":false,"metadata":{"line":24,"column":22,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":38,"column":24,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"ProjectSettingsPage","symbolKind":"function","exported":true,"metadata":{"line":100,"column":46,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setProject",{"id":"symbol-name:setProject","kind":"symbol","language":"jsts","symbolName":"setProject","metadata":{"unresolvedName":"setProject"}}],["symbol-name:fetchProject",{"id":"symbol-name:fetchProject","kind":"symbol","language":"jsts","symbolName":"fetchProject","metadata":{"unresolvedName":"fetchProject"}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":106,"column":13,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","symbolName":"fetchProject","symbolKind":"function","exported":false,"metadata":{"line":107,"column":26,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","metadata":{"lineCount":197,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","metadata":{"lineCount":217,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":191,"column":19,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:vi.spyOn(projectsApi, \"listProjects\").mockImplementation",{"id":"external:vi.spyOn(projectsApi, \"listProjects\").mockImplementation","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockImplementation"}}],["external:expect(screen.getByText(/loading projects/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/loading projects/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/loading projects/i)).toBeInTheDocument"}}],["external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue",{"id":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}}],["external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}}],["external:expect(screen.getByText(\"Beta Project\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Beta Project\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Beta Project\")).toBeInTheDocument"}}],["external:expect(screen.getByText(\"First project\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"First project\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"First project\")).toBeInTheDocument"}}],["external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}}],["external:vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue",{"id":"external:vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue"}}],["external:expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument"}}],["external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument",{"id":"external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument"}}],["external:vi.spyOn(projectsApi, \"createProject\").mockResolvedValue",{"id":"external:vi.spyOn(projectsApi, \"createProject\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"createProject\").mockResolvedValue"}}],["external:expect(screen.getByRole(\"dialog\")).toBeInTheDocument",{"id":"external:expect(screen.getByRole(\"dialog\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByRole(\"dialog\")).toBeInTheDocument"}}],["external:expect(screen.getByText(/project name is required/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/project name is required/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/project name is required/i)).toBeInTheDocument"}}],["external:vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue",{"id":"external:vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue"}}],["external:screen.getByText(\"Alpha Project\").closest",{"id":"external:screen.getByText(\"Alpha Project\").closest","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByText(\"Alpha Project\").closest"}}],["external:within(alphaCard).getByRole",{"id":"external:within(alphaCard).getByRole","kind":"external","language":"jsts","metadata":{"unresolvedName":"within(alphaCard).getByRole"}}],["symbol-name:within",{"id":"symbol-name:within","kind":"symbol","language":"jsts","symbolName":"within","metadata":{"unresolvedName":"within"}}],["external:screen.getByDisplayValue",{"id":"external:screen.getByDisplayValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByDisplayValue"}}],["external:expect(updateMock).toHaveBeenCalledWith",{"id":"external:expect(updateMock).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(updateMock).toHaveBeenCalledWith"}}],["external:vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue",{"id":"external:vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue"}}],["external:expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument",{"id":"external:expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument"}}],["external:within(alphaCard).getByText",{"id":"external:within(alphaCard).getByText","kind":"external","language":"jsts","metadata":{"unresolvedName":"within(alphaCard).getByText"}}],["external:expect(deleteMock).toHaveBeenCalledWith",{"id":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"ProjectsPage","symbolKind":"function","exported":true,"metadata":{"line":20,"column":29,"cyclomaticComplexity":23,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setFormDescription",{"id":"symbol-name:setFormDescription","kind":"symbol","language":"jsts","symbolName":"setFormDescription","metadata":{"unresolvedName":"setFormDescription"}}],["symbol-name:setEditingProject",{"id":"symbol-name:setEditingProject","kind":"symbol","language":"jsts","symbolName":"setEditingProject","metadata":{"unresolvedName":"setEditingProject"}}],["symbol-name:setDialogMode",{"id":"symbol-name:setDialogMode","kind":"symbol","language":"jsts","symbolName":"setDialogMode","metadata":{"unresolvedName":"setDialogMode"}}],["external:formDescription.trim",{"id":"external:formDescription.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"formDescription.trim"}}],["symbol-name:createProject",{"id":"symbol-name:createProject","kind":"symbol","language":"jsts","symbolName":"createProject","metadata":{"unresolvedName":"createProject"}}],["symbol-name:updateProject",{"id":"symbol-name:updateProject","kind":"symbol","language":"jsts","symbolName":"updateProject","metadata":{"unresolvedName":"updateProject"}}],["symbol-name:closeDialog",{"id":"symbol-name:closeDialog","kind":"symbol","language":"jsts","symbolName":"closeDialog","metadata":{"unresolvedName":"closeDialog"}}],["symbol-name:deleteProject",{"id":"symbol-name:deleteProject","kind":"symbol","language":"jsts","symbolName":"deleteProject","metadata":{"unresolvedName":"deleteProject"}}],["external:safeProjects.map",{"id":"external:safeProjects.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"safeProjects.map"}}],["symbol-name:openEdit",{"id":"symbol-name:openEdit","kind":"symbol","language":"jsts","symbolName":"openEdit","metadata":{"unresolvedName":"openEdit"}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"openCreate","symbolKind":"function","exported":false,"metadata":{"line":31,"column":22,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"openEdit","symbolKind":"function","exported":false,"metadata":{"line":39,"column":20,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"closeDialog","symbolKind":"function","exported":false,"metadata":{"line":47,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"handleSubmit","symbolKind":"function","exported":false,"metadata":{"line":53,"column":24,"cyclomaticComplexity":8,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":83,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","metadata":{"lineCount":506,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"RepoWorkspace","symbolKind":"function","exported":true,"metadata":{"line":47,"column":30,"cyclomaticComplexity":43,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["symbol-name:setSelectedRepoId",{"id":"symbol-name:setSelectedRepoId","kind":"symbol","language":"jsts","symbolName":"setSelectedRepoId","metadata":{"unresolvedName":"setSelectedRepoId"}}],["external:newParams.set",{"id":"external:newParams.set","kind":"external","language":"jsts","metadata":{"unresolvedName":"newParams.set"}}],["symbol-name:setSearchParams",{"id":"symbol-name:setSearchParams","kind":"symbol","language":"jsts","symbolName":"setSearchParams","metadata":{"unresolvedName":"setSearchParams"}}],["external:response.data.branches.map",{"id":"external:response.data.branches.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"response.data.branches.map"}}],["symbol-name:setCurrentBranch",{"id":"symbol-name:setCurrentBranch","kind":"symbol","language":"jsts","symbolName":"setCurrentBranch","metadata":{"unresolvedName":"setCurrentBranch"}}],["symbol-name:setGitStatus",{"id":"symbol-name:setGitStatus","kind":"symbol","language":"jsts","symbolName":"setGitStatus","metadata":{"unresolvedName":"setGitStatus"}}],["symbol-name:loadProject",{"id":"symbol-name:loadProject","kind":"symbol","language":"jsts","symbolName":"loadProject","metadata":{"unresolvedName":"loadProject"}}],["symbol-name:loadToolTypes",{"id":"symbol-name:loadToolTypes","kind":"symbol","language":"jsts","symbolName":"loadToolTypes","metadata":{"unresolvedName":"loadToolTypes"}}],["symbol-name:loadGitStatus",{"id":"symbol-name:loadGitStatus","kind":"symbol","language":"jsts","symbolName":"loadGitStatus","metadata":{"unresolvedName":"loadGitStatus"}}],["external:newParams.delete",{"id":"external:newParams.delete","kind":"external","language":"jsts","metadata":{"unresolvedName":"newParams.delete"}}],["symbol-name:handleRepoChange",{"id":"symbol-name:handleRepoChange","kind":"symbol","language":"jsts","symbolName":"handleRepoChange","metadata":{"unresolvedName":"handleRepoChange"}}],["external:window.dispatchEvent",{"id":"external:window.dispatchEvent","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.dispatchEvent"}}],["symbol-name:setMobileTab",{"id":"symbol-name:setMobileTab","kind":"symbol","language":"jsts","symbolName":"setMobileTab","metadata":{"unresolvedName":"setMobileTab"}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":482,"column":20,"cyclomaticComplexity":10,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"handleRepoChange","symbolKind":"function","exported":false,"metadata":{"line":147,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"FileBrowser","symbolKind":"function","exported":false,"metadata":{"line":387,"column":21,"cyclomaticComplexity":26,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["symbol-name:setEntries",{"id":"symbol-name:setEntries","kind":"symbol","language":"jsts","symbolName":"setEntries","metadata":{"unresolvedName":"setEntries"}}],["symbol-name:loadFiles",{"id":"symbol-name:loadFiles","kind":"symbol","language":"jsts","symbolName":"loadFiles","metadata":{"unresolvedName":"loadFiles"}}],["external:path.split(\"/\").slice(0, -1).join",{"id":"external:path.split(\"/\").slice(0, -1).join","kind":"external","language":"jsts","metadata":{"unresolvedName":"path.split(\"/\").slice(0, -1).join"}}],["external:path.split(\"/\").slice",{"id":"external:path.split(\"/\").slice","kind":"external","language":"jsts","metadata":{"unresolvedName":"path.split(\"/\").slice"}}],["external:path.split",{"id":"external:path.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"path.split"}}],["external:gitStatus.modified.includes",{"id":"external:gitStatus.modified.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"gitStatus.modified.includes"}}],["external:gitStatus.added.includes",{"id":"external:gitStatus.added.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"gitStatus.added.includes"}}],["external:gitStatus.deleted.includes",{"id":"external:gitStatus.deleted.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"gitStatus.deleted.includes"}}],["external:gitStatus.untracked.includes",{"id":"external:gitStatus.untracked.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"gitStatus.untracked.includes"}}],["external:entries.map",{"id":"external:entries.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"entries.map"}}],["symbol-name:getFileStatus",{"id":"symbol-name:getFileStatus","kind":"symbol","language":"jsts","symbolName":"getFileStatus","metadata":{"unresolvedName":"getFileStatus"}}],["symbol-name:handleEntryClick",{"id":"symbol-name:handleEntryClick","kind":"symbol","language":"jsts","symbolName":"handleEntryClick","metadata":{"unresolvedName":"handleEntryClick"}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"handleEntryClick","symbolKind":"function","exported":false,"metadata":{"line":436,"column":28,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"navigateUp","symbolKind":"function","exported":false,"metadata":{"line":448,"column":22,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","symbolName":"getFileStatus","symbolKind":"function","exported":false,"metadata":{"line":460,"column":25,"cyclomaticComplexity":6,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database"]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","metadata":{"lineCount":255,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"SessionsPage","symbolKind":"function","exported":true,"metadata":{"line":22,"column":29,"cyclomaticComplexity":17,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["symbol-name:setLastSessionId",{"id":"symbol-name:setLastSessionId","kind":"symbol","language":"jsts","symbolName":"setLastSessionId","metadata":{"unresolvedName":"setLastSessionId"}}],["symbol-name:loadProjects",{"id":"symbol-name:loadProjects","kind":"symbol","language":"jsts","symbolName":"loadProjects","metadata":{"unresolvedName":"loadProjects"}}],["external:[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes",{"id":"external:[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes"}}],["external:s.tool_type_interfaces?.includes",{"id":"external:s.tool_type_interfaces?.includes","kind":"external","language":"jsts","metadata":{"unresolvedName":"s.tool_type_interfaces?.includes"}}],["external:sessions.find",{"id":"external:sessions.find","kind":"external","language":"jsts","metadata":{"unresolvedName":"sessions.find"}}],["external:dirtyDeleteFiles.map",{"id":"external:dirtyDeleteFiles.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"dirtyDeleteFiles.map"}}],["symbol-name:handleForceDelete",{"id":"symbol-name:handleForceDelete","kind":"symbol","language":"jsts","symbolName":"handleForceDelete","metadata":{"unresolvedName":"handleForceDelete"}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":206,"column":32,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"loadProjects","symbolKind":"function","exported":false,"metadata":{"line":54,"column":26,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"loadToolTypes","symbolKind":"function","exported":false,"metadata":{"line":66,"column":27,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"checkHealth","symbolKind":"function","exported":false,"metadata":{"line":92,"column":25,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"loadRepos","symbolKind":"function","exported":false,"metadata":{"line":137,"column":23,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["filesystem","database","auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","symbolName":"handleCreateSuccess","symbolKind":"function","exported":false,"metadata":{"line":153,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","metadata":{"lineCount":154,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","symbolName":"SettingsPage","symbolKind":"function","exported":true,"metadata":{"line":27,"column":29,"cyclomaticComplexity":10,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:setConfig",{"id":"symbol-name:setConfig","kind":"symbol","language":"jsts","symbolName":"setConfig","metadata":{"unresolvedName":"setConfig"}}],["external:window.setTimeout",{"id":"external:window.setTimeout","kind":"external","language":"jsts","metadata":{"unresolvedName":"window.setTimeout"}}],["external:location.pathname.split(\"/\").filter",{"id":"external:location.pathname.split(\"/\").filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"location.pathname.split(\"/\").filter"}}],["external:location.pathname.split",{"id":"external:location.pathname.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"location.pathname.split"}}],["external:location.pathname.endsWith",{"id":"external:location.pathname.endsWith","kind":"external","language":"jsts","metadata":{"unresolvedName":"location.pathname.endsWith"}}],["external:TABS.map",{"id":"external:TABS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"TABS.map"}}],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":40,"column":13,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","symbolName":"handleChange","symbolKind":"function","exported":false,"metadata":{"line":46,"column":24,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","symbolName":"handleSave","symbolKind":"function","exported":false,"metadata":{"line":51,"column":22,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","symbolName":"GeneralSettingsTab","symbolKind":"function","exported":true,"metadata":{"line":118,"column":35,"cyclomaticComplexity":10,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:useOutletContext",{"id":"symbol-name:useOutletContext","kind":"symbol","language":"jsts","symbolName":"useOutletContext","metadata":{"unresolvedName":"useOutletContext"}}],["external:THEME_OPTIONS.map",{"id":"external:THEME_OPTIONS.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"THEME_OPTIONS.map"}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","metadata":{"lineCount":278,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"SSHKeysPage","symbolKind":"function","exported":true,"metadata":{"line":8,"column":28,"cyclomaticComplexity":29,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:newKeyName.trim",{"id":"external:newKeyName.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"newKeyName.trim"}}],["symbol-name:setGenerating",{"id":"symbol-name:setGenerating","kind":"symbol","language":"jsts","symbolName":"setGenerating","metadata":{"unresolvedName":"setGenerating"}}],["symbol-name:createSSHKey",{"id":"symbol-name:createSSHKey","kind":"symbol","language":"jsts","symbolName":"createSSHKey","metadata":{"unresolvedName":"createSSHKey"}}],["symbol-name:setNewKeyName",{"id":"symbol-name:setNewKeyName","kind":"symbol","language":"jsts","symbolName":"setNewKeyName","metadata":{"unresolvedName":"setNewKeyName"}}],["symbol-name:setMutationError",{"id":"symbol-name:setMutationError","kind":"symbol","language":"jsts","symbolName":"setMutationError","metadata":{"unresolvedName":"setMutationError"}}],["symbol-name:deleteSSHKey",{"id":"symbol-name:deleteSSHKey","kind":"symbol","language":"jsts","symbolName":"deleteSSHKey","metadata":{"unresolvedName":"deleteSSHKey"}}],["external:payload?.trim",{"id":"external:payload?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"payload?.trim"}}],["symbol-name:setSigning",{"id":"symbol-name:setSigning","kind":"symbol","language":"jsts","symbolName":"setSigning","metadata":{"unresolvedName":"setSigning"}}],["symbol-name:signPayload",{"id":"symbol-name:signPayload","kind":"symbol","language":"jsts","symbolName":"signPayload","metadata":{"unresolvedName":"signPayload"}}],["external:payload.trim",{"id":"external:payload.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"payload.trim"}}],["symbol-name:setSignatures",{"id":"symbol-name:setSignatures","kind":"symbol","language":"jsts","symbolName":"setSignatures","metadata":{"unresolvedName":"setSignatures"}}],["external:signature?.trim",{"id":"external:signature?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"signature?.trim"}}],["symbol-name:setVerifying",{"id":"symbol-name:setVerifying","kind":"symbol","language":"jsts","symbolName":"setVerifying","metadata":{"unresolvedName":"setVerifying"}}],["symbol-name:verifySignature",{"id":"symbol-name:verifySignature","kind":"symbol","language":"jsts","symbolName":"verifySignature","metadata":{"unresolvedName":"verifySignature"}}],["external:signature.trim",{"id":"external:signature.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"signature.trim"}}],["symbol-name:setVerifyResults",{"id":"symbol-name:setVerifyResults","kind":"symbol","language":"jsts","symbolName":"setVerifyResults","metadata":{"unresolvedName":"setVerifyResults"}}],["external:safeKeys.map",{"id":"external:safeKeys.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"safeKeys.map"}}],["external:new Date(key.created_at).toLocaleDateString",{"id":"external:new Date(key.created_at).toLocaleDateString","kind":"external","language":"jsts","metadata":{"unresolvedName":"new Date(key.created_at).toLocaleDateString"}}],["external:key.public_key.substring",{"id":"external:key.public_key.substring","kind":"external","language":"jsts","metadata":{"unresolvedName":"key.public_key.substring"}}],["symbol-name:copyToClipboard",{"id":"symbol-name:copyToClipboard","kind":"symbol","language":"jsts","symbolName":"copyToClipboard","metadata":{"unresolvedName":"copyToClipboard"}}],["symbol-name:setSignPayloads",{"id":"symbol-name:setSignPayloads","kind":"symbol","language":"jsts","symbolName":"setSignPayloads","metadata":{"unresolvedName":"setSignPayloads"}}],["symbol-name:handleSign",{"id":"symbol-name:handleSign","kind":"symbol","language":"jsts","symbolName":"handleSign","metadata":{"unresolvedName":"handleSign"}}],["external:signPayloads[key.id]?.trim",{"id":"external:signPayloads[key.id]?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"signPayloads[key.id]?.trim"}}],["symbol-name:setVerifyPayloads",{"id":"symbol-name:setVerifyPayloads","kind":"symbol","language":"jsts","symbolName":"setVerifyPayloads","metadata":{"unresolvedName":"setVerifyPayloads"}}],["symbol-name:setVerifySignatures",{"id":"symbol-name:setVerifySignatures","kind":"symbol","language":"jsts","symbolName":"setVerifySignatures","metadata":{"unresolvedName":"setVerifySignatures"}}],["symbol-name:handleVerify",{"id":"symbol-name:handleVerify","kind":"symbol","language":"jsts","symbolName":"handleVerify","metadata":{"unresolvedName":"handleVerify"}}],["external:verifyPayloads[key.id]?.trim",{"id":"external:verifyPayloads[key.id]?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"verifyPayloads[key.id]?.trim"}}],["external:verifySignatures[key.id]?.trim",{"id":"external:verifySignatures[key.id]?.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"verifySignatures[key.id]?.trim"}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"handleGenerate","symbolKind":"function","exported":false,"metadata":{"line":24,"column":3,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"handleDelete","symbolKind":"function","exported":false,"metadata":{"line":40,"column":3,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"copyToClipboard","symbolKind":"function","exported":false,"metadata":{"line":51,"column":3,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"handleSign","symbolKind":"function","exported":false,"metadata":{"line":55,"column":3,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","symbolName":"handleVerify","symbolKind":"function","exported":false,"metadata":{"line":71,"column":3,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","metadata":{"lineCount":51,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","symbolName":"TerminalPage","symbolKind":"function","exported":true,"metadata":{"line":7,"column":39,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","metadata":{"lineCount":400,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":392,"column":23,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation",{"id":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation"}}],["external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation",{"id":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation"}}],["external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation",{"id":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation"}}],["external:expect(screen.getByText(/loading/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/loading/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/loading/i)).toBeInTheDocument"}}],["external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue",{"id":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}}],["external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue",{"id":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}}],["external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue",{"id":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}}],["external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}}],["external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument"}}],["external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument",{"id":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}}],["external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}}],["external:expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument",{"id":"external:expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument"}}],["external:expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument",{"id":"external:expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument"}}],["external:vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue",{"id":"external:vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue"}}],["external:expect(configsListMock).toHaveBeenCalledTimes",{"id":"external:expect(configsListMock).toHaveBeenCalledTimes","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(configsListMock).toHaveBeenCalledTimes"}}],["external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument",{"id":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}}],["external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}}],["external:expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument",{"id":"external:expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument"}}],["external:expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument",{"id":"external:expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument"}}],["external:vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue",{"id":"external:vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue"}}],["external:expect(foldersListMock).toHaveBeenCalledTimes",{"id":"external:expect(foldersListMock).toHaveBeenCalledTimes","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(foldersListMock).toHaveBeenCalledTimes"}}],["external:expect(screen.getByText(\"Active\")).toBeInTheDocument",{"id":"external:expect(screen.getByText(\"Active\")).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(\"Active\")).toBeInTheDocument"}}],["external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue",{"id":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue"}}],["external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue",{"id":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue"}}],["external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue",{"id":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue"}}],["external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument",{"id":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"external","language":"jsts","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}}],["external:vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce",{"id":"external:vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce"}}],["external:vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce",{"id":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce"}}],["external:vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce",{"id":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce"}}],["external:vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue",{"id":"external:vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue"}}],["external:screen.getByText(\"Custom Tool\").closest",{"id":"external:screen.getByText(\"Custom Tool\").closest","kind":"external","language":"jsts","metadata":{"unresolvedName":"screen.getByText(\"Custom Tool\").closest"}}],["external:within(customToolCard as HTMLElement).queryByRole",{"id":"external:within(customToolCard as HTMLElement).queryByRole","kind":"external","language":"jsts","metadata":{"unresolvedName":"within(customToolCard as HTMLElement).queryByRole"}}],["external:vi.spyOn(window, \"confirm\").mockReturnValue",{"id":"external:vi.spyOn(window, \"confirm\").mockReturnValue","kind":"external","language":"jsts","metadata":{"unresolvedName":"vi.spyOn(window, \"confirm\").mockReturnValue"}}],["external:(toolTypes || []).find",{"id":"external:(toolTypes || []).find","kind":"external","language":"jsts","metadata":{"unresolvedName":"(toolTypes || []).find"}}],["external:(configs || []).filter",{"id":"external:(configs || []).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"(configs || []).filter"}}],["symbol-name:listToolConfigs",{"id":"symbol-name:listToolConfigs","kind":"symbol","language":"jsts","symbolName":"listToolConfigs","metadata":{"unresolvedName":"listToolConfigs"}}],["symbol-name:setConfigs",{"id":"symbol-name:setConfigs","kind":"symbol","language":"jsts","symbolName":"setConfigs","metadata":{"unresolvedName":"setConfigs"}}],["symbol-name:setFolders",{"id":"symbol-name:setFolders","kind":"symbol","language":"jsts","symbolName":"setFolders","metadata":{"unresolvedName":"setFolders"}}],["symbol-name:setToolTypeForm",{"id":"symbol-name:setToolTypeForm","kind":"symbol","language":"jsts","symbolName":"setToolTypeForm","metadata":{"unresolvedName":"setToolTypeForm"}}],["symbol-name:setToolTypeError",{"id":"symbol-name:setToolTypeError","kind":"symbol","language":"jsts","symbolName":"setToolTypeError","metadata":{"unresolvedName":"setToolTypeError"}}],["symbol-name:setToolTypeDirty",{"id":"symbol-name:setToolTypeDirty","kind":"symbol","language":"jsts","symbolName":"setToolTypeDirty","metadata":{"unresolvedName":"setToolTypeDirty"}}],["external:toolType.default_port?.toString",{"id":"external:toolType.default_port?.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolType.default_port?.toString"}}],["external:toolType.readiness_probe?.timeout?.toString",{"id":"external:toolType.readiness_probe?.timeout?.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolType.readiness_probe?.timeout?.toString"}}],["external:toolType.readiness_probe?.interval?.toString",{"id":"external:toolType.readiness_probe?.interval?.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolType.readiness_probe?.interval?.toString"}}],["external:toolType.required_variables?.join",{"id":"external:toolType.required_variables?.join","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolType.required_variables?.join"}}],["symbol-name:setSelectedToolTypeId",{"id":"symbol-name:setSelectedToolTypeId","kind":"symbol","language":"jsts","symbolName":"setSelectedToolTypeId","metadata":{"unresolvedName":"setSelectedToolTypeId"}}],["symbol-name:populateToolTypeForm",{"id":"symbol-name:populateToolTypeForm","kind":"symbol","language":"jsts","symbolName":"populateToolTypeForm","metadata":{"unresolvedName":"populateToolTypeForm"}}],["symbol-name:setRightPanelTab",{"id":"symbol-name:setRightPanelTab","kind":"symbol","language":"jsts","symbolName":"setRightPanelTab","metadata":{"unresolvedName":"setRightPanelTab"}}],["symbol-name:setShowConfigForm",{"id":"symbol-name:setShowConfigForm","kind":"symbol","language":"jsts","symbolName":"setShowConfigForm","metadata":{"unresolvedName":"setShowConfigForm"}}],["symbol-name:setShowFolderForm",{"id":"symbol-name:setShowFolderForm","kind":"symbol","language":"jsts","symbolName":"setShowFolderForm","metadata":{"unresolvedName":"setShowFolderForm"}}],["symbol-name:resetToolTypeForm",{"id":"symbol-name:resetToolTypeForm","kind":"symbol","language":"jsts","symbolName":"resetToolTypeForm","metadata":{"unresolvedName":"resetToolTypeForm"}}],["external:toolTypeForm.name.trim",{"id":"external:toolTypeForm.name.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.name.trim"}}],["external:toolTypeForm.display_name.trim",{"id":"external:toolTypeForm.display_name.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.display_name.trim"}}],["external:toolTypeForm.default_port.trim",{"id":"external:toolTypeForm.default_port.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.default_port.trim"}}],["symbol-name:isNaN",{"id":"symbol-name:isNaN","kind":"symbol","language":"jsts","symbolName":"isNaN","metadata":{"unresolvedName":"isNaN"}}],["external:template.trim",{"id":"external:template.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"template.trim"}}],["external:toolTypeForm.required_variables\n .split(\",\")\n .map",{"id":"external:toolTypeForm.required_variables\n .split(\",\")\n .map","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split(\",\")\n .map"}}],["external:toolTypeForm.required_variables\n .split",{"id":"external:toolTypeForm.required_variables\n .split","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split"}}],["external:v.trim",{"id":"external:v.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"v.trim"}}],["external:toolTypeForm.readiness_command.trim",{"id":"external:toolTypeForm.readiness_command.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.readiness_command.trim"}}],["external:toolTypeForm.description.trim",{"id":"external:toolTypeForm.description.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.description.trim"}}],["external:toolTypeForm.category.trim",{"id":"external:toolTypeForm.category.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.category.trim"}}],["external:toolTypeForm.startup_command.trim",{"id":"external:toolTypeForm.startup_command.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolTypeForm.startup_command.trim"}}],["symbol-name:setConfigForm",{"id":"symbol-name:setConfigForm","kind":"symbol","language":"jsts","symbolName":"setConfigForm","metadata":{"unresolvedName":"setConfigForm"}}],["symbol-name:setConfigError",{"id":"symbol-name:setConfigError","kind":"symbol","language":"jsts","symbolName":"setConfigError","metadata":{"unresolvedName":"setConfigError"}}],["symbol-name:setSelectedConfig",{"id":"symbol-name:setSelectedConfig","kind":"symbol","language":"jsts","symbolName":"setSelectedConfig","metadata":{"unresolvedName":"setSelectedConfig"}}],["symbol-name:resetConfigForm",{"id":"symbol-name:resetConfigForm","kind":"symbol","language":"jsts","symbolName":"resetConfigForm","metadata":{"unresolvedName":"resetConfigForm"}}],["external:config.port_override?.toString",{"id":"external:config.port_override?.toString","kind":"external","language":"jsts","metadata":{"unresolvedName":"config.port_override?.toString"}}],["external:configForm.key.trim",{"id":"external:configForm.key.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"configForm.key.trim"}}],["external:configForm.env_vars_json.trim",{"id":"external:configForm.env_vars_json.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"configForm.env_vars_json.trim"}}],["external:configForm.volumes_json.trim",{"id":"external:configForm.volumes_json.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"configForm.volumes_json.trim"}}],["external:configForm.start_command.trim",{"id":"external:configForm.start_command.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"configForm.start_command.trim"}}],["external:configForm.working_directory.trim",{"id":"external:configForm.working_directory.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"configForm.working_directory.trim"}}],["symbol-name:updateToolConfig",{"id":"symbol-name:updateToolConfig","kind":"symbol","language":"jsts","symbolName":"updateToolConfig","metadata":{"unresolvedName":"updateToolConfig"}}],["symbol-name:createToolConfig",{"id":"symbol-name:createToolConfig","kind":"symbol","language":"jsts","symbolName":"createToolConfig","metadata":{"unresolvedName":"createToolConfig"}}],["symbol-name:deleteToolConfig",{"id":"symbol-name:deleteToolConfig","kind":"symbol","language":"jsts","symbolName":"deleteToolConfig","metadata":{"unresolvedName":"deleteToolConfig"}}],["symbol-name:setFolderForm",{"id":"symbol-name:setFolderForm","kind":"symbol","language":"jsts","symbolName":"setFolderForm","metadata":{"unresolvedName":"setFolderForm"}}],["symbol-name:setFolderError",{"id":"symbol-name:setFolderError","kind":"symbol","language":"jsts","symbolName":"setFolderError","metadata":{"unresolvedName":"setFolderError"}}],["symbol-name:setSelectedFolder",{"id":"symbol-name:setSelectedFolder","kind":"symbol","language":"jsts","symbolName":"setSelectedFolder","metadata":{"unresolvedName":"setSelectedFolder"}}],["symbol-name:resetFolderForm",{"id":"symbol-name:resetFolderForm","kind":"symbol","language":"jsts","symbolName":"resetFolderForm","metadata":{"unresolvedName":"resetFolderForm"}}],["external:folderForm.name.trim",{"id":"external:folderForm.name.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"folderForm.name.trim"}}],["external:folderForm.mount_path.trim",{"id":"external:folderForm.mount_path.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"folderForm.mount_path.trim"}}],["external:folderForm.files_json.trim",{"id":"external:folderForm.files_json.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"folderForm.files_json.trim"}}],["external:folderForm.description.trim",{"id":"external:folderForm.description.trim","kind":"external","language":"jsts","metadata":{"unresolvedName":"folderForm.description.trim"}}],["external:selectedToolType.required_variables?.join",{"id":"external:selectedToolType.required_variables?.join","kind":"external","language":"jsts","metadata":{"unresolvedName":"selectedToolType.required_variables?.join"}}],["symbol-name:handleDeleteToolType",{"id":"symbol-name:handleDeleteToolType","kind":"symbol","language":"jsts","symbolName":"handleDeleteToolType","metadata":{"unresolvedName":"handleDeleteToolType"}}],["symbol-name:handleToolTypeSubmit",{"id":"symbol-name:handleToolTypeSubmit","kind":"symbol","language":"jsts","symbolName":"handleToolTypeSubmit","metadata":{"unresolvedName":"handleToolTypeSubmit"}}],["symbol-name:handleSelectToolType",{"id":"symbol-name:handleSelectToolType","kind":"symbol","language":"jsts","symbolName":"handleSelectToolType","metadata":{"unresolvedName":"handleSelectToolType"}}],["external:([\"details\", \"configs\", \"folders\"] as RightPanelTab[]).map",{"id":"external:([\"details\", \"configs\", \"folders\"] as RightPanelTab[]).map","kind":"external","language":"jsts","metadata":{"unresolvedName":"([\"details\", \"configs\", \"folders\"] as RightPanelTab[]).map"}}],["external:toolConfigs.map",{"id":"external:toolConfigs.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolConfigs.map"}}],["symbol-name:openEditConfig",{"id":"symbol-name:openEditConfig","kind":"symbol","language":"jsts","symbolName":"openEditConfig","metadata":{"unresolvedName":"openEditConfig"}}],["symbol-name:handleDeleteConfig",{"id":"symbol-name:handleDeleteConfig","kind":"symbol","language":"jsts","symbolName":"handleDeleteConfig","metadata":{"unresolvedName":"handleDeleteConfig"}}],["external:toolFolders.map",{"id":"external:toolFolders.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"toolFolders.map"}}],["symbol-name:openEditFolder",{"id":"symbol-name:openEditFolder","kind":"symbol","language":"jsts","symbolName":"openEditFolder","metadata":{"unresolvedName":"openEditFolder"}}],["symbol-name:handleDeleteFolder",{"id":"symbol-name:handleDeleteFolder","kind":"symbol","language":"jsts","symbolName":"handleDeleteFolder","metadata":{"unresolvedName":"handleDeleteFolder"}}],["/home/alex/projects/headquarter/apps/web/src/router.tsx:AppRouter",{"id":"/home/alex/projects/headquarter/apps/web/src/router.tsx:AppRouter","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/router.tsx","symbolName":"AppRouter","symbolKind":"function","exported":true,"metadata":{"line":20,"column":26,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider",{"id":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","symbolName":"AuthProvider","symbolKind":"function","exported":true,"metadata":{"line":17,"column":29,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["symbol-name:setUser",{"id":"symbol-name:setUser","kind":"symbol","language":"jsts","symbolName":"setUser","metadata":{"unresolvedName":"setUser"}}],["/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":39,"column":13,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth",{"id":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","symbolName":"useAuth","symbolKind":"function","exported":true,"metadata":{"line":56,"column":24,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["symbol-name:useContext",{"id":"symbol-name:useContext","kind":"symbol","language":"jsts","symbolName":"useContext","metadata":{"unresolvedName":"useContext"}}],["/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider",{"id":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","symbolName":"SessionsProvider","symbolKind":"function","exported":true,"metadata":{"line":24,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":27,"column":38,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions",{"id":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","symbolName":"useSessions","symbolKind":"function","exported":true,"metadata":{"line":38,"column":28,"cyclomaticComplexity":2,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["auth","user-input"]}}],["file:/home/alex/projects/headquarter/apps/web/src/test/setup.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/test/setup.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/test/setup.ts","metadata":{"lineCount":2,"featureKind":"library","trustBoundaries":[]}}],["external:@testing-library/jest-dom/vitest",{"id":"external:@testing-library/jest-dom/vitest","kind":"external","language":"jsts","metadata":{"source":"@testing-library/jest-dom/vitest"}}],["/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage",{"id":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","symbolName":"extractErrorMessage","symbolKind":"function","exported":true,"metadata":{"line":1,"column":36,"cyclomaticComplexity":5,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:detail.map((d) => typeof d === \"string\" ? d : d.msg || JSON.stringify(d)).join",{"id":"external:detail.map((d) => typeof d === \"string\" ? d : d.msg || JSON.stringify(d)).join","kind":"external","language":"jsts","metadata":{"unresolvedName":"detail.map((d) => typeof d === \"string\" ? d : d.msg || JSON.stringify(d)).join"}}],["external:detail.map",{"id":"external:detail.map","kind":"external","language":"jsts","metadata":{"unresolvedName":"detail.map"}}],["external:prismjs",{"id":"external:prismjs","kind":"external","language":"jsts","metadata":{"source":"prismjs"}}],["/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage",{"id":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts","symbolName":"detectLanguage","symbolKind":"function","exported":true,"metadata":{"line":69,"column":31,"cyclomaticComplexity":3,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:filename.split(\".\").pop()?.toLowerCase",{"id":"external:filename.split(\".\").pop()?.toLowerCase","kind":"external","language":"jsts","metadata":{"unresolvedName":"filename.split(\".\").pop()?.toLowerCase"}}],["external:filename.split(\".\").pop",{"id":"external:filename.split(\".\").pop","kind":"external","language":"jsts","metadata":{"unresolvedName":"filename.split(\".\").pop"}}],["external:filename.split",{"id":"external:filename.split","kind":"external","language":"jsts","metadata":{"unresolvedName":"filename.split"}}],["/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode",{"id":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts","symbolName":"highlightCode","symbolKind":"function","exported":true,"metadata":{"line":74,"column":30,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["external:Prism.highlight",{"id":"external:Prism.highlight","kind":"external","language":"jsts","metadata":{"unresolvedName":"Prism.highlight"}}],["/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage",{"id":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts","symbolName":"loadLanguage","symbolKind":"function","exported":true,"metadata":{"line":79,"column":29,"cyclomaticComplexity":4,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["symbol-name:import",{"id":"symbol-name:import","kind":"symbol","language":"jsts","symbolName":"import","metadata":{"unresolvedName":"import"}}],["file:/home/alex/projects/headquarter/apps/web/vite.config.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/vite.config.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/vite.config.ts","metadata":{"lineCount":14,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["external:vite",{"id":"external:vite","kind":"external","language":"jsts","metadata":{"source":"vite"}}],["external:@vitejs/plugin-react",{"id":"external:@vitejs/plugin-react","kind":"external","language":"jsts","metadata":{"source":"@vitejs/plugin-react"}}],["symbol-name:listToolDefinitions",{"id":"symbol-name:listToolDefinitions","kind":"symbol","language":"jsts","symbolName":"listToolDefinitions","metadata":{"unresolvedName":"listToolDefinitions"}}],["symbol-name:setBaseDefinitions",{"id":"symbol-name:setBaseDefinitions","kind":"symbol","language":"jsts","symbolName":"setBaseDefinitions","metadata":{"unresolvedName":"setBaseDefinitions"}}],["external:(defs || []).filter",{"id":"external:(defs || []).filter","kind":"external","language":"jsts","metadata":{"unresolvedName":"(defs || []).filter"}}],["symbol-name:setManifestData",{"id":"symbol-name:setManifestData","kind":"symbol","language":"jsts","symbolName":"setManifestData","metadata":{"unresolvedName":"setManifestData"}}],["symbol-name:setManifestDefinitionId",{"id":"symbol-name:setManifestDefinitionId","kind":"symbol","language":"jsts","symbolName":"setManifestDefinitionId","metadata":{"unresolvedName":"setManifestDefinitionId"}}],["file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts",{"id":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","metadata":{"lineCount":94,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"listToolTypes","symbolKind":"function","exported":true,"metadata":{"line":66,"column":30,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:getToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:getToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"getToolType","symbolKind":"function","exported":true,"metadata":{"line":71,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"createToolType","symbolKind":"function","exported":true,"metadata":{"line":76,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"updateToolType","symbolKind":"function","exported":true,"metadata":{"line":81,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"deleteToolType","symbolKind":"function","exported":true,"metadata":{"line":86,"column":31,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","symbolName":"validateToolType","symbolKind":"function","exported":true,"metadata":{"line":90,"column":33,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":["network","external-api","serialization"]}}],["file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx",{"id":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","kind":"file","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","metadata":{"lineCount":1513,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"ToolWorkshopPage","symbolKind":"function","exported":true,"metadata":{"line":45,"column":33,"cyclomaticComplexity":167,"maxNestingDepth":4,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"","symbolKind":"function","exported":false,"metadata":{"line":1476,"column":56,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"resetToolTypeForm","symbolKind":"function","exported":false,"metadata":{"line":137,"column":29,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"populateToolTypeForm","symbolKind":"function","exported":false,"metadata":{"line":161,"column":32,"cyclomaticComplexity":15,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleSelectToolType","symbolKind":"function","exported":false,"metadata":{"line":186,"column":32,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleCreateNew","symbolKind":"function","exported":false,"metadata":{"line":204,"column":27,"cyclomaticComplexity":3,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleToolTypeSubmit","symbolKind":"function","exported":false,"metadata":{"line":218,"column":32,"cyclomaticComplexity":29,"maxNestingDepth":3,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleDeleteToolType","symbolKind":"function","exported":false,"metadata":{"line":305,"column":32,"cyclomaticComplexity":4,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"resetConfigForm","symbolKind":"function","exported":false,"metadata":{"line":321,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"openCreateConfig","symbolKind":"function","exported":false,"metadata":{"line":337,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"openEditConfig","symbolKind":"function","exported":false,"metadata":{"line":342,"column":26,"cyclomaticComplexity":7,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleConfigSubmit","symbolKind":"function","exported":false,"metadata":{"line":359,"column":30,"cyclomaticComplexity":15,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleDeleteConfig","symbolKind":"function","exported":false,"metadata":{"line":417,"column":30,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"service","trustBoundaries":["filesystem","database"]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"resetFolderForm","symbolKind":"function","exported":false,"metadata":{"line":428,"column":27,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"openCreateFolder","symbolKind":"function","exported":false,"metadata":{"line":440,"column":28,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"openEditFolder","symbolKind":"function","exported":false,"metadata":{"line":445,"column":26,"cyclomaticComplexity":2,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleFolderSubmit","symbolKind":"function","exported":false,"metadata":{"line":458,"column":30,"cyclomaticComplexity":9,"maxNestingDepth":2,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"handleDeleteFolder","symbolKind":"function","exported":false,"metadata":{"line":500,"column":30,"cyclomaticComplexity":3,"maxNestingDepth":1,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}],["/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:preventDefault",{"id":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:preventDefault","kind":"symbol","language":"jsts","filePath":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","symbolName":"preventDefault","symbolKind":"function","exported":false,"metadata":{"line":610,"column":54,"cyclomaticComplexity":1,"maxNestingDepth":0,"isBoundaryWrapper":false,"isPassThroughWrapper":false,"featureKind":"library","trustBoundaries":[]}}]],"edges":[{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","to":"external:axios","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect","to":"external:path.startsWith","kind":"calls","metadata":{"unresolvedName":"path.startsWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:shouldSkipAuthRedirect","kind":"calls","metadata":{"unresolvedName":"shouldSkipAuthRedirect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"external:window.location.assign","kind":"calls","metadata":{"unresolvedName":"window.location.assign"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"external:Promise.reject","kind":"calls","metadata":{"unresolvedName":"Promise.reject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"external:error.message?.includes","kind":"calls","metadata":{"unresolvedName":"error.message?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"external:retryCount.get","kind":"calls","metadata":{"unresolvedName":"retryCount.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"external:retryCount.set","kind":"calls","metadata":{"unresolvedName":"retryCount.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/client.ts:","to":"symbol-name:apiClient","kind":"calls","metadata":{"unresolvedName":"apiClient"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:describe","kind":"calls","metadata":{"unresolvedName":"describe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"calls","metadata":{"unresolvedName":"listConfigFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"calls","metadata":{"unresolvedName":"createConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"calls","metadata":{"unresolvedName":"updateConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"calls","metadata":{"unresolvedName":"deleteConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"calls","metadata":{"unresolvedName":"listConfigFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"calls","metadata":{"unresolvedName":"listConfigFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result[0].files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"calls","metadata":{"unresolvedName":"createConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"calls","metadata":{"unresolvedName":"createConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.name).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.name).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"calls","metadata":{"unresolvedName":"updateConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"calls","metadata":{"unresolvedName":"updateConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(result.files).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.files).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"calls","metadata":{"unresolvedName":"deleteConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"calls","metadata":{"unresolvedName":"deleteConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:getConfigFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:getConfigFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:getConfigFolder","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:addProjectOverride","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:addProjectOverride","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:addProjectOverride","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateProjectOverride","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateProjectOverride","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateProjectOverride","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteProjectOverride","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteProjectOverride","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteProjectOverride","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:getConfigProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:getConfigProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:getConfigProfile","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:resolveDefaultProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:resolveDefaultProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:resolveDefaultProfile","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listAllUserRepositories","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listAllUserRepositories","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listAllUserRepositories","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createExternalRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createExternalRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createExternalRepository","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:updateRepositorySshKey","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:updateRepositorySshKey","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:updateRepositorySshKey","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","to":"external:searchParams.set","kind":"calls","metadata":{"unresolvedName":"searchParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","to":"external:searchParams.toString","kind":"calls","metadata":{"unresolvedName":"searchParams.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteBranch","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteBranch","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteBranch","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:getProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:getProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:getProfile","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","to":"external:formData.append","kind":"calls","metadata":{"unresolvedName":"formData.append"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:setDefaultSSHKey","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:setDefaultSSHKey","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:setDefaultSSHKey","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"external:axios","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"calls","metadata":{"unresolvedName":"restartInstance"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","to":"external:params.append","kind":"calls","metadata":{"unresolvedName":"params.append"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","to":"external:params.toString","kind":"calls","metadata":{"unresolvedName":"params.toString"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:getToolConfigDefaults","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:getToolConfigDefaults","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:getToolConfigDefaults","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:getToolDefinition","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:getToolDefinition","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:getToolDefinition","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:createToolDefinition","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:createToolDefinition","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:createToolDefinition","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:updateToolDefinition","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:updateToolDefinition","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:updateToolDefinition","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:deleteToolDefinition","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:deleteToolDefinition","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:deleteToolDefinition","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:describe","kind":"calls","metadata":{"unresolvedName":"describe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].readiness_probe).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBeNull","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBeNull"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.readiness_probe).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.valid).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.valid).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.errors).toContain","kind":"calls","metadata":{"unresolvedName":"expect(result.errors).toContain"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].readiness_probe).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBeNull","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBeNull"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result[0].readiness_probe).toEqual"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result[0].definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result[0].dockerfile_template).toBeNull","kind":"calls","metadata":{"unresolvedName":"expect(result[0].dockerfile_template).toBeNull"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.readiness_probe).toEqual"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPost).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPost).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPost.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPost.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.readiness_probe).toEqual","kind":"calls","metadata":{"unresolvedName":"expect(result.readiness_probe).toEqual"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.valid).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.valid).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.errors).toContain","kind":"calls","metadata":{"unresolvedName":"expect(result.errors).toContain"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.valid).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.valid).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockGet).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockGet).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockGet.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockGet.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.valid).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.valid).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.errors).toContain","kind":"calls","metadata":{"unresolvedName":"expect(result.errors).toContain"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockPut.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockPut.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(result.definition_type).toBe","kind":"calls","metadata":{"unresolvedName":"expect(result.definition_type).toBe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockPut).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockPut).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:mockDelete.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDelete.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"external:expect(mockDelete).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(mockDelete).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:SessionItem","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:SessionItem","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","kind":"calls","metadata":{"unresolvedName":"useTheme"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"calls","metadata":{"unresolvedName":"useAuth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions","kind":"calls","metadata":{"unresolvedName":"useSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"external:location.pathname.includes","kind":"calls","metadata":{"unresolvedName":"location.pathname.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:setAllSessions","kind":"calls","metadata":{"unresolvedName":"setAllSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"symbol-name:logout","kind":"calls","metadata":{"unresolvedName":"logout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"external:NAV_ITEMS.map","kind":"calls","metadata":{"unresolvedName":"NAV_ITEMS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:AppShell","to":"external:sessions.map","kind":"calls","metadata":{"unresolvedName":"sessions.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:setAllSessions","kind":"calls","metadata":{"unresolvedName":"setAllSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"symbol-name:logout","kind":"calls","metadata":{"unresolvedName":"logout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx:","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"external:react-simple-code-editor","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"symbol-name:highlight","kind":"calls","metadata":{"unresolvedName":"highlight"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"external:input\n .split(\"\\n\")\n .map","kind":"calls","metadata":{"unresolvedName":"input\n .split(\"\\n\")\n .map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"external:input\n .split","kind":"calls","metadata":{"unresolvedName":"input\n .split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:CodeEditor","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"calls","metadata":{"unresolvedName":"highlightCode"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:","to":"symbol-name:highlight","kind":"calls","metadata":{"unresolvedName":"highlight"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:highlight","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:highlight","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx:highlight","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:originalContent.split","kind":"calls","metadata":{"unresolvedName":"originalContent.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:newContent.split","kind":"calls","metadata":{"unresolvedName":"newContent.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:Math.max","kind":"calls","metadata":{"unresolvedName":"Math.max"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:diff.push","kind":"calls","metadata":{"unresolvedName":"diff.push"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:message.trim","kind":"calls","metadata":{"unresolvedName":"message.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"symbol-name:onCommit","kind":"calls","metadata":{"unresolvedName":"onCommit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","kind":"calls","metadata":{"unresolvedName":"generateDiff"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:diff.some","kind":"calls","metadata":{"unresolvedName":"diff.some"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"external:diff.map","kind":"calls","metadata":{"unresolvedName":"diff.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:CommitDialog","to":"symbol-name:setMessage","kind":"calls","metadata":{"unresolvedName":"setMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","to":"external:originalContent.split","kind":"calls","metadata":{"unresolvedName":"originalContent.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","to":"external:newContent.split","kind":"calls","metadata":{"unresolvedName":"newContent.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","to":"external:Math.max","kind":"calls","metadata":{"unresolvedName":"Math.max"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:generateDiff","to":"external:diff.push","kind":"calls","metadata":{"unresolvedName":"diff.push"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","to":"external:message.trim","kind":"calls","metadata":{"unresolvedName":"message.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx:handleCommit","to":"symbol-name:onCommit","kind":"calls","metadata":{"unresolvedName":"onCommit"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"external:message.trim","kind":"calls","metadata":{"unresolvedName":"message.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","kind":"calls","metadata":{"unresolvedName":"commitChanges"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"symbol-name:setMessage","kind":"calls","metadata":{"unresolvedName":"setMessage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"symbol-name:onCommit","kind":"calls","metadata":{"unresolvedName":"onCommit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"external:modified.map","kind":"calls","metadata":{"unresolvedName":"modified.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"external:added.map","kind":"calls","metadata":{"unresolvedName":"added.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"external:deleted.map","kind":"calls","metadata":{"unresolvedName":"deleted.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:CommitPanel","to":"external:untracked.map","kind":"calls","metadata":{"unresolvedName":"untracked.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"external:message.trim","kind":"calls","metadata":{"unresolvedName":"message.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:commitChanges","kind":"calls","metadata":{"unresolvedName":"commitChanges"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"symbol-name:setMessage","kind":"calls","metadata":{"unresolvedName":"setMessage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx:handleCommit","to":"symbol-name:onCommit","kind":"calls","metadata":{"unresolvedName":"onCommit"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setConfigProfiles","kind":"calls","metadata":{"unresolvedName":"setConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setSelectedConfigProfile","kind":"calls","metadata":{"unresolvedName":"setSelectedConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","kind":"calls","metadata":{"unresolvedName":"loadProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setIsLoadingBranches","kind":"calls","metadata":{"unresolvedName":"setIsLoadingBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"calls","metadata":{"unresolvedName":"listRepositoryBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setBranch","kind":"calls","metadata":{"unresolvedName":"setBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setBaseBranch","kind":"calls","metadata":{"unresolvedName":"setBaseBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"calls","metadata":{"unresolvedName":"loadBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:repositories.filter","kind":"calls","metadata":{"unresolvedName":"repositories.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:event.preventDefault","kind":"calls","metadata":{"unresolvedName":"event.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:repositories.find","kind":"calls","metadata":{"unresolvedName":"repositories.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setProgress","kind":"calls","metadata":{"unresolvedName":"setProgress"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","kind":"calls","metadata":{"unresolvedName":"createInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setSelectedRepo","kind":"calls","metadata":{"unresolvedName":"setSelectedRepo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setSelectedToolType","kind":"calls","metadata":{"unresolvedName":"setSelectedToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setDisplayName","kind":"calls","metadata":{"unresolvedName":"setDisplayName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:setNewBranchName","kind":"calls","metadata":{"unresolvedName":"setNewBranchName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:onSuccess","kind":"calls","metadata":{"unresolvedName":"onSuccess"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:renderStep","kind":"calls","metadata":{"unresolvedName":"renderStep"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:projects.find","kind":"calls","metadata":{"unresolvedName":"projects.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"symbol-name:onProjectChange","kind":"calls","metadata":{"unresolvedName":"onProjectChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:projects.map","kind":"calls","metadata":{"unresolvedName":"projects.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:availableRepos.map","kind":"calls","metadata":{"unresolvedName":"availableRepos.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:toolTypes.map","kind":"calls","metadata":{"unresolvedName":"toolTypes.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:configProfiles.map","kind":"calls","metadata":{"unresolvedName":"configProfiles.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:branches.map","kind":"calls","metadata":{"unresolvedName":"branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:CreateSessionForm","to":"external:sshKeys.find","kind":"calls","metadata":{"unresolvedName":"sshKeys.find"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadKeys","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setConfigProfiles","kind":"calls","metadata":{"unresolvedName":"setConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedConfigProfile","kind":"calls","metadata":{"unresolvedName":"setSelectedConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","kind":"calls","metadata":{"unresolvedName":"loadProfiles"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","to":"symbol-name:setConfigProfiles","kind":"calls","metadata":{"unresolvedName":"setConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadProfiles","to":"symbol-name:setSelectedConfigProfile","kind":"calls","metadata":{"unresolvedName":"setSelectedConfigProfile"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsLoadingBranches","kind":"calls","metadata":{"unresolvedName":"setIsLoadingBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"calls","metadata":{"unresolvedName":"listRepositoryBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setBranch","kind":"calls","metadata":{"unresolvedName":"setBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setBaseBranch","kind":"calls","metadata":{"unresolvedName":"setBaseBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"calls","metadata":{"unresolvedName":"loadBranches"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","to":"symbol-name:setIsLoadingBranches","kind":"calls","metadata":{"unresolvedName":"setIsLoadingBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositoryBranches","kind":"calls","metadata":{"unresolvedName":"listRepositoryBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","to":"symbol-name:setBranch","kind":"calls","metadata":{"unresolvedName":"setBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","to":"symbol-name:setBaseBranch","kind":"calls","metadata":{"unresolvedName":"setBaseBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"external:event.preventDefault","kind":"calls","metadata":{"unresolvedName":"event.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"external:repositories.find","kind":"calls","metadata":{"unresolvedName":"repositories.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setProgress","kind":"calls","metadata":{"unresolvedName":"setProgress"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:createInstance","kind":"calls","metadata":{"unresolvedName":"createInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setSelectedRepo","kind":"calls","metadata":{"unresolvedName":"setSelectedRepo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setSelectedToolType","kind":"calls","metadata":{"unresolvedName":"setSelectedToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setDisplayName","kind":"calls","metadata":{"unresolvedName":"setDisplayName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setBranch","kind":"calls","metadata":{"unresolvedName":"setBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setNewBranchName","kind":"calls","metadata":{"unresolvedName":"setNewBranchName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setBaseBranch","kind":"calls","metadata":{"unresolvedName":"setBaseBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:handleSubmit","to":"symbol-name:onSuccess","kind":"calls","metadata":{"unresolvedName":"onSuccess"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:renderStep","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:renderStep","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedRepo","kind":"calls","metadata":{"unresolvedName":"setSelectedRepo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedToolType","kind":"calls","metadata":{"unresolvedName":"setSelectedToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:onProjectChange","kind":"calls","metadata":{"unresolvedName":"onProjectChange"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedRepo","kind":"calls","metadata":{"unresolvedName":"setSelectedRepo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedToolType","kind":"calls","metadata":{"unresolvedName":"setSelectedToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setSelectedToolType","kind":"calls","metadata":{"unresolvedName":"setSelectedToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setCloneMode","kind":"calls","metadata":{"unresolvedName":"setCloneMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setIsCreatingNewBranch","kind":"calls","metadata":{"unresolvedName":"setIsCreatingNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setNewBranchName","kind":"calls","metadata":{"unresolvedName":"setNewBranchName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setBranch","kind":"calls","metadata":{"unresolvedName":"setBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"symbol-name:setBaseBranch","kind":"calls","metadata":{"unresolvedName":"setBaseBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"external:repositories.find","kind":"calls","metadata":{"unresolvedName":"repositories.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:","to":"external:sshKeys.find","kind":"calls","metadata":{"unresolvedName":"sshKeys.find"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/code-editor.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-dialog.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:useSearchParams","kind":"calls","metadata":{"unresolvedName":"useSearchParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"calls","metadata":{"unresolvedName":"useAuth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:searchParams.get","kind":"calls","metadata":{"unresolvedName":"searchParams.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setContent","kind":"calls","metadata":{"unresolvedName":"setContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setOriginalContent","kind":"calls","metadata":{"unresolvedName":"setOriginalContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setIsBinary","kind":"calls","metadata":{"unresolvedName":"setIsBinary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setLanguage","kind":"calls","metadata":{"unresolvedName":"setLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","kind":"calls","metadata":{"unresolvedName":"detectLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:loadFile","kind":"calls","metadata":{"unresolvedName":"loadFile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setMode","kind":"calls","metadata":{"unresolvedName":"setMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setShowCommitDialog","kind":"calls","metadata":{"unresolvedName":"setShowCommitDialog"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:setSaving","kind":"calls","metadata":{"unresolvedName":"setSaving"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"calls","metadata":{"unresolvedName":"handleEdit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"calls","metadata":{"unresolvedName":"handleCancel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"symbol-name:handleSave","kind":"calls","metadata":{"unresolvedName":"handleSave"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:filePath.split(\"/\").map","kind":"calls","metadata":{"unresolvedName":"filePath.split(\"/\").map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:FileEditor","to":"external:filePath.split","kind":"calls","metadata":{"unresolvedName":"filePath.split"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setContent","kind":"calls","metadata":{"unresolvedName":"setContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setOriginalContent","kind":"calls","metadata":{"unresolvedName":"setOriginalContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setIsBinary","kind":"calls","metadata":{"unresolvedName":"setIsBinary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:setLanguage","kind":"calls","metadata":{"unresolvedName":"setLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","kind":"calls","metadata":{"unresolvedName":"detectLanguage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:loadFile","kind":"calls","metadata":{"unresolvedName":"loadFile"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","to":"symbol-name:setMode","kind":"calls","metadata":{"unresolvedName":"setMode"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","to":"symbol-name:setContent","kind":"calls","metadata":{"unresolvedName":"setContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","to":"symbol-name:setMode","kind":"calls","metadata":{"unresolvedName":"setMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","to":"symbol-name:setShowCommitDialog","kind":"calls","metadata":{"unresolvedName":"setShowCommitDialog"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave","to":"symbol-name:setMode","kind":"calls","metadata":{"unresolvedName":"setMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleSave","to":"symbol-name:setShowCommitDialog","kind":"calls","metadata":{"unresolvedName":"setShowCommitDialog"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"symbol-name:setSaving","kind":"calls","metadata":{"unresolvedName":"setSaving"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"symbol-name:setOriginalContent","kind":"calls","metadata":{"unresolvedName":"setOriginalContent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"symbol-name:setMode","kind":"calls","metadata":{"unresolvedName":"setMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"symbol-name:setShowCommitDialog","kind":"calls","metadata":{"unresolvedName":"setShowCommitDialog"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCommit","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"calls","metadata":{"unresolvedName":"handleEdit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"calls","metadata":{"unresolvedName":"handleCancel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"symbol-name:handleSave","kind":"calls","metadata":{"unresolvedName":"handleSave"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleEdit","kind":"calls","metadata":{"unresolvedName":"handleEdit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","to":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleCancel","kind":"calls","metadata":{"unresolvedName":"handleCancel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx:handleKeyDown","to":"symbol-name:handleSave","kind":"calls","metadata":{"unresolvedName":"handleSave"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"symbol-name:setNewMount","kind":"calls","metadata":{"unresolvedName":"setNewMount"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"symbol-name:setEditingIndex","kind":"calls","metadata":{"unresolvedName":"setEditingIndex"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"external:mounts.filter","kind":"calls","metadata":{"unresolvedName":"mounts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"external:path.includes","kind":"calls","metadata":{"unresolvedName":"path.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"external:path.startsWith","kind":"calls","metadata":{"unresolvedName":"path.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"external:url.startsWith","kind":"calls","metadata":{"unresolvedName":"url.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"external:mounts.map","kind":"calls","metadata":{"unresolvedName":"mounts.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","kind":"calls","metadata":{"unresolvedName":"handleUpdate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","kind":"calls","metadata":{"unresolvedName":"handleRemove"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleAdd","to":"symbol-name:setNewMount","kind":"calls","metadata":{"unresolvedName":"setNewMount"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleUpdate","to":"symbol-name:setEditingIndex","kind":"calls","metadata":{"unresolvedName":"setEditingIndex"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleRemove","to":"external:mounts.filter","kind":"calls","metadata":{"unresolvedName":"mounts.filter"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","to":"external:path.includes","kind":"calls","metadata":{"unresolvedName":"path.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","to":"external:path.startsWith","kind":"calls","metadata":{"unresolvedName":"path.startsWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","to":"external:url.startsWith","kind":"calls","metadata":{"unresolvedName":"url.startsWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"symbol-name:setForm","kind":"calls","metadata":{"unresolvedName":"setForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"symbol-name:setErrors","kind":"calls","metadata":{"unresolvedName":"setErrors"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","kind":"calls","metadata":{"unresolvedName":"validateUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","kind":"calls","metadata":{"unresolvedName":"validatePath"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"external:Object.keys","kind":"calls","metadata":{"unresolvedName":"Object.keys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"symbol-name:onSave","kind":"calls","metadata":{"unresolvedName":"onSave"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:GitMountForm","to":"symbol-name:handleChange","kind":"calls","metadata":{"unresolvedName":"handleChange"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange","to":"symbol-name:setForm","kind":"calls","metadata":{"unresolvedName":"setForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleChange","to":"symbol-name:setErrors","kind":"calls","metadata":{"unresolvedName":"setErrors"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validateUrl","kind":"calls","metadata":{"unresolvedName":"validateUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:validatePath","kind":"calls","metadata":{"unresolvedName":"validatePath"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"external:Object.keys","kind":"calls","metadata":{"unresolvedName":"Object.keys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"symbol-name:setErrors","kind":"calls","metadata":{"unresolvedName":"setErrors"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"symbol-name:onSave","kind":"calls","metadata":{"unresolvedName":"onSave"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx:handleSubmit","to":"symbol-name:setForm","kind":"calls","metadata":{"unresolvedName":"setForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"calls","metadata":{"unresolvedName":"getRepositoryStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","kind":"calls","metadata":{"unresolvedName":"fetchRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","kind":"calls","metadata":{"unresolvedName":"pullRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","kind":"calls","metadata":{"unresolvedName":"pushRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","kind":"calls","metadata":{"unresolvedName":"checkoutBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:onBranchChange","kind":"calls","metadata":{"unresolvedName":"onBranchChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"external:newBranchName.trim","kind":"calls","metadata":{"unresolvedName":"newBranchName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","kind":"calls","metadata":{"unresolvedName":"createBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setShowNewBranch","kind":"calls","metadata":{"unresolvedName":"setShowNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setNewBranchName","kind":"calls","metadata":{"unresolvedName":"setNewBranchName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setNewBranchBase","kind":"calls","metadata":{"unresolvedName":"setNewBranchBase"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","kind":"calls","metadata":{"unresolvedName":"handleCheckout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"external:branches.map","kind":"calls","metadata":{"unresolvedName":"branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:GitToolbar","to":"symbol-name:setShowMergeDialog","kind":"calls","metadata":{"unresolvedName":"setShowMergeDialog"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"calls","metadata":{"unresolvedName":"getRepositoryStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:fetchRepository","kind":"calls","metadata":{"unresolvedName":"fetchRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleFetch","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pullRepository","kind":"calls","metadata":{"unresolvedName":"pullRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePull","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:pushRepository","kind":"calls","metadata":{"unresolvedName":"pushRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handlePush","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:checkoutBranch","kind":"calls","metadata":{"unresolvedName":"checkoutBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","to":"symbol-name:onBranchChange","kind":"calls","metadata":{"unresolvedName":"onBranchChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCheckout","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"external:newBranchName.trim","kind":"calls","metadata":{"unresolvedName":"newBranchName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createBranch","kind":"calls","metadata":{"unresolvedName":"createBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:setShowNewBranch","kind":"calls","metadata":{"unresolvedName":"setShowNewBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:setNewBranchName","kind":"calls","metadata":{"unresolvedName":"setNewBranchName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:setNewBranchBase","kind":"calls","metadata":{"unresolvedName":"setNewBranchBase"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:handleCreateBranch","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:loadStatus","kind":"calls","metadata":{"unresolvedName":"loadStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","to":"external:@phosphor-icons/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/icon.tsx:Icon","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/icon.tsx:Icon","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","kind":"calls","metadata":{"unresolvedName":"listInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setInstances","kind":"calls","metadata":{"unresolvedName":"setInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:instances.filter","kind":"calls","metadata":{"unresolvedName":"instances.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:i.url?.startsWith","kind":"calls","metadata":{"unresolvedName":"i.url?.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setHealthStatus","kind":"calls","metadata":{"unresolvedName":"setHealthStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setShowCreate","kind":"calls","metadata":{"unresolvedName":"setShowCreate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setConfigProfiles","kind":"calls","metadata":{"unresolvedName":"setConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"calls","metadata":{"unresolvedName":"stopInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:setStopConfirmId","kind":"calls","metadata":{"unresolvedName":"setStopConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"calls","metadata":{"unresolvedName":"restartInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:confirm","kind":"calls","metadata":{"unresolvedName":"confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"calls","metadata":{"unresolvedName":"deleteInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:prev.filter","kind":"calls","metadata":{"unresolvedName":"prev.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"calls","metadata":{"unresolvedName":"recreateInstanceTunnel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:instance.url?.startsWith","kind":"calls","metadata":{"unresolvedName":"instance.url?.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:instances.map","kind":"calls","metadata":{"unresolvedName":"instances.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:getStatusColor","kind":"calls","metadata":{"unresolvedName":"getStatusColor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy","kind":"calls","metadata":{"unresolvedName":"isTunnelUnhealthy"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:configProfiles.find","kind":"calls","metadata":{"unresolvedName":"configProfiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:instance.tool_type_interfaces.includes","kind":"calls","metadata":{"unresolvedName":"instance.tool_type_interfaces.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:instance.url.startsWith","kind":"calls","metadata":{"unresolvedName":"instance.url.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","kind":"calls","metadata":{"unresolvedName":"handleRecreateTunnel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:configProfiles.map","kind":"calls","metadata":{"unresolvedName":"configProfiles.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","kind":"calls","metadata":{"unresolvedName":"handleStart"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"external:toolTypes.find","kind":"calls","metadata":{"unresolvedName":"toolTypes.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:loadConfigProfiles","kind":"calls","metadata":{"unresolvedName":"loadConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:handleStop","kind":"calls","metadata":{"unresolvedName":"handleStop"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","kind":"calls","metadata":{"unresolvedName":"handleRestart"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:InstanceList","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:listInstances","kind":"calls","metadata":{"unresolvedName":"listInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setInstances","kind":"calls","metadata":{"unresolvedName":"setInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"external:instances.filter","kind":"calls","metadata":{"unresolvedName":"instances.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"external:i.url?.startsWith","kind":"calls","metadata":{"unresolvedName":"i.url?.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setHealthStatus","kind":"calls","metadata":{"unresolvedName":"setHealthStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","to":"symbol-name:setHealthStatus","kind":"calls","metadata":{"unresolvedName":"setHealthStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:checkHealth","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess","to":"symbol-name:setShowCreate","kind":"calls","metadata":{"unresolvedName":"setShowCreate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleCreateSuccess","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setConfigProfiles","kind":"calls","metadata":{"unresolvedName":"setConfigProfiles"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStart","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"calls","metadata":{"unresolvedName":"stopInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","to":"symbol-name:setStopConfirmId","kind":"calls","metadata":{"unresolvedName":"setStopConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleStop","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:restartInstance","kind":"calls","metadata":{"unresolvedName":"restartInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRestart","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"symbol-name:confirm","kind":"calls","metadata":{"unresolvedName":"confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"calls","metadata":{"unresolvedName":"deleteInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"symbol-name:setInstances","kind":"calls","metadata":{"unresolvedName":"setInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"external:prev.filter","kind":"calls","metadata":{"unresolvedName":"prev.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleDelete","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","to":"symbol-name:setBusyInstanceId","kind":"calls","metadata":{"unresolvedName":"setBusyInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"calls","metadata":{"unresolvedName":"recreateInstanceTunnel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","to":"symbol-name:loadInstances","kind":"calls","metadata":{"unresolvedName":"loadInstances"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:handleRecreateTunnel","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:getStatusColor","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:getStatusColor","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:isTunnelUnhealthy","to":"external:instance.url?.startsWith","kind":"calls","metadata":{"unresolvedName":"instance.url?.startsWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"external:toolTypes.find","kind":"calls","metadata":{"unresolvedName":"toolTypes.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:loadConfigProfiles","kind":"calls","metadata":{"unresolvedName":"loadConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"external:toolTypes.find","kind":"calls","metadata":{"unresolvedName":"toolTypes.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:loadConfigProfiles","kind":"calls","metadata":{"unresolvedName":"loadConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setProfileSelectInstanceId","kind":"calls","metadata":{"unresolvedName":"setProfileSelectInstanceId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx:","to":"symbol-name:setSelectedProfileForAction","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileForAction"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setBaseImage","kind":"calls","metadata":{"unresolvedName":"setBaseImage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setBaseDefinitionId","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setAptPackages","kind":"calls","metadata":{"unresolvedName":"setAptPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:((pkgs.apt as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.apt as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setNpmPackages","kind":"calls","metadata":{"unresolvedName":"setNpmPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:((pkgs.npm_global as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.npm_global as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setPipPackages","kind":"calls","metadata":{"unresolvedName":"setPipPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:((pkgs.pip as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.pip as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setNodeVersion","kind":"calls","metadata":{"unresolvedName":"setNodeVersion"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setUserName","kind":"calls","metadata":{"unresolvedName":"setUserName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setUserUid","kind":"calls","metadata":{"unresolvedName":"setUserUid"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setUserGid","kind":"calls","metadata":{"unresolvedName":"setUserGid"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setEnvVars","kind":"calls","metadata":{"unresolvedName":"setEnvVars"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:Object.entries(env).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(env).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:Object.entries","kind":"calls","metadata":{"unresolvedName":"Object.entries"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setBuildScripts","kind":"calls","metadata":{"unresolvedName":"setBuildScripts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setStartupScripts","kind":"calls","metadata":{"unresolvedName":"setStartupScripts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setMounts","kind":"calls","metadata":{"unresolvedName":"setMounts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setCommand","kind":"calls","metadata":{"unresolvedName":"setCommand"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setWorkingDir","kind":"calls","metadata":{"unresolvedName":"setWorkingDir"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setStdinOpen","kind":"calls","metadata":{"unresolvedName":"setStdinOpen"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setTty","kind":"calls","metadata":{"unresolvedName":"setTty"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:aptPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"aptPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:aptPackages.map","kind":"calls","metadata":{"unresolvedName":"aptPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:npmPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"npmPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:npmPackages.map","kind":"calls","metadata":{"unresolvedName":"npmPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:pipPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"pipPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:pipPackages.map","kind":"calls","metadata":{"unresolvedName":"pipPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:envVars.forEach","kind":"calls","metadata":{"unresolvedName":"envVars.forEach"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:buildScripts.filter","kind":"calls","metadata":{"unresolvedName":"buildScripts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:startupScripts.filter","kind":"calls","metadata":{"unresolvedName":"startupScripts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:mounts.filter","kind":"calls","metadata":{"unresolvedName":"mounts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:command.filter","kind":"calls","metadata":{"unresolvedName":"command.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:buildManifest","kind":"calls","metadata":{"unresolvedName":"buildManifest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setPreviewError","kind":"calls","metadata":{"unresolvedName":"setPreviewError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setPreviewLoading","kind":"calls","metadata":{"unresolvedName":"setPreviewLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","kind":"calls","metadata":{"unresolvedName":"compileToolDefinition"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:setPreview","kind":"calls","metadata":{"unresolvedName":"setPreview"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:aptPackages.filter","kind":"calls","metadata":{"unresolvedName":"aptPackages.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:npmPackages.filter","kind":"calls","metadata":{"unresolvedName":"npmPackages.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:pipPackages.filter","kind":"calls","metadata":{"unresolvedName":"pipPackages.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:envVars.filter","kind":"calls","metadata":{"unresolvedName":"envVars.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:baseDefinitions.map","kind":"calls","metadata":{"unresolvedName":"baseDefinitions.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage","kind":"calls","metadata":{"unresolvedName":"updateAptPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:removeAptPackage","kind":"calls","metadata":{"unresolvedName":"removeAptPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage","kind":"calls","metadata":{"unresolvedName":"updateNpmPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:removeNpmPackage","kind":"calls","metadata":{"unresolvedName":"removeNpmPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage","kind":"calls","metadata":{"unresolvedName":"updatePipPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:removePipPackage","kind":"calls","metadata":{"unresolvedName":"removePipPackage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:envVars.map","kind":"calls","metadata":{"unresolvedName":"envVars.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:updateEnvVar","kind":"calls","metadata":{"unresolvedName":"updateEnvVar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","kind":"calls","metadata":{"unresolvedName":"removeEnvVar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:buildScripts.map","kind":"calls","metadata":{"unresolvedName":"buildScripts.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript","kind":"calls","metadata":{"unresolvedName":"updateBuildScript"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:removeBuildScript","kind":"calls","metadata":{"unresolvedName":"removeBuildScript"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:startupScripts.map","kind":"calls","metadata":{"unresolvedName":"startupScripts.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript","kind":"calls","metadata":{"unresolvedName":"updateStartupScript"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:removeStartupScript","kind":"calls","metadata":{"unresolvedName":"removeStartupScript"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:mounts.map","kind":"calls","metadata":{"unresolvedName":"mounts.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"symbol-name:updateMount","kind":"calls","metadata":{"unresolvedName":"updateMount"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","kind":"calls","metadata":{"unresolvedName":"removeMount"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:command.join","kind":"calls","metadata":{"unresolvedName":"command.join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:ManifestEditor","to":"external:e.target.value.split","kind":"calls","metadata":{"unresolvedName":"e.target.value.split"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseImage","kind":"calls","metadata":{"unresolvedName":"setBaseImage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseDefinitionId","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setAptPackages","kind":"calls","metadata":{"unresolvedName":"setAptPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:((pkgs.apt as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.apt as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setNpmPackages","kind":"calls","metadata":{"unresolvedName":"setNpmPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:((pkgs.npm_global as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.npm_global as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setPipPackages","kind":"calls","metadata":{"unresolvedName":"setPipPackages"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:((pkgs.pip as string[]) || []).map","kind":"calls","metadata":{"unresolvedName":"((pkgs.pip as string[]) || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setNodeVersion","kind":"calls","metadata":{"unresolvedName":"setNodeVersion"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setUserName","kind":"calls","metadata":{"unresolvedName":"setUserName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setUserUid","kind":"calls","metadata":{"unresolvedName":"setUserUid"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setUserGid","kind":"calls","metadata":{"unresolvedName":"setUserGid"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setEnvVars","kind":"calls","metadata":{"unresolvedName":"setEnvVars"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:Object.entries(env).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(env).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:Object.entries","kind":"calls","metadata":{"unresolvedName":"Object.entries"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBuildScripts","kind":"calls","metadata":{"unresolvedName":"setBuildScripts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setStartupScripts","kind":"calls","metadata":{"unresolvedName":"setStartupScripts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setMounts","kind":"calls","metadata":{"unresolvedName":"setMounts"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setCommand","kind":"calls","metadata":{"unresolvedName":"setCommand"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setWorkingDir","kind":"calls","metadata":{"unresolvedName":"setWorkingDir"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setStdinOpen","kind":"calls","metadata":{"unresolvedName":"setStdinOpen"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setTty","kind":"calls","metadata":{"unresolvedName":"setTty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:aptPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"aptPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:aptPackages.map","kind":"calls","metadata":{"unresolvedName":"aptPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:npmPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"npmPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:npmPackages.map","kind":"calls","metadata":{"unresolvedName":"npmPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:pipPackages.map((p) => p.name).filter","kind":"calls","metadata":{"unresolvedName":"pipPackages.map((p) => p.name).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:pipPackages.map","kind":"calls","metadata":{"unresolvedName":"pipPackages.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:envVars.forEach","kind":"calls","metadata":{"unresolvedName":"envVars.forEach"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:buildScripts.filter","kind":"calls","metadata":{"unresolvedName":"buildScripts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:startupScripts.filter","kind":"calls","metadata":{"unresolvedName":"startupScripts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:mounts.filter","kind":"calls","metadata":{"unresolvedName":"mounts.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"external:command.filter","kind":"calls","metadata":{"unresolvedName":"command.filter"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:buildManifest","kind":"calls","metadata":{"unresolvedName":"buildManifest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:onChange","kind":"calls","metadata":{"unresolvedName":"onChange"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","to":"symbol-name:setPreviewError","kind":"calls","metadata":{"unresolvedName":"setPreviewError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","to":"symbol-name:setPreviewLoading","kind":"calls","metadata":{"unresolvedName":"setPreviewLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:compileToolDefinition","kind":"calls","metadata":{"unresolvedName":"compileToolDefinition"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","to":"symbol-name:setPreview","kind":"calls","metadata":{"unresolvedName":"setPreview"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:handlePreview","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateAptPackage","to":"symbol-name:setAptPackages","kind":"calls","metadata":{"unresolvedName":"setAptPackages"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateNpmPackage","to":"symbol-name:setNpmPackages","kind":"calls","metadata":{"unresolvedName":"setNpmPackages"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updatePipPackage","to":"symbol-name:setPipPackages","kind":"calls","metadata":{"unresolvedName":"setPipPackages"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateEnvVar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateEnvVar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateEnvVar","to":"symbol-name:setEnvVars","kind":"calls","metadata":{"unresolvedName":"setEnvVars"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateBuildScript","to":"symbol-name:setBuildScripts","kind":"calls","metadata":{"unresolvedName":"setBuildScripts"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateStartupScript","to":"symbol-name:setStartupScripts","kind":"calls","metadata":{"unresolvedName":"setStartupScripts"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateMount","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateMount","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:updateMount","to":"symbol-name:setMounts","kind":"calls","metadata":{"unresolvedName":"setMounts"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseDefinitionId","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseImage","kind":"calls","metadata":{"unresolvedName":"setBaseImage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseImage","kind":"calls","metadata":{"unresolvedName":"setBaseImage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx:","to":"symbol-name:setBaseDefinitionId","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitionId"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"external:branches.filter","kind":"calls","metadata":{"unresolvedName":"branches.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setSuccess","kind":"calls","metadata":{"unresolvedName":"setSuccess"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","kind":"calls","metadata":{"unresolvedName":"mergeBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:onMerge","kind":"calls","metadata":{"unresolvedName":"onMerge"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setSourceBranch","kind":"calls","metadata":{"unresolvedName":"setSourceBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"external:availableBranches.map","kind":"calls","metadata":{"unresolvedName":"availableBranches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:MergeDialog","to":"symbol-name:setCommitMessage","kind":"calls","metadata":{"unresolvedName":"setCommitMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:setSuccess","kind":"calls","metadata":{"unresolvedName":"setSuccess"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:mergeBranches","kind":"calls","metadata":{"unresolvedName":"mergeBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:onMerge","kind":"calls","metadata":{"unresolvedName":"onMerge"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:handleMerge","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:","to":"symbol-name:onMerge","kind":"calls","metadata":{"unresolvedName":"onMerge"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/merge-dialog.tsx:","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"symbol-name:useRef","kind":"calls","metadata":{"unresolvedName":"useRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"external:document.addEventListener","kind":"calls","metadata":{"unresolvedName":"document.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"external:document.removeEventListener","kind":"calls","metadata":{"unresolvedName":"document.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"external:actions.map","kind":"calls","metadata":{"unresolvedName":"actions.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:MobileActionSheet","to":"external:action.onClick","kind":"calls","metadata":{"unresolvedName":"action.onClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","to":"external:document.addEventListener","kind":"calls","metadata":{"unresolvedName":"document.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","to":"external:document.removeEventListener","kind":"calls","metadata":{"unresolvedName":"document.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:handleEscape","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:handleEscape","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:handleEscape","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","to":"external:action.onClick","kind":"calls","metadata":{"unresolvedName":"action.onClick"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx:","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","to":"external:fields.map","kind":"calls","metadata":{"unresolvedName":"fields.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:MobileDetailView","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","kind":"calls","metadata":{"unresolvedName":"renderValue"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx:renderValue","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"external:fields?.forEach","kind":"calls","metadata":{"unresolvedName":"fields?.forEach"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:onSave","kind":"calls","metadata":{"unresolvedName":"onSave"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"external:fields?.map","kind":"calls","metadata":{"unresolvedName":"fields?.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:handleChange","kind":"calls","metadata":{"unresolvedName":"handleChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"external:field.options?.map","kind":"calls","metadata":{"unresolvedName":"field.options?.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:Boolean","kind":"calls","metadata":{"unresolvedName":"Boolean"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:MobileEditView","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","to":"external:fields?.forEach","kind":"calls","metadata":{"unresolvedName":"fields?.forEach"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleChange","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx:handleSubmit","to":"symbol-name:onSave","kind":"calls","metadata":{"unresolvedName":"onSave"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx:MobileFAB","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx:MobileFAB","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","to":"symbol-name:onSearch","kind":"calls","metadata":{"unresolvedName":"onSearch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","to":"external:items.map","kind":"calls","metadata":{"unresolvedName":"items.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx:MobileListView","to":"symbol-name:onItemClick","kind":"calls","metadata":{"unresolvedName":"onItemClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","to":"symbol-name:setToolsSheetOpen","kind":"calls","metadata":{"unresolvedName":"setToolsSheetOpen"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","to":"external:MOBILE_NAV_ITEMS.map","kind":"calls","metadata":{"unresolvedName":"MOBILE_NAV_ITEMS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:MobileNav","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","kind":"calls","metadata":{"unresolvedName":"handleNavClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","to":"symbol-name:setToolsSheetOpen","kind":"calls","metadata":{"unresolvedName":"setToolsSheetOpen"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-nav.tsx:handleNavClick","kind":"calls","metadata":{"unresolvedName":"handleNavClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-page-header.tsx:MobilePageHeader","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:MobileTerminalHeader","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:MobileTerminalHeader","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx:MobileTerminalHeader","to":"symbol-name:onFontSizeChange","kind":"calls","metadata":{"unresolvedName":"onFontSizeChange"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-header.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","kind":"calls","metadata":{"unresolvedName":"useVirtualKeyboard"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","kind":"calls","metadata":{"unresolvedName":"useAutoHide"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"external:headerAutoHide.toggle","kind":"calls","metadata":{"unresolvedName":"headerAutoHide.toggle"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"symbol-name:setTerminalRef","kind":"calls","metadata":{"unresolvedName":"setTerminalRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"external:terminalRef?.sendData","kind":"calls","metadata":{"unresolvedName":"terminalRef?.sendData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"external:terminalRef?.changeFontSize","kind":"calls","metadata":{"unresolvedName":"terminalRef?.changeFontSize"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"symbol-name:setShowPanel","kind":"calls","metadata":{"unresolvedName":"setShowPanel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:MobileTerminalWrapper","to":"external:terminalRef?.focusInput","kind":"calls","metadata":{"unresolvedName":"terminalRef?.focusInput"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","to":"external:headerAutoHide.toggle","kind":"calls","metadata":{"unresolvedName":"headerAutoHide.toggle"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","to":"symbol-name:setTerminalRef","kind":"calls","metadata":{"unresolvedName":"setTerminalRef"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx:","to":"external:terminalRef?.sendData","kind":"calls","metadata":{"unresolvedName":"terminalRef?.sendData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"external:@testing-library/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:mockUseAuth.mockReturnValue","kind":"calls","metadata":{"unresolvedName":"mockUseAuth.mockReturnValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:expect(screen.getByText(\"Checking session...\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Checking session...\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:expect(screen.getByText(\"login page\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"login page\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:mockUseAuth.mockReturnValue","kind":"calls","metadata":{"unresolvedName":"mockUseAuth.mockReturnValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:expect(screen.getByText(\"Checking session...\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Checking session...\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:mockUseAuth.mockReturnValue","kind":"calls","metadata":{"unresolvedName":"mockUseAuth.mockReturnValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:expect(screen.getByText(\"login page\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"login page\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"calls","metadata":{"unresolvedName":"useAuth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx:ProtectedRoute","to":"symbol-name:encodeURIComponent","kind":"calls","metadata":{"unresolvedName":"encodeURIComponent"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"external:@testing-library/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.importActual","kind":"calls","metadata":{"unresolvedName":"vi.importActual"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:cleanup","kind":"calls","metadata":{"unresolvedName":"cleanup"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.restoreAllMocks","kind":"calls","metadata":{"unresolvedName":"vi.restoreAllMocks"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"createRepository\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(gitRepositoriesApi, \"listRepositories\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:expect(screen.getByText(\"Main Repo\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Main Repo\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:loadRepositories","kind":"calls","metadata":{"unresolvedName":"loadRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"calls","metadata":{"unresolvedName":"deleteRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"external:current.filter","kind":"calls","metadata":{"unresolvedName":"current.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:setShowCreate","kind":"calls","metadata":{"unresolvedName":"setShowCreate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"external:repositories.map","kind":"calls","metadata":{"unresolvedName":"repositories.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:RepositoriesSettingsTab","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:","to":"symbol-name:loadRepositories","kind":"calls","metadata":{"unresolvedName":"loadRepositories"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"calls","metadata":{"unresolvedName":"deleteRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","to":"external:current.filter","kind":"calls","metadata":{"unresolvedName":"current.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx:handleDelete","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:useRef","kind":"calls","metadata":{"unresolvedName":"useRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setUrlValidation","kind":"calls","metadata":{"unresolvedName":"setUrlValidation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:advancedUrl.trim","kind":"calls","metadata":{"unresolvedName":"advancedUrl.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"calls","metadata":{"unresolvedName":"parseGitUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setCreateMode","kind":"calls","metadata":{"unresolvedName":"setCreateMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setFormName","kind":"calls","metadata":{"unresolvedName":"setFormName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setOwner","kind":"calls","metadata":{"unresolvedName":"setOwner"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setRepoName","kind":"calls","metadata":{"unresolvedName":"setRepoName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setAdvancedUrl","kind":"calls","metadata":{"unresolvedName":"setAdvancedUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setUseAdvancedUrl","kind":"calls","metadata":{"unresolvedName":"setUseAdvancedUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:setSelectedSshKey","kind":"calls","metadata":{"unresolvedName":"setSelectedSshKey"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:event.preventDefault","kind":"calls","metadata":{"unresolvedName":"event.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:formName.trim","kind":"calls","metadata":{"unresolvedName":"formName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:owner.trim","kind":"calls","metadata":{"unresolvedName":"owner.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:repoName.trim","kind":"calls","metadata":{"unresolvedName":"repoName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","kind":"calls","metadata":{"unresolvedName":"createRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","kind":"calls","metadata":{"unresolvedName":"handleClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"symbol-name:onCreated","kind":"calls","metadata":{"unresolvedName":"onCreated"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"external:sshKeys.map","kind":"calls","metadata":{"unresolvedName":"sshKeys.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:RepositoryCreateDialog","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:getUrlInputClass","kind":"calls","metadata":{"unresolvedName":"getUrlInputClass"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:listSSHKeys","kind":"calls","metadata":{"unresolvedName":"listSSHKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:loadKeys","to":"symbol-name:setSshKeys","kind":"calls","metadata":{"unresolvedName":"setSshKeys"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:setUrlValidation","kind":"calls","metadata":{"unresolvedName":"setUrlValidation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"external:advancedUrl.trim","kind":"calls","metadata":{"unresolvedName":"advancedUrl.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"calls","metadata":{"unresolvedName":"parseGitUrl"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:parseGitUrl","kind":"calls","metadata":{"unresolvedName":"parseGitUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"external:advancedUrl.trim","kind":"calls","metadata":{"unresolvedName":"advancedUrl.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:setUrlValidation","kind":"calls","metadata":{"unresolvedName":"setUrlValidation"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setCreateMode","kind":"calls","metadata":{"unresolvedName":"setCreateMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setFormName","kind":"calls","metadata":{"unresolvedName":"setFormName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setOwner","kind":"calls","metadata":{"unresolvedName":"setOwner"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setRepoName","kind":"calls","metadata":{"unresolvedName":"setRepoName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setAdvancedUrl","kind":"calls","metadata":{"unresolvedName":"setAdvancedUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setUseAdvancedUrl","kind":"calls","metadata":{"unresolvedName":"setUseAdvancedUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setUrlValidation","kind":"calls","metadata":{"unresolvedName":"setUrlValidation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:resetForm","to":"symbol-name:setSelectedSshKey","kind":"calls","metadata":{"unresolvedName":"setSelectedSshKey"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"external:event.preventDefault","kind":"calls","metadata":{"unresolvedName":"event.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"external:formName.trim","kind":"calls","metadata":{"unresolvedName":"formName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"external:advancedUrl.trim","kind":"calls","metadata":{"unresolvedName":"advancedUrl.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"external:owner.trim","kind":"calls","metadata":{"unresolvedName":"owner.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"external:repoName.trim","kind":"calls","metadata":{"unresolvedName":"repoName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:createRepository","kind":"calls","metadata":{"unresolvedName":"createRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleClose","kind":"calls","metadata":{"unresolvedName":"handleClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleSubmit","to":"symbol-name:onCreated","kind":"calls","metadata":{"unresolvedName":"onCreated"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","to":"symbol-name:setAdvancedUrl","kind":"calls","metadata":{"unresolvedName":"setAdvancedUrl"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","to":"symbol-name:setUrlValidation","kind":"calls","metadata":{"unresolvedName":"setUrlValidation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:handleUseSuggestedUrl","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:getUrlInputClass","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx:getUrlInputClass","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-action-sheet.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"external:session.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"session.tool_type_interfaces?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:setShowStopConfirm","kind":"calls","metadata":{"unresolvedName":"setShowStopConfirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:onStop","kind":"calls","metadata":{"unresolvedName":"onStop"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:setShowDeleteConfirm","kind":"calls","metadata":{"unresolvedName":"setShowDeleteConfirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:onDelete","kind":"calls","metadata":{"unresolvedName":"onDelete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"external:[\"running\", \"building\", \"starting\", \"probing\", \"pending\", \"unhealthy\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"building\", \"starting\", \"probing\", \"pending\", \"unhealthy\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"external:new Date(session.created_at).toLocaleString","kind":"calls","metadata":{"unresolvedName":"new Date(session.created_at).toLocaleString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:onOpen","kind":"calls","metadata":{"unresolvedName":"onOpen"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:setShowActionSheet","kind":"calls","metadata":{"unresolvedName":"setShowActionSheet"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:onStart","kind":"calls","metadata":{"unresolvedName":"onStart"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:SessionCard","to":"symbol-name:onRecreateTunnel","kind":"calls","metadata":{"unresolvedName":"onRecreateTunnel"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop","to":"symbol-name:setShowStopConfirm","kind":"calls","metadata":{"unresolvedName":"setShowStopConfirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleStop","to":"symbol-name:onStop","kind":"calls","metadata":{"unresolvedName":"onStop"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete","to":"symbol-name:setShowDeleteConfirm","kind":"calls","metadata":{"unresolvedName":"setShowDeleteConfirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx:handleDelete","to":"symbol-name:onDelete","kind":"calls","metadata":{"unresolvedName":"onDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:activeStatuses.includes","kind":"calls","metadata":{"unresolvedName":"activeStatuses.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:sessions\n .filter((s) => recentStatuses.includes(s.status))\n .slice","kind":"calls","metadata":{"unresolvedName":"sessions\n .filter((s) => recentStatuses.includes(s.status))\n .slice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:sessions\n .filter","kind":"calls","metadata":{"unresolvedName":"sessions\n .filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:recentStatuses.includes","kind":"calls","metadata":{"unresolvedName":"recentStatuses.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:sessions.map","kind":"calls","metadata":{"unresolvedName":"sessions.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:activeSessions.map","kind":"calls","metadata":{"unresolvedName":"activeSessions.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx:SessionList","to":"external:recentSessions.map","kind":"calls","metadata":{"unresolvedName":"recentSessions.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","to":"external:tabs.map","kind":"calls","metadata":{"unresolvedName":"tabs.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx:SettingsTabLayout","to":"external:location.pathname.includes","kind":"calls","metadata":{"unresolvedName":"location.pathname.includes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"calls","metadata":{"unresolvedName":"getSequenceWithModifier"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:onSend","kind":"calls","metadata":{"unresolvedName":"onSend"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"external:EXPANDED_KEYS.map","kind":"calls","metadata":{"unresolvedName":"EXPANDED_KEYS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"symbol-name:handlePointerDown","kind":"calls","metadata":{"unresolvedName":"handlePointerDown"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:SpecialKeysPanel","to":"external:F_KEYS.map","kind":"calls","metadata":{"unresolvedName":"F_KEYS.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"calls","metadata":{"unresolvedName":"getSequenceWithModifier"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"symbol-name:onSend","kind":"calls","metadata":{"unresolvedName":"onSend"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handlePointerDown","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:handleOverlayPointerDown","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-panel.tsx:","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"calls","metadata":{"unresolvedName":"getSequenceWithModifier"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:onSend","kind":"calls","metadata":{"unresolvedName":"onSend"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:onMoreClick","kind":"calls","metadata":{"unresolvedName":"onMoreClick"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"external:PRIMARY_KEYS.map","kind":"calls","metadata":{"unresolvedName":"PRIMARY_KEYS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:SpecialKeysStrip","to":"symbol-name:handlePointerDown","kind":"calls","metadata":{"unresolvedName":"handlePointerDown"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"calls","metadata":{"unresolvedName":"getSequenceWithModifier"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handlePointerDown","to":"symbol-name:onSend","kind":"calls","metadata":{"unresolvedName":"onSend"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","to":"symbol-name:onMoreClick","kind":"calls","metadata":{"unresolvedName":"onMoreClick"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:handleMorePointerDown","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/special-keys-strip.tsx:","to":"symbol-name:onKeepFocus","kind":"calls","metadata":{"unresolvedName":"onKeepFocus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:setHighlighted","kind":"calls","metadata":{"unresolvedName":"setHighlighted"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"calls","metadata":{"unresolvedName":"highlightCode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:highlight","kind":"calls","metadata":{"unresolvedName":"highlight"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:setCopied","kind":"calls","metadata":{"unresolvedName":"setCopied"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"external:code.split","kind":"calls","metadata":{"unresolvedName":"code.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:SyntaxHighlighter","to":"external:lines.map","kind":"calls","metadata":{"unresolvedName":"lines.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","to":"symbol-name:setHighlighted","kind":"calls","metadata":{"unresolvedName":"setHighlighted"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"calls","metadata":{"unresolvedName":"highlightCode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:","to":"symbol-name:highlight","kind":"calls","metadata":{"unresolvedName":"highlight"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"calls","metadata":{"unresolvedName":"loadLanguage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","to":"symbol-name:setHighlighted","kind":"calls","metadata":{"unresolvedName":"setHighlighted"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:highlight","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"calls","metadata":{"unresolvedName":"highlightCode"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","to":"symbol-name:setCopied","kind":"calls","metadata":{"unresolvedName":"setCopied"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/syntax-highlighter.tsx:handleCopy","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"external:xterm","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"external:xterm-addon-fit","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"external:xterm-addon-web-links","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"external:xterm/css/xterm.css","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:useRef","kind":"calls","metadata":{"unresolvedName":"useRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:localStorage.getItem","kind":"calls","metadata":{"unresolvedName":"localStorage.getItem"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:Math.max","kind":"calls","metadata":{"unresolvedName":"Math.max"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:Math.min","kind":"calls","metadata":{"unresolvedName":"Math.min"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:apiUrl.replace(/^https?:\\/\\//, \"\").replace","kind":"calls","metadata":{"unresolvedName":"apiUrl.replace(/^https?:\\/\\//, \"\").replace"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:apiUrl.replace","kind":"calls","metadata":{"unresolvedName":"apiUrl.replace"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:ws.send","kind":"calls","metadata":{"unresolvedName":"ws.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:window.setInterval","kind":"calls","metadata":{"unresolvedName":"window.setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:event.data.arrayBuffer().then","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer().then"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:event.data.arrayBuffer","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current?.write","kind":"calls","metadata":{"unresolvedName":"termRef.current?.write"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current.clear","kind":"calls","metadata":{"unresolvedName":"termRef.current.clear"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:Math.pow","kind":"calls","metadata":{"unresolvedName":"Math.pow"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:calculateFontSize","kind":"calls","metadata":{"unresolvedName":"calculateFontSize"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:term.loadAddon","kind":"calls","metadata":{"unresolvedName":"term.loadAddon"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current.refresh","kind":"calls","metadata":{"unresolvedName":"termRef.current.refresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:term.open","kind":"calls","metadata":{"unresolvedName":"term.open"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.fonts.ready.then","kind":"calls","metadata":{"unresolvedName":"document.fonts.ready.then"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:term.onData","kind":"calls","metadata":{"unresolvedName":"term.onData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"calls","metadata":{"unresolvedName":"applyModifierToChar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:resizeObserver.observe","kind":"calls","metadata":{"unresolvedName":"resizeObserver.observe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current?.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current?.focus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:handleFontSizeChangeRef.current","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:onTerminalReadyRef.current","kind":"calls","metadata":{"unresolvedName":"onTerminalReadyRef.current"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.addEventListener","kind":"calls","metadata":{"unresolvedName":"document.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:resizeObserver.disconnect","kind":"calls","metadata":{"unresolvedName":"resizeObserver.disconnect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.removeEventListener","kind":"calls","metadata":{"unresolvedName":"document.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:term.dispose","kind":"calls","metadata":{"unresolvedName":"term.dispose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:onTerminalReady","kind":"calls","metadata":{"unresolvedName":"onTerminalReady"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:setFontSize","kind":"calls","metadata":{"unresolvedName":"setFontSize"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:localStorage.setItem","kind":"calls","metadata":{"unresolvedName":"localStorage.setItem"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:newSize.toString","kind":"calls","metadata":{"unresolvedName":"newSize.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current.getSelection","kind":"calls","metadata":{"unresolvedName":"termRef.current.getSelection"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.createElement","kind":"calls","metadata":{"unresolvedName":"document.createElement"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.body.appendChild","kind":"calls","metadata":{"unresolvedName":"document.body.appendChild"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:textarea.select","kind":"calls","metadata":{"unresolvedName":"textarea.select"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.execCommand","kind":"calls","metadata":{"unresolvedName":"document.execCommand"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:document.body.removeChild","kind":"calls","metadata":{"unresolvedName":"document.body.removeChild"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:navigator.clipboard.readText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.readText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"external:termRef.current.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current.focus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:TerminalComponent","to":"symbol-name:setShowResetConfirm","kind":"calls","metadata":{"unresolvedName":"setShowResetConfirm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:localStorage.getItem","kind":"calls","metadata":{"unresolvedName":"localStorage.getItem"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Math.max","kind":"calls","metadata":{"unresolvedName":"Math.max"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Math.min","kind":"calls","metadata":{"unresolvedName":"Math.min"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:apiUrl.replace(/^https?:\\/\\//, \"\").replace","kind":"calls","metadata":{"unresolvedName":"apiUrl.replace(/^https?:\\/\\//, \"\").replace"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:apiUrl.replace","kind":"calls","metadata":{"unresolvedName":"apiUrl.replace"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.send","kind":"calls","metadata":{"unresolvedName":"ws.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.setInterval","kind":"calls","metadata":{"unresolvedName":"window.setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:event.data.arrayBuffer().then","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer().then"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:event.data.arrayBuffer","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current?.write","kind":"calls","metadata":{"unresolvedName":"termRef.current?.write"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current.clear","kind":"calls","metadata":{"unresolvedName":"termRef.current.clear"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Math.pow","kind":"calls","metadata":{"unresolvedName":"Math.pow"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.send","kind":"calls","metadata":{"unresolvedName":"ws.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.setInterval","kind":"calls","metadata":{"unresolvedName":"window.setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:event.data.arrayBuffer().then","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer().then"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:event.data.arrayBuffer","kind":"calls","metadata":{"unresolvedName":"event.data.arrayBuffer"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current?.write","kind":"calls","metadata":{"unresolvedName":"termRef.current?.write"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current.clear","kind":"calls","metadata":{"unresolvedName":"termRef.current.clear"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.send","kind":"calls","metadata":{"unresolvedName":"ws.send"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current?.write","kind":"calls","metadata":{"unresolvedName":"termRef.current?.write"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:Math.pow","kind":"calls","metadata":{"unresolvedName":"Math.pow"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:calculateFontSize","kind":"calls","metadata":{"unresolvedName":"calculateFontSize"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:term.loadAddon","kind":"calls","metadata":{"unresolvedName":"term.loadAddon"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current.refresh","kind":"calls","metadata":{"unresolvedName":"termRef.current.refresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:term.open","kind":"calls","metadata":{"unresolvedName":"term.open"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:document.fonts.ready.then","kind":"calls","metadata":{"unresolvedName":"document.fonts.ready.then"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:term.onData","kind":"calls","metadata":{"unresolvedName":"term.onData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"calls","metadata":{"unresolvedName":"applyModifierToChar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:resizeObserver.observe","kind":"calls","metadata":{"unresolvedName":"resizeObserver.observe"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current?.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current?.focus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:handleFontSizeChangeRef.current","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:onTerminalReadyRef.current","kind":"calls","metadata":{"unresolvedName":"onTerminalReadyRef.current"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:document.addEventListener","kind":"calls","metadata":{"unresolvedName":"document.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:resizeObserver.disconnect","kind":"calls","metadata":{"unresolvedName":"resizeObserver.disconnect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:document.removeEventListener","kind":"calls","metadata":{"unresolvedName":"document.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:term.dispose","kind":"calls","metadata":{"unresolvedName":"term.dispose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","to":"external:termRef.current.refresh","kind":"calls","metadata":{"unresolvedName":"termRef.current.refresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:doInitialFit","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"calls","metadata":{"unresolvedName":"applyModifierToChar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:onModifierChange","kind":"calls","metadata":{"unresolvedName":"onModifierChange"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleWindowResize","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:fitTerminal","kind":"calls","metadata":{"unresolvedName":"fitTerminal"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","to":"external:currentWs.send","kind":"calls","metadata":{"unresolvedName":"currentWs.send"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","to":"external:termRef.current?.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current?.focus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","to":"external:handleFontSizeChangeRef.current","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleVisibilityChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleVisibilityChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleVisibilityChange","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:resizeObserver.disconnect","kind":"calls","metadata":{"unresolvedName":"resizeObserver.disconnect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:document.removeEventListener","kind":"calls","metadata":{"unresolvedName":"document.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:ws.close","kind":"calls","metadata":{"unresolvedName":"ws.close"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:window.clearInterval","kind":"calls","metadata":{"unresolvedName":"window.clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:term.dispose","kind":"calls","metadata":{"unresolvedName":"term.dispose"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:termRef.current?.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current?.focus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:handleFontSizeChangeRef.current","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:onTerminalReady","kind":"calls","metadata":{"unresolvedName":"onTerminalReady"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:sendData","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:focusInput","to":"external:termRef.current?.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current?.focus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:changeFontSize","to":"external:handleFontSizeChangeRef.current","kind":"calls","metadata":{"unresolvedName":"handleFontSizeChangeRef.current"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:Math.max","kind":"calls","metadata":{"unresolvedName":"Math.max"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:Math.min","kind":"calls","metadata":{"unresolvedName":"Math.min"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"symbol-name:setFontSize","kind":"calls","metadata":{"unresolvedName":"setFontSize"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:localStorage.setItem","kind":"calls","metadata":{"unresolvedName":"localStorage.setItem"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:newSize.toString","kind":"calls","metadata":{"unresolvedName":"newSize.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"symbol-name:requestAnimationFrame","kind":"calls","metadata":{"unresolvedName":"requestAnimationFrame"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleFontSizeChange","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:fitAddonRef.current.fit","kind":"calls","metadata":{"unresolvedName":"fitAddonRef.current.fit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:termRef.current.getSelection","kind":"calls","metadata":{"unresolvedName":"termRef.current.getSelection"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:document.createElement","kind":"calls","metadata":{"unresolvedName":"document.createElement"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:document.body.appendChild","kind":"calls","metadata":{"unresolvedName":"document.body.appendChild"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:textarea.select","kind":"calls","metadata":{"unresolvedName":"textarea.select"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:document.execCommand","kind":"calls","metadata":{"unresolvedName":"document.execCommand"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleCopy","to":"external:document.body.removeChild","kind":"calls","metadata":{"unresolvedName":"document.body.removeChild"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste","to":"external:navigator.clipboard.readText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.readText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handlePaste","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleTerminalClick","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleTerminalClick","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:handleTerminalClick","to":"external:termRef.current.focus","kind":"calls","metadata":{"unresolvedName":"termRef.current.focus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:setShowResetConfirm","kind":"calls","metadata":{"unresolvedName":"setShowResetConfirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:wsRef.current.send","kind":"calls","metadata":{"unresolvedName":"wsRef.current.send"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx:","to":"symbol-name:connectWebSocket","kind":"calls","metadata":{"unresolvedName":"connectWebSocket"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"external:TOOLS_ITEMS.map","kind":"calls","metadata":{"unresolvedName":"TOOLS_ITEMS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:ToolsBottomSheet","to":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","kind":"calls","metadata":{"unresolvedName":"handleSelect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","to":"symbol-name:onClose","kind":"calls","metadata":{"unresolvedName":"onClose"}},{"from":"/home/alex/projects/headquarter/apps/web/src/components/tools-bottom-sheet.tsx:handleSelect","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx:WorkspaceHeader","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","to":"/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx:WorkspaceHeader","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:fetcher","kind":"calls","metadata":{"unresolvedName":"fetcher"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:setData","kind":"calls","metadata":{"unresolvedName":"setData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:load","kind":"calls","metadata":{"unresolvedName":"load"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:fetcher","kind":"calls","metadata":{"unresolvedName":"fetcher"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:setData","kind":"calls","metadata":{"unresolvedName":"setData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:load","kind":"calls","metadata":{"unresolvedName":"load"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:","to":"symbol-name:load","kind":"calls","metadata":{"unresolvedName":"load"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:useRef","kind":"calls","metadata":{"unresolvedName":"useRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:setIsVisible","kind":"calls","metadata":{"unresolvedName":"setIsVisible"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:hide","kind":"calls","metadata":{"unresolvedName":"hide"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:show","kind":"calls","metadata":{"unresolvedName":"show"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:useAutoHide","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:setIsVisible","kind":"calls","metadata":{"unresolvedName":"setIsVisible"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"external:Date.now","kind":"calls","metadata":{"unresolvedName":"Date.now"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:setTimeout","kind":"calls","metadata":{"unresolvedName":"setTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:setIsVisible","kind":"calls","metadata":{"unresolvedName":"setIsVisible"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:setIsVisible","kind":"calls","metadata":{"unresolvedName":"setIsVisible"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:hide","kind":"calls","metadata":{"unresolvedName":"hide"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:show","kind":"calls","metadata":{"unresolvedName":"show"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:setIsVisible","kind":"calls","metadata":{"unresolvedName":"setIsVisible"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:show","kind":"calls","metadata":{"unresolvedName":"show"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-auto-hide.ts:","to":"symbol-name:clearTimeout","kind":"calls","metadata":{"unresolvedName":"clearTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"external:window.open","kind":"calls","metadata":{"unresolvedName":"window.open"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"external:session.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"session.tool_type_interfaces?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"calls","metadata":{"unresolvedName":"stopInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"calls","metadata":{"unresolvedName":"deleteInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:setDirtyDeleteSession","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"symbol-name:setDirtyDeleteFiles","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteFiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"calls","metadata":{"unresolvedName":"recreateInstanceTunnel"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"external:window.open","kind":"calls","metadata":{"unresolvedName":"window.open"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"external:session.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"session.tool_type_interfaces?.includes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:startInstance","kind":"calls","metadata":{"unresolvedName":"startInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:stopInstance","kind":"calls","metadata":{"unresolvedName":"stopInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"calls","metadata":{"unresolvedName":"deleteInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteSession","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteFiles","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteFiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:deleteInstance","kind":"calls","metadata":{"unresolvedName":"deleteInstance"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteSession","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteFiles","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteFiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setLoadingSessionId","kind":"calls","metadata":{"unresolvedName":"setLoadingSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:recreateInstanceTunnel","kind":"calls","metadata":{"unresolvedName":"recreateInstanceTunnel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:onRefresh","kind":"calls","metadata":{"unresolvedName":"onRefresh"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteSession","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:","to":"symbol-name:setDirtyDeleteFiles","kind":"calls","metadata":{"unresolvedName":"setDirtyDeleteFiles"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","to":"symbol-name:setIsMobile","kind":"calls","metadata":{"unresolvedName":"setIsMobile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","to":"symbol-name:setIsMobile","kind":"calls","metadata":{"unresolvedName":"setIsMobile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:handleResize","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:handleResize","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:handleResize","to":"symbol-name:setIsMobile","kind":"calls","metadata":{"unresolvedName":"setIsMobile"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:getSequenceWithModifier","to":"external:char.toLowerCase","kind":"calls","metadata":{"unresolvedName":"char.toLowerCase"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-special-keys.ts:applyModifierToChar","to":"external:char.toLowerCase","kind":"calls","metadata":{"unresolvedName":"char.toLowerCase"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"calls","metadata":{"unresolvedName":"getUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","to":"external:document.documentElement.removeAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:useTheme","to":"external:document.documentElement.setAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.setAttribute"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"calls","metadata":{"unresolvedName":"getUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"external:document.documentElement.removeAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"external:document.documentElement.setAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.setAttribute"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"calls","metadata":{"unresolvedName":"getUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"external:document.documentElement.removeAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-theme.ts:","to":"external:document.documentElement.setAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.setAttribute"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"symbol-name:setState","kind":"calls","metadata":{"unresolvedName":"setState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"external:visualViewport.addEventListener","kind":"calls","metadata":{"unresolvedName":"visualViewport.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"symbol-name:updateKeyboardState","kind":"calls","metadata":{"unresolvedName":"updateKeyboardState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"external:visualViewport.removeEventListener","kind":"calls","metadata":{"unresolvedName":"visualViewport.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:useVirtualKeyboard","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"symbol-name:setState","kind":"calls","metadata":{"unresolvedName":"setState"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:visualViewport.addEventListener","kind":"calls","metadata":{"unresolvedName":"visualViewport.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"symbol-name:updateKeyboardState","kind":"calls","metadata":{"unresolvedName":"updateKeyboardState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:visualViewport.removeEventListener","kind":"calls","metadata":{"unresolvedName":"visualViewport.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:visualViewport.removeEventListener","kind":"calls","metadata":{"unresolvedName":"visualViewport.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/hooks/use-virtual-keyboard.ts:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"external:react-dom/client","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/main.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/styles.css","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/git-mount-editor.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setProfiles","kind":"calls","metadata":{"unresolvedName":"setProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setPreviewData","kind":"calls","metadata":{"unresolvedName":"setPreviewData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:profile.includes.map","kind":"calls","metadata":{"unresolvedName":"profile.includes.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:visited.has","kind":"calls","metadata":{"unresolvedName":"visited.has"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:getIncludedProfile","kind":"calls","metadata":{"unresolvedName":"getIncludedProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:nextVisited.add","kind":"calls","metadata":{"unresolvedName":"nextVisited.add"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"calls","metadata":{"unresolvedName":"wouldCreateCycle"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:profiles.filter","kind":"calls","metadata":{"unresolvedName":"profiles.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:includedProfileIds.includes","kind":"calls","metadata":{"unresolvedName":"includedProfileIds.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:prev.filter","kind":"calls","metadata":{"unresolvedName":"prev.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:e.dataTransfer.setData","kind":"calls","metadata":{"unresolvedName":"e.dataTransfer.setData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setDragOverIndex","kind":"calls","metadata":{"unresolvedName":"setDragOverIndex"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:e.dataTransfer.getData","kind":"calls","metadata":{"unresolvedName":"e.dataTransfer.getData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:newOrder.splice","kind":"calls","metadata":{"unresolvedName":"newOrder.splice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:formData.name?.trim","kind":"calls","metadata":{"unresolvedName":"formData.name?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","kind":"calls","metadata":{"unresolvedName":"createConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","kind":"calls","metadata":{"unresolvedName":"updateProfileIncludes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:(await listConfigProfiles()).find","kind":"calls","metadata":{"unresolvedName":"(await listConfigProfiles()).find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","kind":"calls","metadata":{"unresolvedName":"updateConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","kind":"calls","metadata":{"unresolvedName":"deleteConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setPreviewingId","kind":"calls","metadata":{"unresolvedName":"setPreviewingId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","kind":"calls","metadata":{"unresolvedName":"previewConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:mounts.splice","kind":"calls","metadata":{"unresolvedName":"mounts.splice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:profiles.map","kind":"calls","metadata":{"unresolvedName":"profiles.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel","kind":"calls","metadata":{"unresolvedName":"getScopeLabel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.keys","kind":"calls","metadata":{"unresolvedName":"Object.keys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries(selectedProfile.env_vars).map(([k, v]) => `${k}=${v}`).join","kind":"calls","metadata":{"unresolvedName":"Object.entries(selectedProfile.env_vars).map(([k, v]) => `${k}=${v}`).join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries(selectedProfile.env_vars).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(selectedProfile.env_vars).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries","kind":"calls","metadata":{"unresolvedName":"Object.entries"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:selectedProfile.mounts.map((m) => `${m.target} (${m.mode})`).join","kind":"calls","metadata":{"unresolvedName":"selectedProfile.mounts.map((m) => `${m.target} (${m.mode})`).join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:selectedProfile.mounts.map","kind":"calls","metadata":{"unresolvedName":"selectedProfile.mounts.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:handleSubmit","kind":"calls","metadata":{"unresolvedName":"handleSubmit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:projects.map","kind":"calls","metadata":{"unresolvedName":"projects.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:toolTypes.map","kind":"calls","metadata":{"unresolvedName":"toolTypes.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries(formData.env_vars || {}).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(formData.env_vars || {}).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:(formData.mounts || []).map","kind":"calls","metadata":{"unresolvedName":"(formData.mounts || []).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:(formData.mounts || []).filter","kind":"calls","metadata":{"unresolvedName":"(formData.mounts || []).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","kind":"calls","metadata":{"unresolvedName":"handleSelectProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:projects.find","kind":"calls","metadata":{"unresolvedName":"projects.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:toolTypes.find","kind":"calls","metadata":{"unresolvedName":"toolTypes.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:handlePreview","kind":"calls","metadata":{"unresolvedName":"handlePreview"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:includedProfileIds.map","kind":"calls","metadata":{"unresolvedName":"includedProfileIds.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","kind":"calls","metadata":{"unresolvedName":"handleDragStart"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","kind":"calls","metadata":{"unresolvedName":"handleDragOver"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","kind":"calls","metadata":{"unresolvedName":"handleDrop"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","kind":"calls","metadata":{"unresolvedName":"removeInclude"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","kind":"calls","metadata":{"unresolvedName":"availableProfilesForInclude"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","kind":"calls","metadata":{"unresolvedName":"addInclude"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:availableProfilesForInclude().map","kind":"calls","metadata":{"unresolvedName":"availableProfilesForInclude().map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:updateEnvVar","kind":"calls","metadata":{"unresolvedName":"updateEnvVar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","kind":"calls","metadata":{"unresolvedName":"removeEnvVar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries(formData.files || {}).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(formData.files || {}).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","kind":"calls","metadata":{"unresolvedName":"updateFile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","kind":"calls","metadata":{"unresolvedName":"removeFile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"symbol-name:updateMount","kind":"calls","metadata":{"unresolvedName":"updateMount"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","kind":"calls","metadata":{"unresolvedName":"removeMount"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"external:Object.entries(mount.files).map","kind":"calls","metadata":{"unresolvedName":"Object.entries(mount.files).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","kind":"calls","metadata":{"unresolvedName":"updateMountFile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","kind":"calls","metadata":{"unresolvedName":"removeMountFile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","kind":"calls","metadata":{"unresolvedName":"addMountFile"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setProfiles","kind":"calls","metadata":{"unresolvedName":"setProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:resetForm","to":"symbol-name:setPreviewData","kind":"calls","metadata":{"unresolvedName":"setPreviewData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"external:profile.includes.map","kind":"calls","metadata":{"unresolvedName":"profile.includes.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","to":"symbol-name:setPreviewData","kind":"calls","metadata":{"unresolvedName":"setPreviewData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSelectProfile","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleCreateNew","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","to":"external:visited.has","kind":"calls","metadata":{"unresolvedName":"visited.has"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","to":"symbol-name:getIncludedProfile","kind":"calls","metadata":{"unresolvedName":"getIncludedProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","to":"external:nextVisited.add","kind":"calls","metadata":{"unresolvedName":"nextVisited.add"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"calls","metadata":{"unresolvedName":"wouldCreateCycle"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","to":"external:profiles.filter","kind":"calls","metadata":{"unresolvedName":"profiles.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","to":"external:includedProfileIds.includes","kind":"calls","metadata":{"unresolvedName":"includedProfileIds.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:availableProfilesForInclude","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"calls","metadata":{"unresolvedName":"wouldCreateCycle"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:includedProfileIds.includes","kind":"calls","metadata":{"unresolvedName":"includedProfileIds.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:wouldCreateCycle","kind":"calls","metadata":{"unresolvedName":"wouldCreateCycle"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","to":"external:prev.filter","kind":"calls","metadata":{"unresolvedName":"prev.filter"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","to":"external:e.dataTransfer.setData","kind":"calls","metadata":{"unresolvedName":"e.dataTransfer.setData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","to":"symbol-name:String","kind":"calls","metadata":{"unresolvedName":"String"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","to":"symbol-name:setDragOverIndex","kind":"calls","metadata":{"unresolvedName":"setDragOverIndex"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragLeave","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragLeave","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragLeave","to":"symbol-name:setDragOverIndex","kind":"calls","metadata":{"unresolvedName":"setDragOverIndex"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"external:e.dataTransfer.getData","kind":"calls","metadata":{"unresolvedName":"e.dataTransfer.getData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"symbol-name:setDragOverIndex","kind":"calls","metadata":{"unresolvedName":"setDragOverIndex"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"symbol-name:setIncludedProfileIds","kind":"calls","metadata":{"unresolvedName":"setIncludedProfileIds"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","to":"external:newOrder.splice","kind":"calls","metadata":{"unresolvedName":"newOrder.splice"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:newOrder.splice","kind":"calls","metadata":{"unresolvedName":"newOrder.splice"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"external:formData.name?.trim","kind":"calls","metadata":{"unresolvedName":"formData.name?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:createConfigProfile","kind":"calls","metadata":{"unresolvedName":"createConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateProfileIncludes","kind":"calls","metadata":{"unresolvedName":"updateProfileIncludes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"external:(await listConfigProfiles()).find","kind":"calls","metadata":{"unresolvedName":"(await listConfigProfiles()).find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:listConfigProfiles","kind":"calls","metadata":{"unresolvedName":"listConfigProfiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:updateConfigProfile","kind":"calls","metadata":{"unresolvedName":"updateConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:deleteConfigProfile","kind":"calls","metadata":{"unresolvedName":"deleteConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDelete","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","to":"symbol-name:setPreviewingId","kind":"calls","metadata":{"unresolvedName":"setPreviewingId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","to":"/home/alex/projects/headquarter/apps/web/src/api/config_profiles.ts:previewConfigProfile","kind":"calls","metadata":{"unresolvedName":"previewConfigProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","to":"symbol-name:setPreviewData","kind":"calls","metadata":{"unresolvedName":"setPreviewData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handlePreview","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addEnvVar","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateEnvVar","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeEnvVar","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMount","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMount","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","to":"external:mounts.splice","kind":"calls","metadata":{"unresolvedName":"mounts.splice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMount","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:mounts.splice","kind":"calls","metadata":{"unresolvedName":"mounts.splice"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addMountFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateMountFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","to":"symbol-name:setFormData","kind":"calls","metadata":{"unresolvedName":"setFormData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeMountFile","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:preventDefault","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:preventDefault","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:(formData.mounts || []).filter","kind":"calls","metadata":{"unresolvedName":"(formData.mounts || []).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:profiles.find","kind":"calls","metadata":{"unresolvedName":"profiles.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setSelectedProfileId","kind":"calls","metadata":{"unresolvedName":"setSelectedProfileId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:getIncludedProfile","kind":"calls","metadata":{"unresolvedName":"getIncludedProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragStart","kind":"calls","metadata":{"unresolvedName":"handleDragStart"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDragOver","kind":"calls","metadata":{"unresolvedName":"handleDragOver"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:handleDrop","kind":"calls","metadata":{"unresolvedName":"handleDrop"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:getScopeLabel","kind":"calls","metadata":{"unresolvedName":"getScopeLabel"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:removeInclude","kind":"calls","metadata":{"unresolvedName":"removeInclude"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:addInclude","kind":"calls","metadata":{"unresolvedName":"addInclude"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:updateFormField","kind":"calls","metadata":{"unresolvedName":"updateFormField"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"symbol-name:resetForm","kind":"calls","metadata":{"unresolvedName":"resetForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:populateForm","kind":"calls","metadata":{"unresolvedName":"populateForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"external:@testing-library/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:beforeEach","kind":"calls","metadata":{"unresolvedName":"beforeEach"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockReset","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockReset","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockReset","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockRepos.mockReset","kind":"calls","metadata":{"unresolvedName":"mockRepos.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockRepos.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockRepos.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan","kind":"calls","metadata":{"unresolvedName":"expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getAllByText","kind":"calls","metadata":{"unresolvedName":"screen.getAllByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getByText(\"Available projects\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Available projects\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getAllByRole","kind":"calls","metadata":{"unresolvedName":"screen.getAllByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockReset","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockReset","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockReset","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockReset"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockRepos.mockReset","kind":"calls","metadata":{"unresolvedName":"mockRepos.mockReset"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockRepos.mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"mockRepos.mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Loading overview...\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan","kind":"calls","metadata":{"unresolvedName":"expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getAllByText","kind":"calls","metadata":{"unresolvedName":"screen.getAllByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getByText(\"Available projects\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Available projects\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan","kind":"calls","metadata":{"unresolvedName":"expect(screen.getAllByText(\"Open sessions\").length).toBeGreaterThan"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getAllByText","kind":"calls","metadata":{"unresolvedName":"screen.getAllByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:expect(screen.getByText(\"Available projects\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Available projects\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockDashboard.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockDashboard.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockSessions.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockSessions.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:mockProjects.mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"mockProjects.mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getAllByRole","kind":"calls","metadata":{"unresolvedName":"screen.getAllByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:Array.isArray","kind":"calls","metadata":{"unresolvedName":"Array.isArray"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","kind":"calls","metadata":{"unresolvedName":"getDashboardSummary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setSummary","kind":"calls","metadata":{"unresolvedName":"setSummary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:loadHome","kind":"calls","metadata":{"unresolvedName":"loadHome"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","kind":"calls","metadata":{"unresolvedName":"useInstanceActions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:safeSessions.filter","kind":"calls","metadata":{"unresolvedName":"safeSessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:loadRepos","kind":"calls","metadata":{"unresolvedName":"loadRepos"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:useMemo","kind":"calls","metadata":{"unresolvedName":"useMemo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:[\"running\", \"building\", \"pending\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"building\", \"pending\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:summaryCards.map","kind":"calls","metadata":{"unresolvedName":"summaryCards.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:[\"running\", \"building\", \"pending\", \"starting\", \"probing\", \"unhealthy\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"building\", \"pending\", \"starting\", \"probing\", \"unhealthy\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:projects.map","kind":"calls","metadata":{"unresolvedName":"projects.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"external:[\"stopped\", \"error\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"stopped\", \"error\"].includes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/dashboard.ts:getDashboardSummary","kind":"calls","metadata":{"unresolvedName":"getDashboardSummary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setSummary","kind":"calls","metadata":{"unresolvedName":"setSummary"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:loadHome","kind":"calls","metadata":{"unresolvedName":"loadHome"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"external:safeSessions.filter","kind":"calls","metadata":{"unresolvedName":"safeSessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","to":"external:safeSessions.filter","kind":"calls","metadata":{"unresolvedName":"safeSessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:checkHealth","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"symbol-name:loadRepos","kind":"calls","metadata":{"unresolvedName":"loadRepos"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:loadRepos","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:handleCreateSuccess","to":"symbol-name:loadHome","kind":"calls","metadata":{"unresolvedName":"loadHome"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","kind":"calls","metadata":{"unresolvedName":"getRepositoryHistory"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:setSelectedBranch","kind":"calls","metadata":{"unresolvedName":"setSelectedBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:setSelectedCommit","kind":"calls","metadata":{"unresolvedName":"setSelectedCommit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:setDetailStatus","kind":"calls","metadata":{"unresolvedName":"setDetailStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","kind":"calls","metadata":{"unresolvedName":"getCommitDetail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:setCommitDetail","kind":"calls","metadata":{"unresolvedName":"setCommitDetail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:new Date(dateStr).toLocaleString","kind":"calls","metadata":{"unresolvedName":"new Date(dateStr).toLocaleString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:branches.map","kind":"calls","metadata":{"unresolvedName":"branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:commits.map","kind":"calls","metadata":{"unresolvedName":"commits.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","kind":"calls","metadata":{"unresolvedName":"handleCommitClick"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:commit.refs.map","kind":"calls","metadata":{"unresolvedName":"commit.refs.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:commit.message.split","kind":"calls","metadata":{"unresolvedName":"commit.message.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate","kind":"calls","metadata":{"unresolvedName":"formatDate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:commitDetail.parents.map","kind":"calls","metadata":{"unresolvedName":"commitDetail.parents.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:GitHistoryPage","to":"external:parent.substring","kind":"calls","metadata":{"unresolvedName":"parent.substring"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryHistory","kind":"calls","metadata":{"unresolvedName":"getRepositoryHistory"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","to":"symbol-name:setSelectedBranch","kind":"calls","metadata":{"unresolvedName":"setSelectedBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","to":"symbol-name:setSelectedCommit","kind":"calls","metadata":{"unresolvedName":"setSelectedCommit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","to":"symbol-name:setDetailStatus","kind":"calls","metadata":{"unresolvedName":"setDetailStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getCommitDetail","kind":"calls","metadata":{"unresolvedName":"getCommitDetail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","to":"symbol-name:setCommitDetail","kind":"calls","metadata":{"unresolvedName":"setCommitDetail"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","to":"symbol-name:setSelectedCommit","kind":"calls","metadata":{"unresolvedName":"setSelectedCommit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","to":"symbol-name:setCommitDetail","kind":"calls","metadata":{"unresolvedName":"setCommitDetail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCloseDetail","to":"symbol-name:setDetailStatus","kind":"calls","metadata":{"unresolvedName":"setDetailStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:formatDate","to":"external:new Date(dateStr).toLocaleString","kind":"calls","metadata":{"unresolvedName":"new Date(dateStr).toLocaleString"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx:handleCommitClick","kind":"calls","metadata":{"unresolvedName":"handleCommitClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/repository-create-dialog.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"calls","metadata":{"unresolvedName":"deleteRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:setDeleteConfirmId","kind":"calls","metadata":{"unresolvedName":"setDeleteConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:setShowCreate","kind":"calls","metadata":{"unresolvedName":"setShowCreate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"external:safeRepositories.map","kind":"calls","metadata":{"unresolvedName":"safeRepositories.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:GitRepositoriesPage","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:deleteRepository","kind":"calls","metadata":{"unresolvedName":"deleteRepository"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","to":"symbol-name:setDeleteConfirmId","kind":"calls","metadata":{"unresolvedName":"setDeleteConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx:handleDelete","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:PlaceholderPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:PlaceholderPage","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:NotFoundPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:NotFoundPage","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage","to":"external:new URLSearchParams(window.location.search).get","kind":"calls","metadata":{"unresolvedName":"new URLSearchParams(window.location.search).get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx:LoginRedirectPage","to":"symbol-name:encodeURIComponent","kind":"calls","metadata":{"unresolvedName":"encodeURIComponent"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/profile.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"calls","metadata":{"unresolvedName":"useAuth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:useRef","kind":"calls","metadata":{"unresolvedName":"useRef"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:setName","kind":"calls","metadata":{"unresolvedName":"setName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:setEmail","kind":"calls","metadata":{"unresolvedName":"setEmail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:setDisplayStatus","kind":"calls","metadata":{"unresolvedName":"setDisplayStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:name.trim","kind":"calls","metadata":{"unresolvedName":"name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:email.includes","kind":"calls","metadata":{"unresolvedName":"email.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","kind":"calls","metadata":{"unresolvedName":"updateProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:email.trim","kind":"calls","metadata":{"unresolvedName":"email.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:refreshSession","kind":"calls","metadata":{"unresolvedName":"refreshSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:file.type.startsWith","kind":"calls","metadata":{"unresolvedName":"file.type.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","kind":"calls","metadata":{"unresolvedName":"uploadAvatar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:profile.name.charAt(0).toUpperCase","kind":"calls","metadata":{"unresolvedName":"profile.name.charAt(0).toUpperCase"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:profile.name.charAt","kind":"calls","metadata":{"unresolvedName":"profile.name.charAt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"external:fileInputRef.current?.click","kind":"calls","metadata":{"unresolvedName":"fileInputRef.current?.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:ProfilePage","to":"symbol-name:handleSave","kind":"calls","metadata":{"unresolvedName":"handleSave"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setName","kind":"calls","metadata":{"unresolvedName":"setName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setEmail","kind":"calls","metadata":{"unresolvedName":"setEmail"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setDisplayStatus","kind":"calls","metadata":{"unresolvedName":"setDisplayStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setDisplayStatus","kind":"calls","metadata":{"unresolvedName":"setDisplayStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"external:name.trim","kind":"calls","metadata":{"unresolvedName":"name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"external:email.includes","kind":"calls","metadata":{"unresolvedName":"email.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setDisplayStatus","kind":"calls","metadata":{"unresolvedName":"setDisplayStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:updateProfile","kind":"calls","metadata":{"unresolvedName":"updateProfile"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"external:email.trim","kind":"calls","metadata":{"unresolvedName":"email.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:refreshSession","kind":"calls","metadata":{"unresolvedName":"refreshSession"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"external:file.type.startsWith","kind":"calls","metadata":{"unresolvedName":"file.type.startsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:setDisplayStatus","kind":"calls","metadata":{"unresolvedName":"setDisplayStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/profile.ts:uploadAvatar","kind":"calls","metadata":{"unresolvedName":"uploadAvatar"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:refreshSession","kind":"calls","metadata":{"unresolvedName":"refreshSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx:","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/settings-tab-layout.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/repositories-settings-tab.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:setSaving","kind":"calls","metadata":{"unresolvedName":"setSaving"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:setName","kind":"calls","metadata":{"unresolvedName":"setName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:GeneralSettings","to":"symbol-name:setDescription","kind":"calls","metadata":{"unresolvedName":"setDescription"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","to":"symbol-name:setSaving","kind":"calls","metadata":{"unresolvedName":"setSaving"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","to":"external:apiClient.patch","kind":"calls","metadata":{"unresolvedName":"apiClient.patch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleSave","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:handleDelete","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:setProject","kind":"calls","metadata":{"unresolvedName":"setProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:ProjectSettingsPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","kind":"calls","metadata":{"unresolvedName":"fetchProject"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","to":"symbol-name:setProject","kind":"calls","metadata":{"unresolvedName":"setProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","kind":"calls","metadata":{"unresolvedName":"fetchProject"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","to":"symbol-name:setProject","kind":"calls","metadata":{"unresolvedName":"setProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx:fetchProject","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"external:@testing-library/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:cleanup","kind":"calls","metadata":{"unresolvedName":"cleanup"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.restoreAllMocks","kind":"calls","metadata":{"unresolvedName":"vi.restoreAllMocks"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/loading projects/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/loading projects/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Beta Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Beta Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"First project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"First project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"createProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"createProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByRole(\"dialog\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"dialog\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/project name is required/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/project name is required/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText(\"Alpha Project\").closest","kind":"calls","metadata":{"unresolvedName":"screen.getByText(\"Alpha Project\").closest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:within(alphaCard).getByRole","kind":"calls","metadata":{"unresolvedName":"within(alphaCard).getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:within","kind":"calls","metadata":{"unresolvedName":"within"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByDisplayValue","kind":"calls","metadata":{"unresolvedName":"screen.getByDisplayValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(updateMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(updateMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:within(alphaCard).getByText","kind":"calls","metadata":{"unresolvedName":"within(alphaCard).getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/loading projects/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/loading projects/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Beta Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Beta Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"First project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"First project\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load projects/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"createProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"createProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByRole(\"dialog\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"dialog\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/project name is required/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/project name is required/i)).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(/no projects yet/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/no projects yet/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"updateProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText(\"Alpha Project\").closest","kind":"calls","metadata":{"unresolvedName":"screen.getByText(\"Alpha Project\").closest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:within(alphaCard).getByRole","kind":"calls","metadata":{"unresolvedName":"within(alphaCard).getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:within","kind":"calls","metadata":{"unresolvedName":"within"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByRole(\"dialog\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"dialog\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByDisplayValue","kind":"calls","metadata":{"unresolvedName":"screen.getByDisplayValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(updateMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(updateMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(updateMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(updateMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"listProjects\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(projectsApi, \"deleteProject\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText(\"Alpha Project\").closest","kind":"calls","metadata":{"unresolvedName":"screen.getByText(\"Alpha Project\").closest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:within(alphaCard).getByRole","kind":"calls","metadata":{"unresolvedName":"within(alphaCard).getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:within","kind":"calls","metadata":{"unresolvedName":"within"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(within(alphaCard).getByText(/are you sure/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:within(alphaCard).getByText","kind":"calls","metadata":{"unresolvedName":"within(alphaCard).getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Alpha Project\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setFormName","kind":"calls","metadata":{"unresolvedName":"setFormName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setFormDescription","kind":"calls","metadata":{"unresolvedName":"setFormDescription"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setEditingProject","kind":"calls","metadata":{"unresolvedName":"setEditingProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setDialogMode","kind":"calls","metadata":{"unresolvedName":"setDialogMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"external:formName.trim","kind":"calls","metadata":{"unresolvedName":"formName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"external:formDescription.trim","kind":"calls","metadata":{"unresolvedName":"formDescription.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","kind":"calls","metadata":{"unresolvedName":"createProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","kind":"calls","metadata":{"unresolvedName":"updateProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","kind":"calls","metadata":{"unresolvedName":"closeDialog"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","kind":"calls","metadata":{"unresolvedName":"deleteProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:setDeleteConfirmId","kind":"calls","metadata":{"unresolvedName":"setDeleteConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"external:safeProjects.map","kind":"calls","metadata":{"unresolvedName":"safeProjects.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","kind":"calls","metadata":{"unresolvedName":"openEdit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:ProjectsPage","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","to":"symbol-name:setFormName","kind":"calls","metadata":{"unresolvedName":"setFormName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","to":"symbol-name:setFormDescription","kind":"calls","metadata":{"unresolvedName":"setFormDescription"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","to":"symbol-name:setEditingProject","kind":"calls","metadata":{"unresolvedName":"setEditingProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openCreate","to":"symbol-name:setDialogMode","kind":"calls","metadata":{"unresolvedName":"setDialogMode"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","to":"symbol-name:setFormName","kind":"calls","metadata":{"unresolvedName":"setFormName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","to":"symbol-name:setFormDescription","kind":"calls","metadata":{"unresolvedName":"setFormDescription"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","to":"symbol-name:setEditingProject","kind":"calls","metadata":{"unresolvedName":"setEditingProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:openEdit","to":"symbol-name:setDialogMode","kind":"calls","metadata":{"unresolvedName":"setDialogMode"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","to":"symbol-name:setDialogMode","kind":"calls","metadata":{"unresolvedName":"setDialogMode"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","to":"symbol-name:setEditingProject","kind":"calls","metadata":{"unresolvedName":"setEditingProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"symbol-name:setFormError","kind":"calls","metadata":{"unresolvedName":"setFormError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"external:formName.trim","kind":"calls","metadata":{"unresolvedName":"formName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"external:formDescription.trim","kind":"calls","metadata":{"unresolvedName":"formDescription.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:createProject","kind":"calls","metadata":{"unresolvedName":"createProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:updateProject","kind":"calls","metadata":{"unresolvedName":"updateProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:closeDialog","kind":"calls","metadata":{"unresolvedName":"closeDialog"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleSubmit","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:deleteProject","kind":"calls","metadata":{"unresolvedName":"deleteProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","to":"symbol-name:setDeleteConfirmId","kind":"calls","metadata":{"unresolvedName":"setDeleteConfirmId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx:handleDelete","to":"symbol-name:reload","kind":"calls","metadata":{"unresolvedName":"reload"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/commit-panel.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/file-editor.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/git-toolbar.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/instance-list.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/workspace-header.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:useSearchParams","kind":"calls","metadata":{"unresolvedName":"useSearchParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:searchParams.get","kind":"calls","metadata":{"unresolvedName":"searchParams.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setProject","kind":"calls","metadata":{"unresolvedName":"setProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setSelectedRepoId","kind":"calls","metadata":{"unresolvedName":"setSelectedRepoId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:response.data.branches.map","kind":"calls","metadata":{"unresolvedName":"response.data.branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setCurrentBranch","kind":"calls","metadata":{"unresolvedName":"setCurrentBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"calls","metadata":{"unresolvedName":"getRepositoryStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setGitStatus","kind":"calls","metadata":{"unresolvedName":"setGitStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:loadProject","kind":"calls","metadata":{"unresolvedName":"loadProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:loadRepositories","kind":"calls","metadata":{"unresolvedName":"loadRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"calls","metadata":{"unresolvedName":"loadToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"calls","metadata":{"unresolvedName":"loadBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:loadGitStatus","kind":"calls","metadata":{"unresolvedName":"loadGitStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:newParams.delete","kind":"calls","metadata":{"unresolvedName":"newParams.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:repositories.find","kind":"calls","metadata":{"unresolvedName":"repositories.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","kind":"calls","metadata":{"unresolvedName":"handleRepoChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:repositories.map","kind":"calls","metadata":{"unresolvedName":"repositories.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:branches.map","kind":"calls","metadata":{"unresolvedName":"branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"external:window.dispatchEvent","kind":"calls","metadata":{"unresolvedName":"window.dispatchEvent"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:setMobileTab","kind":"calls","metadata":{"unresolvedName":"setMobileTab"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"symbol-name:Boolean","kind":"calls","metadata":{"unresolvedName":"Boolean"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setProject","kind":"calls","metadata":{"unresolvedName":"setProject"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setSelectedRepoId","kind":"calls","metadata":{"unresolvedName":"setSelectedRepoId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:response.data.branches.map","kind":"calls","metadata":{"unresolvedName":"response.data.branches.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setBranches","kind":"calls","metadata":{"unresolvedName":"setBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setCurrentBranch","kind":"calls","metadata":{"unresolvedName":"setCurrentBranch"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:getRepositoryStatus","kind":"calls","metadata":{"unresolvedName":"getRepositoryStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setGitStatus","kind":"calls","metadata":{"unresolvedName":"setGitStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadProject","kind":"calls","metadata":{"unresolvedName":"loadProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadRepositories","kind":"calls","metadata":{"unresolvedName":"loadRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"calls","metadata":{"unresolvedName":"loadToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"calls","metadata":{"unresolvedName":"loadBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadGitStatus","kind":"calls","metadata":{"unresolvedName":"loadGitStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","to":"symbol-name:setSelectedRepoId","kind":"calls","metadata":{"unresolvedName":"setSelectedRepoId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","to":"external:newParams.delete","kind":"calls","metadata":{"unresolvedName":"newParams.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleRepoChange","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setCurrentBranch","kind":"calls","metadata":{"unresolvedName":"setCurrentBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadGitStatus","kind":"calls","metadata":{"unresolvedName":"loadGitStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:window.dispatchEvent","kind":"calls","metadata":{"unresolvedName":"window.dispatchEvent"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setCurrentBranch","kind":"calls","metadata":{"unresolvedName":"setCurrentBranch"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx:loadBranches","kind":"calls","metadata":{"unresolvedName":"loadBranches"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadGitStatus","kind":"calls","metadata":{"unresolvedName":"loadGitStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:window.dispatchEvent","kind":"calls","metadata":{"unresolvedName":"window.dispatchEvent"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadGitStatus","kind":"calls","metadata":{"unresolvedName":"loadGitStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:window.dispatchEvent","kind":"calls","metadata":{"unresolvedName":"window.dispatchEvent"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:useSearchParams","kind":"calls","metadata":{"unresolvedName":"useSearchParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:searchParams.get","kind":"calls","metadata":{"unresolvedName":"searchParams.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:setEntries","kind":"calls","metadata":{"unresolvedName":"setEntries"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:loadFiles","kind":"calls","metadata":{"unresolvedName":"loadFiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:path.split(\"/\").slice(0, -1).join","kind":"calls","metadata":{"unresolvedName":"path.split(\"/\").slice(0, -1).join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:path.split(\"/\").slice","kind":"calls","metadata":{"unresolvedName":"path.split(\"/\").slice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:path.split","kind":"calls","metadata":{"unresolvedName":"path.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:newParams.delete","kind":"calls","metadata":{"unresolvedName":"newParams.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:gitStatus.modified.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.modified.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:gitStatus.added.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.added.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:gitStatus.deleted.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.deleted.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:gitStatus.untracked.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.untracked.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"external:entries.map","kind":"calls","metadata":{"unresolvedName":"entries.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","kind":"calls","metadata":{"unresolvedName":"getFileStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:FileBrowser","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","kind":"calls","metadata":{"unresolvedName":"handleEntryClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setLoading","kind":"calls","metadata":{"unresolvedName":"setLoading"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setError","kind":"calls","metadata":{"unresolvedName":"setError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:setEntries","kind":"calls","metadata":{"unresolvedName":"setEntries"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadFiles","kind":"calls","metadata":{"unresolvedName":"loadFiles"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"symbol-name:loadFiles","kind":"calls","metadata":{"unresolvedName":"loadFiles"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:window.addEventListener","kind":"calls","metadata":{"unresolvedName":"window.addEventListener"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"external:window.removeEventListener","kind":"calls","metadata":{"unresolvedName":"window.removeEventListener"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"external:path.split(\"/\").slice(0, -1).join","kind":"calls","metadata":{"unresolvedName":"path.split(\"/\").slice(0, -1).join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"external:path.split(\"/\").slice","kind":"calls","metadata":{"unresolvedName":"path.split(\"/\").slice"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"external:path.split","kind":"calls","metadata":{"unresolvedName":"path.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"external:newParams.set","kind":"calls","metadata":{"unresolvedName":"newParams.set"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"external:newParams.delete","kind":"calls","metadata":{"unresolvedName":"newParams.delete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:navigateUp","to":"symbol-name:setSearchParams","kind":"calls","metadata":{"unresolvedName":"setSearchParams"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","to":"external:gitStatus.modified.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.modified.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","to":"external:gitStatus.added.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.added.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","to":"external:gitStatus.deleted.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.deleted.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","to":"external:gitStatus.untracked.includes","kind":"calls","metadata":{"unresolvedName":"gitStatus.untracked.includes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:getFileStatus","kind":"calls","metadata":{"unresolvedName":"getFileStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:handleEntryClick","kind":"calls","metadata":{"unresolvedName":"handleEntryClick"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/projects.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/create-session-form.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/session-list.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/session-card.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/sessions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"calls","metadata":{"unresolvedName":"getUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setLastSessionId","kind":"calls","metadata":{"unresolvedName":"setLastSessionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","kind":"calls","metadata":{"unresolvedName":"loadProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"calls","metadata":{"unresolvedName":"loadToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-instance-actions.ts:useInstanceActions","kind":"calls","metadata":{"unresolvedName":"useInstanceActions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:s.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"s.tool_type_interfaces?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:loadRepos","kind":"calls","metadata":{"unresolvedName":"loadRepos"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:useMemo","kind":"calls","metadata":{"unresolvedName":"useMemo"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:sessions.find","kind":"calls","metadata":{"unresolvedName":"sessions.find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"external:dirtyDeleteFiles.map","kind":"calls","metadata":{"unresolvedName":"dirtyDeleteFiles.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"symbol-name:handleForceDelete","kind":"calls","metadata":{"unresolvedName":"handleForceDelete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:getUserSessions","kind":"calls","metadata":{"unresolvedName":"getUserSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:getUserConfig","kind":"calls","metadata":{"unresolvedName":"getUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setLastSessionId","kind":"calls","metadata":{"unresolvedName":"setLastSessionId"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","kind":"calls","metadata":{"unresolvedName":"loadProjects"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","to":"/home/alex/projects/headquarter/apps/web/src/api/projects.ts:listProjects","kind":"calls","metadata":{"unresolvedName":"listProjects"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadProjects","to":"symbol-name:setProjects","kind":"calls","metadata":{"unresolvedName":"setProjects"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"calls","metadata":{"unresolvedName":"loadToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"external:[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"external:s.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"s.tool_type_interfaces?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:checkHealth","kind":"calls","metadata":{"unresolvedName":"checkHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setInterval","kind":"calls","metadata":{"unresolvedName":"setInterval"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:clearInterval","kind":"calls","metadata":{"unresolvedName":"clearInterval"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","to":"external:sessions.filter","kind":"calls","metadata":{"unresolvedName":"sessions.filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","to":"external:[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes","kind":"calls","metadata":{"unresolvedName":"[\"running\", \"starting\", \"unhealthy\", \"probing\"].includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","to":"external:s.tool_type_interfaces?.includes","kind":"calls","metadata":{"unresolvedName":"s.tool_type_interfaces?.includes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","to":"/home/alex/projects/headquarter/apps/web/src/api/sessions.ts:checkInstanceHealth","kind":"calls","metadata":{"unresolvedName":"checkInstanceHealth"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:checkHealth","to":"symbol-name:setTunnelHealth","kind":"calls","metadata":{"unresolvedName":"setTunnelHealth"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:loadRepos","kind":"calls","metadata":{"unresolvedName":"loadRepos"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos","to":"/home/alex/projects/headquarter/apps/web/src/api/git_repositories.ts:listRepositories","kind":"calls","metadata":{"unresolvedName":"listRepositories"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadRepos","to":"symbol-name:setRepositories","kind":"calls","metadata":{"unresolvedName":"setRepositories"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:handleCreateSuccess","to":"symbol-name:loadSessions","kind":"calls","metadata":{"unresolvedName":"loadSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"symbol-name:setSelectedProject","kind":"calls","metadata":{"unresolvedName":"setSelectedProject"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/settings.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"symbol-name:useLocation","kind":"calls","metadata":{"unresolvedName":"useLocation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"symbol-name:setConfig","kind":"calls","metadata":{"unresolvedName":"setConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:document.documentElement.removeAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:document.documentElement.setAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.setAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:window.setTimeout","kind":"calls","metadata":{"unresolvedName":"window.setTimeout"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:location.pathname.split(\"/\").filter","kind":"calls","metadata":{"unresolvedName":"location.pathname.split(\"/\").filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:location.pathname.split","kind":"calls","metadata":{"unresolvedName":"location.pathname.split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:location.pathname.endsWith","kind":"calls","metadata":{"unresolvedName":"location.pathname.endsWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:SettingsPage","to":"external:TABS.map","kind":"calls","metadata":{"unresolvedName":"TABS.map"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:","to":"symbol-name:setConfig","kind":"calls","metadata":{"unresolvedName":"setConfig"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange","to":"symbol-name:setConfig","kind":"calls","metadata":{"unresolvedName":"setConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleChange","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"symbol-name:setSaveStatus","kind":"calls","metadata":{"unresolvedName":"setSaveStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"/home/alex/projects/headquarter/apps/web/src/api/settings.ts:updateUserConfig","kind":"calls","metadata":{"unresolvedName":"updateUserConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"symbol-name:setConfig","kind":"calls","metadata":{"unresolvedName":"setConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"external:document.documentElement.removeAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.removeAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"external:document.documentElement.setAttribute","kind":"calls","metadata":{"unresolvedName":"document.documentElement.setAttribute"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:handleSave","to":"external:window.setTimeout","kind":"calls","metadata":{"unresolvedName":"window.setTimeout"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","to":"symbol-name:useOutletContext","kind":"calls","metadata":{"unresolvedName":"useOutletContext"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","to":"symbol-name:handleChange","kind":"calls","metadata":{"unresolvedName":"handleChange"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","to":"external:THEME_OPTIONS.map","kind":"calls","metadata":{"unresolvedName":"THEME_OPTIONS.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx:GeneralSettingsTab","to":"symbol-name:handleSave","kind":"calls","metadata":{"unresolvedName":"handleSave"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-async-data.ts:useAsyncData","kind":"calls","metadata":{"unresolvedName":"useAsyncData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:newKeyName.trim","kind":"calls","metadata":{"unresolvedName":"newKeyName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setGenerating","kind":"calls","metadata":{"unresolvedName":"setGenerating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","kind":"calls","metadata":{"unresolvedName":"createSSHKey"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setNewKeyName","kind":"calls","metadata":{"unresolvedName":"setNewKeyName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setMutationError","kind":"calls","metadata":{"unresolvedName":"setMutationError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:confirm","kind":"calls","metadata":{"unresolvedName":"confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","kind":"calls","metadata":{"unresolvedName":"deleteSSHKey"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:payload?.trim","kind":"calls","metadata":{"unresolvedName":"payload?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setSigning","kind":"calls","metadata":{"unresolvedName":"setSigning"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","kind":"calls","metadata":{"unresolvedName":"signPayload"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:payload.trim","kind":"calls","metadata":{"unresolvedName":"payload.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setSignatures","kind":"calls","metadata":{"unresolvedName":"setSignatures"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:signature?.trim","kind":"calls","metadata":{"unresolvedName":"signature?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setVerifying","kind":"calls","metadata":{"unresolvedName":"setVerifying"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","kind":"calls","metadata":{"unresolvedName":"verifySignature"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:signature.trim","kind":"calls","metadata":{"unresolvedName":"signature.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setVerifyResults","kind":"calls","metadata":{"unresolvedName":"setVerifyResults"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:safeKeys.map","kind":"calls","metadata":{"unresolvedName":"safeKeys.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:handleDelete","kind":"calls","metadata":{"unresolvedName":"handleDelete"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:new Date(key.created_at).toLocaleDateString","kind":"calls","metadata":{"unresolvedName":"new Date(key.created_at).toLocaleDateString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:key.public_key.substring","kind":"calls","metadata":{"unresolvedName":"key.public_key.substring"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard","kind":"calls","metadata":{"unresolvedName":"copyToClipboard"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setSignPayloads","kind":"calls","metadata":{"unresolvedName":"setSignPayloads"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","kind":"calls","metadata":{"unresolvedName":"handleSign"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:signPayloads[key.id]?.trim","kind":"calls","metadata":{"unresolvedName":"signPayloads[key.id]?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setVerifyPayloads","kind":"calls","metadata":{"unresolvedName":"setVerifyPayloads"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"symbol-name:setVerifySignatures","kind":"calls","metadata":{"unresolvedName":"setVerifySignatures"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","kind":"calls","metadata":{"unresolvedName":"handleVerify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:verifyPayloads[key.id]?.trim","kind":"calls","metadata":{"unresolvedName":"verifyPayloads[key.id]?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:SSHKeysPage","to":"external:verifySignatures[key.id]?.trim","kind":"calls","metadata":{"unresolvedName":"verifySignatures[key.id]?.trim"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"external:newKeyName.trim","kind":"calls","metadata":{"unresolvedName":"newKeyName.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"symbol-name:setGenerating","kind":"calls","metadata":{"unresolvedName":"setGenerating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:createSSHKey","kind":"calls","metadata":{"unresolvedName":"createSSHKey"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"symbol-name:setNewKeyName","kind":"calls","metadata":{"unresolvedName":"setNewKeyName"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleGenerate","to":"symbol-name:setMutationError","kind":"calls","metadata":{"unresolvedName":"setMutationError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","to":"symbol-name:confirm","kind":"calls","metadata":{"unresolvedName":"confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:deleteSSHKey","kind":"calls","metadata":{"unresolvedName":"deleteSSHKey"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","to":"symbol-name:loadKeys","kind":"calls","metadata":{"unresolvedName":"loadKeys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleDelete","to":"symbol-name:setMutationError","kind":"calls","metadata":{"unresolvedName":"setMutationError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:copyToClipboard","to":"external:navigator.clipboard.writeText","kind":"calls","metadata":{"unresolvedName":"navigator.clipboard.writeText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"external:payload?.trim","kind":"calls","metadata":{"unresolvedName":"payload?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"symbol-name:setSigning","kind":"calls","metadata":{"unresolvedName":"setSigning"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:signPayload","kind":"calls","metadata":{"unresolvedName":"signPayload"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"external:payload.trim","kind":"calls","metadata":{"unresolvedName":"payload.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"symbol-name:setSignatures","kind":"calls","metadata":{"unresolvedName":"setSignatures"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleSign","to":"symbol-name:setMutationError","kind":"calls","metadata":{"unresolvedName":"setMutationError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"external:payload?.trim","kind":"calls","metadata":{"unresolvedName":"payload?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"external:signature?.trim","kind":"calls","metadata":{"unresolvedName":"signature?.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"symbol-name:setVerifying","kind":"calls","metadata":{"unresolvedName":"setVerifying"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"/home/alex/projects/headquarter/apps/web/src/api/ssh_keys.ts:verifySignature","kind":"calls","metadata":{"unresolvedName":"verifySignature"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"external:payload.trim","kind":"calls","metadata":{"unresolvedName":"payload.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"external:signature.trim","kind":"calls","metadata":{"unresolvedName":"signature.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"symbol-name:setVerifyResults","kind":"calls","metadata":{"unresolvedName":"setVerifyResults"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx:handleVerify","to":"symbol-name:setMutationError","kind":"calls","metadata":{"unresolvedName":"setMutationError"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/terminal.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-terminal-wrapper.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","to":"symbol-name:useParams","kind":"calls","metadata":{"unresolvedName":"useParams"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","to":"symbol-name:useNavigate","kind":"calls","metadata":{"unresolvedName":"useNavigate"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx:TerminalPage","to":"symbol-name:navigate","kind":"calls","metadata":{"unresolvedName":"navigate"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"external:@testing-library/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"external:vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:cleanup","kind":"calls","metadata":{"unresolvedName":"cleanup"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.restoreAllMocks","kind":"calls","metadata":{"unresolvedName":"vi.restoreAllMocks"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:it","kind":"calls","metadata":{"unresolvedName":"it"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/loading/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/loading/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(configsListMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(configsListMock).toHaveBeenCalledTimes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(foldersListMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(foldersListMock).toHaveBeenCalledTimes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Active\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Active\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText(\"Custom Tool\").closest","kind":"calls","metadata":{"unresolvedName":"screen.getByText(\"Custom Tool\").closest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:within(customToolCard as HTMLElement).queryByRole","kind":"calls","metadata":{"unresolvedName":"within(customToolCard as HTMLElement).queryByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:within","kind":"calls","metadata":{"unresolvedName":"within"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(window, \"confirm\").mockReturnValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(window, \"confirm\").mockReturnValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockImplementation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/loading/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/loading/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(/Enter value/i)).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"createToolConfig\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(configsListMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(configsListMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /configs/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"OPENAI_API_KEY\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByPlaceholderText(\"e.g., /home/user\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"createConfigFolder\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.change","kind":"calls","metadata":{"unresolvedName":"fireEvent.change"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByPlaceholderText","kind":"calls","metadata":{"unresolvedName":"screen.getByPlaceholderText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(foldersListMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(foldersListMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(createMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(createMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect.objectContaining","kind":"calls","metadata":{"unresolvedName":"expect.objectContaining"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Active\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Active\")).toBeInTheDocument"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /folders/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"my-dotfiles\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockRejectedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByRole(\"button\", { name: /retry/i })).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\")\n .mockRejectedValueOnce"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByRole","kind":"calls","metadata":{"unresolvedName":"screen.getByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(/failed to load/i)).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(/failed to load/i)).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"VS Code Server\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"listToolTypes\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn","kind":"calls","metadata":{"unresolvedName":"vi.spyOn"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolTypesApi, \"deleteToolType\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(toolConfigsApi, \"listToolConfigs\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(configFoldersApi, \"listConfigFolders\").mockResolvedValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:render","kind":"calls","metadata":{"unresolvedName":"render"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:waitFor","kind":"calls","metadata":{"unresolvedName":"waitFor"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText(\"Custom Tool\").closest","kind":"calls","metadata":{"unresolvedName":"screen.getByText(\"Custom Tool\").closest"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:within(customToolCard as HTMLElement).queryByRole","kind":"calls","metadata":{"unresolvedName":"within(customToolCard as HTMLElement).queryByRole"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:within","kind":"calls","metadata":{"unresolvedName":"within"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:vi.spyOn(window, \"confirm\").mockReturnValue","kind":"calls","metadata":{"unresolvedName":"vi.spyOn(window, \"confirm\").mockReturnValue"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:fireEvent.click","kind":"calls","metadata":{"unresolvedName":"fireEvent.click"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(listMock).toHaveBeenCalledTimes","kind":"calls","metadata":{"unresolvedName":"expect(listMock).toHaveBeenCalledTimes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument","kind":"calls","metadata":{"unresolvedName":"expect(screen.getByText(\"Custom Tool\")).toBeInTheDocument"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:screen.getByText","kind":"calls","metadata":{"unresolvedName":"screen.getByText"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"external:expect(deleteMock).toHaveBeenCalledWith","kind":"calls","metadata":{"unresolvedName":"expect(deleteMock).toHaveBeenCalledWith"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.test.tsx:","to":"symbol-name:expect","kind":"calls","metadata":{"unresolvedName":"expect"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"external:react-router-dom","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/app-shell.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/protected-route.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/placeholder.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/profile.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/projects.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-repositories.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/git-history.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/project-settings.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/settings.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/terminal.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/ssh-keys.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"/home/alex/projects/headquarter/apps/web/src/router.tsx:AppRouter","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/router.tsx","to":"/home/alex/projects/headquarter/apps/web/src/router.tsx:AppRouter","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:setState","kind":"calls","metadata":{"unresolvedName":"setState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:setUser","kind":"calls","metadata":{"unresolvedName":"setUser"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:refreshSession","kind":"calls","metadata":{"unresolvedName":"refreshSession"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:AuthProvider","to":"symbol-name:useMemo","kind":"calls","metadata":{"unresolvedName":"useMemo"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"symbol-name:setState","kind":"calls","metadata":{"unresolvedName":"setState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"symbol-name:setUser","kind":"calls","metadata":{"unresolvedName":"setUser"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"symbol-name:setUser","kind":"calls","metadata":{"unresolvedName":"setUser"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"symbol-name:setState","kind":"calls","metadata":{"unresolvedName":"setState"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:","to":"symbol-name:refreshSession","kind":"calls","metadata":{"unresolvedName":"refreshSession"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/auth.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/auth.tsx:useAuth","to":"symbol-name:useContext","kind":"calls","metadata":{"unresolvedName":"useContext"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:SessionsProvider","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:","to":"symbol-name:setSessions","kind":"calls","metadata":{"unresolvedName":"setSessions"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx","to":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/state/sessions.tsx:useSessions","to":"symbol-name:useContext","kind":"calls","metadata":{"unresolvedName":"useContext"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/test/setup.ts","to":"external:@testing-library/jest-dom/vitest","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","to":"external:Array.isArray","kind":"calls","metadata":{"unresolvedName":"Array.isArray"}},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","to":"external:detail.map((d) => typeof d === \"string\" ? d : d.msg || JSON.stringify(d)).join","kind":"calls","metadata":{"unresolvedName":"detail.map((d) => typeof d === \"string\" ? d : d.msg || JSON.stringify(d)).join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","to":"external:detail.map","kind":"calls","metadata":{"unresolvedName":"detail.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/icons.ts","to":"external:@phosphor-icons/react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"external:prismjs","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","to":"external:filename.split(\".\").pop()?.toLowerCase","kind":"calls","metadata":{"unresolvedName":"filename.split(\".\").pop()?.toLowerCase"}},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","to":"external:filename.split(\".\").pop","kind":"calls","metadata":{"unresolvedName":"filename.split(\".\").pop"}},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:detectLanguage","to":"external:filename.split","kind":"calls","metadata":{"unresolvedName":"filename.split"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:highlightCode","to":"external:Prism.highlight","kind":"calls","metadata":{"unresolvedName":"Prism.highlight"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/utils/language.ts","to":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/utils/language.ts:loadLanguage","to":"symbol-name:import","kind":"calls","metadata":{"unresolvedName":"import"}},{"from":"file:/home/alex/projects/headquarter/apps/web/vite.config.ts","to":"external:vite","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/vite.config.ts","to":"external:@vitejs/plugin-react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"file:/home/alex/projects/headquarter/apps/web/src/api/client.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:getToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:getToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:getToolType","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","to":"external:apiClient.post","kind":"calls","metadata":{"unresolvedName":"apiClient.post"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","to":"external:apiClient.put","kind":"calls","metadata":{"unresolvedName":"apiClient.put"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","to":"external:apiClient.delete","kind":"calls","metadata":{"unresolvedName":"apiClient.delete"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType","to":"external:apiClient.get","kind":"calls","metadata":{"unresolvedName":"apiClient.get"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"calls","metadata":{"unresolvedName":"createToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:validateToolType","kind":"calls","metadata":{"unresolvedName":"validateToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"calls","metadata":{"unresolvedName":"updateToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.test.ts:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"calls","metadata":{"unresolvedName":"deleteToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:ConfigProfilesPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/config-profiles.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:HomePage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/dashboard.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:RepoWorkspace","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/repo-workspace.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:SessionsPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/sessions.tsx:loadToolTypes","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"external:react","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/data-states.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/icon.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/utils/errors.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-list-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-detail-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-edit-view.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/mobile-fab.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/components/manifest-editor.tsx","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"file:/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts","kind":"imports"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/hooks/use-mobile-viewport.ts:useMobileViewport","kind":"calls","metadata":{"unresolvedName":"useMobileViewport"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:useState","kind":"calls","metadata":{"unresolvedName":"useState"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:(toolTypes || []).find","kind":"calls","metadata":{"unresolvedName":"(toolTypes || []).find"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:(configs || []).filter","kind":"calls","metadata":{"unresolvedName":"(configs || []).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:useCallback","kind":"calls","metadata":{"unresolvedName":"useCallback"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","kind":"calls","metadata":{"unresolvedName":"listToolConfigs"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"calls","metadata":{"unresolvedName":"listConfigFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","kind":"calls","metadata":{"unresolvedName":"listToolDefinitions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setConfigs","kind":"calls","metadata":{"unresolvedName":"setConfigs"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setFolders","kind":"calls","metadata":{"unresolvedName":"setFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setBaseDefinitions","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:(defs || []).filter","kind":"calls","metadata":{"unresolvedName":"(defs || []).filter"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:useEffect","kind":"calls","metadata":{"unresolvedName":"useEffect"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setToolTypeError","kind":"calls","metadata":{"unresolvedName":"setToolTypeError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setManifestData","kind":"calls","metadata":{"unresolvedName":"setManifestData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setManifestDefinitionId","kind":"calls","metadata":{"unresolvedName":"setManifestDefinitionId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolType.default_port?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.default_port?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolType.readiness_probe?.timeout?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.readiness_probe?.timeout?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolType.readiness_probe?.interval?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.readiness_probe?.interval?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolType.required_variables?.join","kind":"calls","metadata":{"unresolvedName":"toolType.required_variables?.join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"calls","metadata":{"unresolvedName":"populateToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setRightPanelTab","kind":"calls","metadata":{"unresolvedName":"setRightPanelTab"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"calls","metadata":{"unresolvedName":"resetToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.name.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.display_name.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.display_name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.default_port.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.default_port.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:isNaN","kind":"calls","metadata":{"unresolvedName":"isNaN"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:template.trim","kind":"calls","metadata":{"unresolvedName":"template.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.required_variables\n .split(\",\")\n .map","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split(\",\")\n .map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.required_variables\n .split","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:v.trim","kind":"calls","metadata":{"unresolvedName":"v.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.readiness_command.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.readiness_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.description.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.description.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.category.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.category.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypeForm.startup_command.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.startup_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"calls","metadata":{"unresolvedName":"createToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"calls","metadata":{"unresolvedName":"updateToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"calls","metadata":{"unresolvedName":"deleteToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setConfigForm","kind":"calls","metadata":{"unresolvedName":"setConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setConfigError","kind":"calls","metadata":{"unresolvedName":"setConfigError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setSelectedConfig","kind":"calls","metadata":{"unresolvedName":"setSelectedConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"calls","metadata":{"unresolvedName":"resetConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:config.port_override?.toString","kind":"calls","metadata":{"unresolvedName":"config.port_override?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:configForm.key.trim","kind":"calls","metadata":{"unresolvedName":"configForm.key.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:configForm.env_vars_json.trim","kind":"calls","metadata":{"unresolvedName":"configForm.env_vars_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:configForm.volumes_json.trim","kind":"calls","metadata":{"unresolvedName":"configForm.volumes_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:configForm.start_command.trim","kind":"calls","metadata":{"unresolvedName":"configForm.start_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:configForm.working_directory.trim","kind":"calls","metadata":{"unresolvedName":"configForm.working_directory.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","kind":"calls","metadata":{"unresolvedName":"updateToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","kind":"calls","metadata":{"unresolvedName":"createToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","kind":"calls","metadata":{"unresolvedName":"deleteToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setFolderForm","kind":"calls","metadata":{"unresolvedName":"setFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setFolderError","kind":"calls","metadata":{"unresolvedName":"setFolderError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setSelectedFolder","kind":"calls","metadata":{"unresolvedName":"setSelectedFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"calls","metadata":{"unresolvedName":"resetFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:folderForm.name.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:folderForm.mount_path.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.mount_path.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:folderForm.files_json.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.files_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:folderForm.description.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.description.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"calls","metadata":{"unresolvedName":"updateConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"calls","metadata":{"unresolvedName":"createConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"calls","metadata":{"unresolvedName":"deleteConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolTypes.map","kind":"calls","metadata":{"unresolvedName":"toolTypes.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:selectedToolType.required_variables?.join","kind":"calls","metadata":{"unresolvedName":"selectedToolType.required_variables?.join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"calls","metadata":{"unresolvedName":"handleDeleteToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","kind":"calls","metadata":{"unresolvedName":"handleToolTypeSubmit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","kind":"calls","metadata":{"unresolvedName":"handleSelectToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:([\"details\", \"configs\", \"folders\"] as RightPanelTab[]).map","kind":"calls","metadata":{"unresolvedName":"([\"details\", \"configs\", \"folders\"] as RightPanelTab[]).map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolConfigs.map","kind":"calls","metadata":{"unresolvedName":"toolConfigs.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","kind":"calls","metadata":{"unresolvedName":"openEditConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","kind":"calls","metadata":{"unresolvedName":"handleDeleteConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:toolFolders.map","kind":"calls","metadata":{"unresolvedName":"toolFolders.map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"external:Object.keys","kind":"calls","metadata":{"unresolvedName":"Object.keys"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","kind":"calls","metadata":{"unresolvedName":"openEditFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:ToolWorkshopPage","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","kind":"calls","metadata":{"unresolvedName":"handleDeleteFolder"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setStatus","kind":"calls","metadata":{"unresolvedName":"setStatus"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"external:Promise.all","kind":"calls","metadata":{"unresolvedName":"Promise.all"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:listToolTypes","kind":"calls","metadata":{"unresolvedName":"listToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:listToolConfigs","kind":"calls","metadata":{"unresolvedName":"listToolConfigs"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:listConfigFolders","kind":"calls","metadata":{"unresolvedName":"listConfigFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_definitions.ts:listToolDefinitions","kind":"calls","metadata":{"unresolvedName":"listToolDefinitions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypes","kind":"calls","metadata":{"unresolvedName":"setToolTypes"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setConfigs","kind":"calls","metadata":{"unresolvedName":"setConfigs"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setFolders","kind":"calls","metadata":{"unresolvedName":"setFolders"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setBaseDefinitions","kind":"calls","metadata":{"unresolvedName":"setBaseDefinitions"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"external:(defs || []).filter","kind":"calls","metadata":{"unresolvedName":"(defs || []).filter"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","to":"symbol-name:setToolTypeError","kind":"calls","metadata":{"unresolvedName":"setToolTypeError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","to":"symbol-name:setManifestData","kind":"calls","metadata":{"unresolvedName":"setManifestData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","to":"symbol-name:setManifestDefinitionId","kind":"calls","metadata":{"unresolvedName":"setManifestDefinitionId"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"external:toolType.default_port?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.default_port?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"external:toolType.readiness_probe?.timeout?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.readiness_probe?.timeout?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"external:toolType.readiness_probe?.interval?.toString","kind":"calls","metadata":{"unresolvedName":"toolType.readiness_probe?.interval?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"external:toolType.required_variables?.join","kind":"calls","metadata":{"unresolvedName":"toolType.required_variables?.join"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"symbol-name:setToolTypeError","kind":"calls","metadata":{"unresolvedName":"setToolTypeError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"symbol-name:setManifestData","kind":"calls","metadata":{"unresolvedName":"setManifestData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","to":"symbol-name:setManifestDefinitionId","kind":"calls","metadata":{"unresolvedName":"setManifestDefinitionId"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"calls","metadata":{"unresolvedName":"populateToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"symbol-name:setRightPanelTab","kind":"calls","metadata":{"unresolvedName":"setRightPanelTab"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleSelectToolType","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"calls","metadata":{"unresolvedName":"resetToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"symbol-name:setRightPanelTab","kind":"calls","metadata":{"unresolvedName":"setRightPanelTab"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleCreateNew","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:setToolTypeError","kind":"calls","metadata":{"unresolvedName":"setToolTypeError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.name.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.display_name.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.display_name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.default_port.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.default_port.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:isNaN","kind":"calls","metadata":{"unresolvedName":"isNaN"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:template.trim","kind":"calls","metadata":{"unresolvedName":"template.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.required_variables\n .split(\",\")\n .map","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split(\",\")\n .map"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.required_variables\n .split","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.required_variables\n .split"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:v.trim","kind":"calls","metadata":{"unresolvedName":"v.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.readiness_command.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.readiness_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:parseInt","kind":"calls","metadata":{"unresolvedName":"parseInt"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.description.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.description.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.category.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.category.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"external:toolTypeForm.startup_command.trim","kind":"calls","metadata":{"unresolvedName":"toolTypeForm.startup_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:createToolType","kind":"calls","metadata":{"unresolvedName":"createToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:updateToolType","kind":"calls","metadata":{"unresolvedName":"updateToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_types.ts:deleteToolType","kind":"calls","metadata":{"unresolvedName":"deleteToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"calls","metadata":{"unresolvedName":"resetToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","to":"symbol-name:setConfigForm","kind":"calls","metadata":{"unresolvedName":"setConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","to":"symbol-name:setConfigError","kind":"calls","metadata":{"unresolvedName":"setConfigError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","to":"symbol-name:setSelectedConfig","kind":"calls","metadata":{"unresolvedName":"setSelectedConfig"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"calls","metadata":{"unresolvedName":"resetConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateConfig","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"symbol-name:setConfigForm","kind":"calls","metadata":{"unresolvedName":"setConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"external:config.port_override?.toString","kind":"calls","metadata":{"unresolvedName":"config.port_override?.toString"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"symbol-name:setConfigError","kind":"calls","metadata":{"unresolvedName":"setConfigError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditConfig","to":"symbol-name:setSelectedConfig","kind":"calls","metadata":{"unresolvedName":"setSelectedConfig"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"symbol-name:setConfigError","kind":"calls","metadata":{"unresolvedName":"setConfigError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:configForm.key.trim","kind":"calls","metadata":{"unresolvedName":"configForm.key.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:configForm.env_vars_json.trim","kind":"calls","metadata":{"unresolvedName":"configForm.env_vars_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:configForm.volumes_json.trim","kind":"calls","metadata":{"unresolvedName":"configForm.volumes_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"symbol-name:Number","kind":"calls","metadata":{"unresolvedName":"Number"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:configForm.start_command.trim","kind":"calls","metadata":{"unresolvedName":"configForm.start_command.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"external:configForm.working_directory.trim","kind":"calls","metadata":{"unresolvedName":"configForm.working_directory.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:updateToolConfig","kind":"calls","metadata":{"unresolvedName":"updateToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:createToolConfig","kind":"calls","metadata":{"unresolvedName":"createToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"symbol-name:setSelectedConfig","kind":"calls","metadata":{"unresolvedName":"setSelectedConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"calls","metadata":{"unresolvedName":"resetConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleConfigSubmit","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","to":"/home/alex/projects/headquarter/apps/web/src/api/tool_configs.ts:deleteToolConfig","kind":"calls","metadata":{"unresolvedName":"deleteToolConfig"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteConfig","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","to":"symbol-name:setFolderForm","kind":"calls","metadata":{"unresolvedName":"setFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","to":"symbol-name:setFolderError","kind":"calls","metadata":{"unresolvedName":"setFolderError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","to":"symbol-name:setSelectedFolder","kind":"calls","metadata":{"unresolvedName":"setSelectedFolder"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"calls","metadata":{"unresolvedName":"resetFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openCreateFolder","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","to":"symbol-name:setFolderForm","kind":"calls","metadata":{"unresolvedName":"setFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","to":"external:JSON.stringify","kind":"calls","metadata":{"unresolvedName":"JSON.stringify"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","to":"symbol-name:setFolderError","kind":"calls","metadata":{"unresolvedName":"setFolderError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:openEditFolder","to":"symbol-name:setSelectedFolder","kind":"calls","metadata":{"unresolvedName":"setSelectedFolder"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:e.preventDefault","kind":"calls","metadata":{"unresolvedName":"e.preventDefault"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"symbol-name:setFolderError","kind":"calls","metadata":{"unresolvedName":"setFolderError"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:folderForm.name.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.name.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:folderForm.mount_path.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.mount_path.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:folderForm.files_json.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.files_json.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:JSON.parse","kind":"calls","metadata":{"unresolvedName":"JSON.parse"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"external:folderForm.description.trim","kind":"calls","metadata":{"unresolvedName":"folderForm.description.trim"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:updateConfigFolder","kind":"calls","metadata":{"unresolvedName":"updateConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:createConfigFolder","kind":"calls","metadata":{"unresolvedName":"createConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"symbol-name:setSelectedFolder","kind":"calls","metadata":{"unresolvedName":"setSelectedFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"calls","metadata":{"unresolvedName":"resetFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleFolderSubmit","to":"/home/alex/projects/headquarter/apps/web/src/utils/errors.ts:extractErrorMessage","kind":"calls","metadata":{"unresolvedName":"extractErrorMessage"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","to":"/home/alex/projects/headquarter/apps/web/src/api/config_folders.ts:deleteConfigFolder","kind":"calls","metadata":{"unresolvedName":"deleteConfigFolder"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","to":"symbol-name:loadData","kind":"calls","metadata":{"unresolvedName":"loadData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteFolder","to":"symbol-name:alert","kind":"calls","metadata":{"unresolvedName":"alert"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"calls","metadata":{"unresolvedName":"resetToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"calls","metadata":{"unresolvedName":"populateToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setIsCreating","kind":"calls","metadata":{"unresolvedName":"setIsCreating"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"calls","metadata":{"unresolvedName":"handleDeleteToolType"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setSelectedToolTypeId","kind":"calls","metadata":{"unresolvedName":"setSelectedToolTypeId"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"external:window.confirm","kind":"calls","metadata":{"unresolvedName":"window.confirm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleToolTypeSubmit","kind":"calls","metadata":{"unresolvedName":"handleToolTypeSubmit"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setMobileView","kind":"calls","metadata":{"unresolvedName":"setMobileView"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:preventDefault","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:preventDefault","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"external:e.stopPropagation","kind":"calls","metadata":{"unresolvedName":"e.stopPropagation"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:handleDeleteToolType","kind":"calls","metadata":{"unresolvedName":"handleDeleteToolType"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setManifestData","kind":"calls","metadata":{"unresolvedName":"setManifestData"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeForm","kind":"calls","metadata":{"unresolvedName":"setToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setToolTypeDirty","kind":"calls","metadata":{"unresolvedName":"setToolTypeDirty"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetToolTypeForm","kind":"calls","metadata":{"unresolvedName":"resetToolTypeForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:populateToolTypeForm","kind":"calls","metadata":{"unresolvedName":"populateToolTypeForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setShowConfigForm","kind":"calls","metadata":{"unresolvedName":"setShowConfigForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetConfigForm","kind":"calls","metadata":{"unresolvedName":"resetConfigForm"}},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"contains"},{"from":"file:/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","kind":"defines"},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"symbol-name:setShowFolderForm","kind":"calls","metadata":{"unresolvedName":"setShowFolderForm"}},{"from":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:","to":"/home/alex/projects/headquarter/apps/web/src/pages/tool-workshop.tsx:resetFolderForm","kind":"calls","metadata":{"unresolvedName":"resetFolderForm"}}]} \ No newline at end of file diff --git a/apps/web/.pi-lens/cache/tsx-rules-v2.json b/apps/web/.pi-lens/cache/tsx-rules-v2.json new file mode 100644 index 0000000..49f2cfc --- /dev/null +++ b/apps/web/.pi-lens/cache/tsx-rules-v2.json @@ -0,0 +1,36 @@ +{ + "version": "v2", + "timestamp": 1779892231625, + "ruleHash": "0a2423849fae7580", + "queries": [ + { + "id": "dangerously-set-inner-html", + "name": "Dangerously Set Inner HTML", + "severity": "error", + "language": "tsx", + "message": "dangerouslySetInnerHTML — XSS risk, sanitize user input", + "query": " (jsx_attribute\n (property_identifier) @ATTR\n (#match? @ATTR \"dangerouslySetInnerHTML\"))", + "metavars": [ + "ATTR" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/tsx/dangerously-set-inner-html.yml" + }, + { + "id": "no-nested-links", + "name": "Nested anchor tags", + "severity": "error", + "language": "tsx", + "message": "Nested tags are invalid HTML and cause unexpected behavior", + "query": " (jsx_element\n open_tag: (jsx_opening_element\n (identifier) @OUTER\n (#eq? @OUTER \"a\"))\n (jsx_element\n open_tag: (jsx_opening_element\n (identifier) @INNER\n (#eq? @INNER \"a\"))))", + "metavars": [ + "OUTER", + "INNER" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml" + } + ] +} \ No newline at end of file diff --git a/apps/web/.pi-lens/cache/typescript-rules-v2.json b/apps/web/.pi-lens/cache/typescript-rules-v2.json new file mode 100644 index 0000000..fe23553 --- /dev/null +++ b/apps/web/.pi-lens/cache/typescript-rules-v2.json @@ -0,0 +1,477 @@ +{ + "version": "v2", + "timestamp": 1779889832502, + "ruleHash": "45ab8be323739a4e", + "queries": [ + { + "id": "console-statement", + "name": "Console Statement", + "severity": "warning", + "language": "typescript", + "message": "{{METHOD}} — remove debug statements before committing", + "query": " (call_expression\n function: (member_expression\n object: (identifier) @OBJ (#eq? @OBJ \"console\")\n property: (property_identifier) @METHOD (#not-eq? @METHOD \"dbg\"))\n arguments: (arguments) @ARGS)", + "metavars": [ + "OBJ", + "METHOD", + "ARGS" + ], + "post_filter": "not_in_test_block # skip test blocks — no-console-in-tests handles that case", + "defect_class": "safety", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/console-statement.yml" + }, + { + "id": "debugger-statement", + "name": "Debugger Statement", + "severity": "error", + "language": "typescript", + "message": "Debugger statement — remove before committing", + "query": " (debugger_statement) @DEBUGGER", + "metavars": [ + "DEBUGGER" + ], + "defect_class": "safety", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/debugger.yml" + }, + { + "id": "deep-nesting", + "name": "Deep Nesting", + "severity": "warning", + "language": "typescript", + "message": "Deep nesting (3+ levels) — consider early returns or extract functions", + "query": " [\n ;; Pattern 1: if inside if inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (if_statement\n consequence: (statement_block\n (if_statement) @IF_NESTED)))))\n\n ;; Pattern 2: for inside if inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (if_statement\n consequence: (statement_block\n (for_statement) @FOR_NESTED)))))\n\n ;; Pattern 3: while inside if inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (if_statement\n consequence: (statement_block\n (while_statement) @WHILE_NESTED)))))\n\n ;; Pattern 4: try inside if inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (if_statement\n consequence: (statement_block\n (try_statement) @TRY_NESTED)))))\n\n ;; Pattern 5: if inside for inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (for_statement\n body: (statement_block\n (if_statement) @IF_IN_FOR)))))\n\n ;; Pattern 6: if inside while inside if\n (statement_block\n (if_statement\n consequence: (statement_block\n (while_statement\n body: (statement_block\n (if_statement) @IF_IN_WHILE)))))\n\n ;; Pattern 7: for inside for inside for\n (statement_block\n (for_statement\n body: (statement_block\n (for_statement\n body: (statement_block\n (for_statement) @FOR_NESTED)))))\n ]", + "metavars": [ + "IF_NESTED", + "FOR_NESTED", + "WHILE_NESTED", + "TRY_NESTED", + "IF_IN_FOR", + "IF_IN_WHILE" + ], + "defect_class": "safety", + "inline_tier": "review", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/deep-nesting.yml" + }, + { + "id": "deep-promise-chain", + "name": "Deep Promise Chain (4+ levels)", + "severity": "warning", + "language": "typescript", + "message": "Promise chain {{M1}} → {{M2}} → {{M3}} → {{M4}} — consider async/await", + "query": " (call_expression\n function: (member_expression\n object: (call_expression\n function: (member_expression\n object: (call_expression\n function: (member_expression\n object: (call_expression\n function: (member_expression\n property: (property_identifier) @M1)\n arguments: (arguments))\n property: (property_identifier) @M2)\n arguments: (arguments))\n property: (property_identifier) @M3)\n arguments: (arguments))\n property: (property_identifier) @M4)\n arguments: (arguments)\n (#match? @M1 \"^(then|catch|finally)$\")\n (#match? @M2 \"^(then|catch|finally)$\")\n (#match? @M3 \"^(then|catch|finally)$\")\n (#match? @M4 \"^(then|catch|finally)$\"))", + "metavars": [ + "M1", + "M2", + "M3", + "M4" + ], + "defect_class": "async-misuse", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/deep-promise-chain.yml" + }, + { + "id": "default-not-last", + "name": "Default Clauses Should Be Last", + "severity": "error", + "language": "typescript", + "message": "default clause should be the last case", + "query": " (switch_statement\n body: (switch_body\n (switch_default) @DEFAULT\n (switch_case) @AFTER_CASE))", + "metavars": [ + "DEFAULT", + "AFTER_CASE" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/default-not-last.yml" + }, + { + "id": "duplicate-function-arg", + "name": "Function Argument Names Should Be Unique", + "severity": "error", + "language": "typescript", + "message": "Duplicate parameter name '{{NAME}}'", + "query": " (function_declaration\n parameters: (formal_parameters\n (identifier) @PARAM1\n (identifier) @PARAM2))\n (arrow_function\n parameters: (formal_parameters\n (identifier) @PARAM1\n (identifier) @PARAM2))", + "metavars": [ + "PARAM1", + "PARAM2" + ], + "post_filter": "same_param_name", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml" + }, + { + "id": "empty-switch-case", + "name": "Switch Cases Should Not Be Empty", + "severity": "error", + "language": "typescript", + "message": "Switch case should not be empty", + "query": " (switch_statement\n body: (switch_body\n (switch_case\n consequence: (statement_block) @BLOCK)))", + "metavars": [ + "BLOCK" + ], + "post_filter": "is_empty_block", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/empty-switch-case.yml" + }, + { + "id": "no-eval", + "name": "Eval Usage", + "severity": "error", + "language": "typescript", + "message": "eval() detected — security risk, never use eval", + "query": " (call_expression\n function: (identifier) @FUNC\n (#eq? @FUNC \"eval\")\n arguments: (arguments) @ARGS)", + "metavars": [ + "FUNC", + "ARGS" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/eval.yml" + }, + { + "id": "ts-incomplete-assertion", + "name": "Incomplete Test Assertion", + "severity": "error", + "language": "typescript", + "message": "Incomplete assertion — expect() chain is not called", + "query": " (call_expression\n function: (identifier) @EXPECT\n (#eq? @EXPECT \"expect\")\n arguments: (arguments)) @EXPR", + "metavars": [ + "EXPECT", + "EXPR" + ], + "post_filter": "incomplete_assertion", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/incomplete-assertion.yml" + }, + { + "id": "infinite-loop", + "name": "Loops Should Not Be Infinite", + "severity": "error", + "language": "typescript", + "message": "Loop appears to be infinite with no termination condition", + "query": " (while_statement\n condition: (true)\n body: (statement_block) @BODY)\n (for_statement\n condition: (null)\n body: (statement_block) @BODY)", + "metavars": [ + "BODY" + ], + "post_filter": "no_break_or_return_in_body", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/infinite-loop.yml" + }, + { + "id": "mixed-async-styles", + "name": "Mixed Async/Await and Promise Chains", + "severity": "warning", + "language": "typescript", + "message": "Mixed async/await + promise chains — use consistent async style", + "query": " (function_declaration\n (async_modifier)\n body: (statement_block) @BODY)\n\n# Post-filter: Check if body contains both await and .then()", + "metavars": [ + "BODY" + ], + "post_filter": "has_mixed_async", + "defect_class": "async-misuse", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/mixed-async-styles.yml" + }, + { + "id": "no-console-in-tests", + "name": "Console Statement in Test", + "severity": "warning", + "language": "typescript", + "message": "console.{{METHOD}} in test block — use proper assertions or logging", + "query": " (call_expression\n function: (member_expression\n object: (identifier) @OBJ (#eq? @OBJ \"console\")\n property: (property_identifier) @METHOD)\n arguments: (arguments) @ARGS)", + "metavars": [ + "OBJ", + "METHOD", + "ARGS" + ], + "post_filter": "in_test_block", + "defect_class": "safety", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/no-console-in-tests.yml" + }, + { + "id": "self-assignment", + "name": "Variables Should Not Be Self-Assigned", + "severity": "error", + "language": "typescript", + "message": "'{{VAR}}' is assigned to itself", + "query": " (assignment_expression\n left: (identifier) @VAR\n right: (identifier) @SAME\n (#eq? @VAR @SAME))", + "metavars": [ + "VAR", + "SAME" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/self-assignment.yml" + }, + { + "id": "sql-injection", + "name": "SQL Injection Risk", + "severity": "error", + "language": "typescript", + "message": "SQL injection risk — use parameterized queries, never interpolate into SQL", + "query": " (call_expression\n function: [\n (identifier) @SQL_FUNC\n (member_expression property: (property_identifier) @SQL_FUNC)\n ]\n arguments: (arguments\n (template_string (template_substitution) @INTERPOLATION))\n (#match? @SQL_FUNC \"^(query|execute|exec|run)$\"))", + "metavars": [ + "SQL_FUNC", + "INTERPOLATION" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml" + }, + { + "id": "switch-case-termination", + "name": "Switch Cases Should End With Terminating Statement", + "severity": "error", + "language": "typescript", + "message": "Switch case should end with break, return, throw, or continue", + "query": " (switch_statement\n body: (switch_body\n (switch_case\n consequence: (statement_block\n (expression_statement) @LAST))\n (switch_case) @NEXT))", + "metavars": [ + "LAST", + "NEXT" + ], + "post_filter": "no_terminating_statement", + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/switch-case-termination.yml" + }, + { + "id": "switch-non-case-labels-ts", + "name": "Switch Should Not Contain Non-Case Labels", + "severity": "error", + "language": "typescript", + "message": "switch statements should not contain non-case labels", + "query": " (switch_statement\n body: (switch_body\n (switch_case\n (labeled_statement\n (statement_identifier) @LABEL) @LABELED)))", + "metavars": [ + "LABEL", + "LABELED" + ], + "defect_class": "correctness", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/switch-non-case-labels.yml" + }, + { + "id": "ts-command-injection", + "name": "Command Injection Sink", + "severity": "error", + "language": "typescript", + "message": "Potential command injection sink — avoid child_process command execution with untrusted input", + "query": " [\n (call_expression\n function: (member_expression\n object: (identifier) @MOD\n property: (property_identifier) @FN)\n arguments: (arguments) @ARGS\n (#eq? @MOD \"child_process\")\n (#match? @FN \"^(exec|execSync)$\"))\n (call_expression\n function: (member_expression\n object: (member_expression\n object: (identifier) @MOD\n property: (property_identifier) @NS)\n property: (property_identifier) @FN)\n arguments: (arguments) @ARGS\n (#eq? @MOD \"child_process\")\n (#match? @FN \"^(exec|execSync)$\"))\n ]", + "metavars": [ + "MOD", + "NS", + "FN", + "ARGS" + ], + "post_filter": "ts_command_injection_sink", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-command-injection.yml" + }, + { + "id": "ts-detached-async-call", + "name": "Detached Async Call", + "severity": "warning", + "language": "typescript", + "message": "Detached async call — ensure this Promise is awaited or explicitly handled", + "query": " (expression_statement\n (call_expression\n function: [\n (identifier) @FN\n (member_expression\n property: (property_identifier) @FN)\n ]\n arguments: (arguments) @ARGS)\n (#match? @FN \"(Async$|fetch$|request$)\"))", + "metavars": [ + "FN", + "ARGS" + ], + "post_filter": "ts_detached_async_call", + "defect_class": "async-misuse", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-detached-async-call.yml" + }, + { + "id": "ts-dynamic-require", + "name": "Dynamic Require Injection", + "severity": "error", + "language": "typescript", + "message": "Dynamic require() — non-literal argument allows loading arbitrary modules", + "query": " (call_expression\n function: (identifier) @FN\n arguments: (arguments [(identifier) (member_expression) (call_expression) (await_expression)] @ARG)\n (#eq? @FN \"require\"))", + "metavars": [ + "FN", + "ARG" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-dynamic-require.yml" + }, + { + "id": "ts-hallucinated-react-import", + "name": "Hallucinated React Import", + "severity": "error", + "language": "typescript", + "message": "'{NAME}' is a Next.js API, not from 'react' — import from 'next/{CORRECT}' instead", + "query": " (import_statement\n (import_clause\n (named_imports\n (import_specifier\n name: (identifier) @NAME)))\n source: (string) @SRC)\n (#match? @SRC \"^['\\\"]react['\\\"]$\")\n (#match? @NAME \"^(useRouter|usePathname|useSearchParams|useParams|Link|Image|Script|Head|getServerSideProps|getStaticProps|getStaticPaths|NextPage|NextApiRequest|NextApiResponse|GetServerSideProps|GetStaticProps|GetStaticPaths|notFound|redirect|permanentRedirect)$\")", + "metavars": [ + "NAME", + "SRC" + ], + "post_filter": "match_captures", + "post_filter_params": { + "SRC": "^['\\\"]react['\\\"]$", + "NAME": "^(useRouter|usePathname|useSearchParams|useParams|Link|Image|Script|Head|getServerSideProps|getStaticProps|getStaticPaths|NextPage|NextApiRequest|NextApiResponse|GetServerSideProps|GetStaticProps|GetStaticPaths|notFound|redirect|permanentRedirect)$" + }, + "defect_class": "hallucination", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-hallucinated-react-import.yml" + }, + { + "id": "ts-insecure-random", + "name": "Insecure Randomness", + "severity": "warning", + "language": "typescript", + "message": "Insecure randomness source detected — use crypto.getRandomValues or secure RNG APIs", + "query": " (variable_declarator\n name: (identifier) @VAR\n value: (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments) @ARGS)\n (#eq? @OBJ \"Math\")\n (#eq? @FN \"random\")\n (#match? @VAR \"(?i)(token|secret|password|key|nonce|salt|csrf|auth|session|credential|hash|otp|pin)\"))", + "metavars": [ + "OBJ", + "FN", + "ARGS", + "VAR" + ], + "post_filter": "ts_insecure_random_source", + "defect_class": "injection", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-insecure-random.yml" + }, + { + "id": "ts-nosql-injection", + "name": "NoSQL Injection", + "severity": "error", + "language": "typescript", + "message": "NoSQL injection — $where executes JavaScript server-side and must never be used with user input", + "query": " (pair\n key: [(property_identifier) (string)] @KEY\n (#match? @KEY \"\\\\$where\"))", + "metavars": [ + "KEY" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-nosql-injection.yml" + }, + { + "id": "ts-open-redirect", + "name": "Open Redirect", + "severity": "error", + "language": "typescript", + "message": "Open redirect — unvalidated URL in redirect/location lets attackers send users to malicious sites", + "query": " [\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (identifier) @URL)\n (#match? @OBJ \"^(res|response|ctx|context)$\")\n (#eq? @FN \"redirect\"))\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (member_expression) @URL)\n (#match? @OBJ \"^(res|response|ctx|context)$\")\n (#eq? @FN \"redirect\"))\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (call_expression) @URL)\n (#match? @OBJ \"^(res|response|ctx|context)$\")\n (#eq? @FN \"redirect\"))\n ]\n [\n (assignment_expression\n left: (member_expression\n object: (member_expression\n object: (identifier) @WIN\n property: (property_identifier) @LOC)\n property: (property_identifier) @PROP)\n right: (identifier) @VALUE\n (#eq? @WIN \"window\")\n (#eq? @LOC \"location\")\n (#eq? @PROP \"href\"))\n (assignment_expression\n left: (member_expression\n object: (member_expression\n object: (identifier) @WIN\n property: (property_identifier) @LOC)\n property: (property_identifier) @PROP)\n right: (member_expression) @VALUE\n (#eq? @WIN \"window\")\n (#eq? @LOC \"location\")\n (#eq? @PROP \"href\"))\n (assignment_expression\n left: (member_expression\n object: (member_expression\n object: (identifier) @WIN\n property: (property_identifier) @LOC)\n property: (property_identifier) @PROP)\n right: (call_expression) @VALUE\n (#eq? @WIN \"window\")\n (#eq? @LOC \"location\")\n (#eq? @PROP \"href\"))\n ]", + "metavars": [ + "OBJ", + "FN", + "URL", + "WIN", + "LOC", + "PROP", + "VALUE" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-open-redirect.yml" + }, + { + "id": "ts-react-antipatterns", + "name": "React Anti-Pattern", + "severity": "warning", + "language": "typescript", + "message": "React anti-pattern: setState inside a loop causes multiple re-renders — batch with a single state update", + "query": " [\n (for_statement\n (statement_block) @BODY\n (#match? @BODY \"set[A-Z]\")\n (#not-match? @BODY \"set(Timeout|Interval|Immediate)\"))\n (for_in_statement\n (statement_block) @BODY\n (#match? @BODY \"set[A-Z]\")\n (#not-match? @BODY \"set(Timeout|Interval|Immediate)\"))\n (while_statement\n (statement_block) @BODY\n (#match? @BODY \"set[A-Z]\")\n (#not-match? @BODY \"set(Timeout|Interval|Immediate)\"))\n ]", + "metavars": [ + "BODY" + ], + "defect_class": "logic-error", + "inline_tier": "warning", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-react-antipatterns.yml" + }, + { + "id": "ts-ssrf", + "name": "SSRF Risk", + "severity": "error", + "language": "typescript", + "message": "Potential SSRF sink — validate and allowlist outbound URLs", + "query": " [\n (call_expression\n function: (identifier) @FN\n arguments: (arguments [(identifier) (member_expression) (call_expression) (await_expression)] @URL)\n (#match? @FN \"^(fetch|get|post|put|patch|delete|request)$\"))\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments [(identifier) (member_expression) (call_expression) (await_expression)] @URL)\n (#match? @FN \"^(fetch|get|post|put|patch|delete|request)$\"))\n ]", + "metavars": [ + "OBJ", + "FN", + "URL" + ], + "post_filter": "ts_ssrf_sink", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-ssrf.yml" + }, + { + "id": "ts-weak-hash", + "name": "Weak Hash Primitive", + "severity": "error", + "language": "typescript", + "message": "Weak hash primitive selected (md5/sha1) — use sha256+ for security-sensitive contexts", + "query": " (call_expression\n function: (member_expression\n property: (property_identifier) @FN)\n arguments: (arguments\n (string (string_fragment) @ALG)\n (_)*)\n (#eq? @FN \"createHash\")\n (#match? @ALG \"^(md5|sha1)$\"))", + "metavars": [ + "FN", + "ALG" + ], + "post_filter": "ts_weak_hash_algorithm", + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-weak-hash.yml" + }, + { + "id": "ts-xss-dom-sink", + "name": "XSS DOM Sink", + "severity": "error", + "language": "typescript", + "message": "XSS risk — dynamic value written to innerHTML/outerHTML or document.write()", + "query": " [\n (assignment_expression\n left: (member_expression\n property: (property_identifier) @PROP)\n right: (identifier) @VALUE\n (#match? @PROP \"^(innerHTML|outerHTML)$\"))\n (assignment_expression\n left: (member_expression\n property: (property_identifier) @PROP)\n right: (member_expression) @VALUE\n (#match? @PROP \"^(innerHTML|outerHTML)$\"))\n (assignment_expression\n left: (member_expression\n property: (property_identifier) @PROP)\n right: (call_expression) @VALUE\n (#match? @PROP \"^(innerHTML|outerHTML)$\"))\n (assignment_expression\n left: (member_expression\n property: (property_identifier) @PROP)\n right: (await_expression) @VALUE\n (#match? @PROP \"^(innerHTML|outerHTML)$\"))\n ]\n [\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (identifier) @ARG)\n (#eq? @OBJ \"document\")\n (#match? @FN \"^(write|writeln)$\"))\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (member_expression) @ARG)\n (#eq? @OBJ \"document\")\n (#match? @FN \"^(write|writeln)$\"))\n (call_expression\n function: (member_expression\n object: (identifier) @OBJ\n property: (property_identifier) @FN)\n arguments: (arguments (call_expression) @ARG)\n (#eq? @OBJ \"document\")\n (#match? @FN \"^(write|writeln)$\"))\n ]", + "metavars": [ + "PROP", + "VALUE", + "OBJ", + "FN", + "ARG" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/ts-xss-dom-sink.yml" + }, + { + "id": "unsafe-regex", + "name": "Dynamic Regex Construction", + "severity": "error", + "language": "typescript", + "message": "Dynamic regex from user input — can cause ReDoS (Regular Expression Denial of Service)", + "query": " (new_expression\n constructor: (identifier) @CTOR\n (#eq? @CTOR \"RegExp\")\n arguments: (arguments\n (template_string\n (template_substitution) @INTERPOLATION) @PATTERN)\n (#not-match? @INTERPOLATION \"escape|Escape|replace\"))", + "metavars": [ + "CTOR", + "INTERPOLATION", + "PATTERN" + ], + "defect_class": "injection", + "inline_tier": "blocking", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/unsafe-regex.yml" + }, + { + "id": "variable-shadowing", + "name": "Variable Shadowing", + "severity": "warning", + "language": "typescript", + "message": "Variable '{{NAME}}' shadows a parameter — use a distinct name", + "query": " (function_declaration\n parameters: (formal_parameters\n (required_parameter\n pattern: (identifier) @PARAM))\n body: (statement_block\n (lexical_declaration\n (variable_declarator\n name: (identifier) @NAME))))", + "metavars": [ + "PARAM", + "NAME" + ], + "post_filter": "name_matches_param", + "defect_class": "safety", + "inline_tier": "review", + "filePath": "/home/alex/.npm-global/lib/node_modules/pi-lens/rules/tree-sitter-queries/typescript/variable-shadowing.yml" + } + ] +} \ No newline at end of file diff --git a/apps/web/src/api/terminal.ts b/apps/web/src/api/terminal.ts new file mode 100644 index 0000000..ad10d9d --- /dev/null +++ b/apps/web/src/api/terminal.ts @@ -0,0 +1,77 @@ +import { apiClient } from "./client"; + +export interface TerminalSession { + id: string; + name: string; + status: string; + has_websockets: boolean; + created_at: string; + last_activity_at: string | null; +} + +export interface TerminalSessionListResponse { + sessions: TerminalSession[]; +} + +export interface TerminalSessionCreateRequest { + name?: string; +} + +export interface TerminalSessionCreateResponse { + id: string; + name: string; + status: string; + created_at: string; +} + +export async function listTerminalSessions( + instanceId: string, +): Promise { + const response = await apiClient.get( + `/instances/${instanceId}/terminal/sessions`, + ); + return response.data.sessions; +} + +export async function createTerminalSession( + instanceId: string, + name?: string, +): Promise { + const response = await apiClient.post( + `/instances/${instanceId}/terminal/sessions`, + { name }, + ); + return response.data; +} + +export async function closeTerminalSession( + instanceId: string, + sessionId: string, +): Promise<{ status: string; session_id: string }> { + const response = await apiClient.delete( + `/instances/${instanceId}/terminal/sessions/${sessionId}`, + ); + return response.data; +} + +export async function resetTerminalSession( + instanceId: string, + sessionId: string, +): Promise<{ id: string; name: string; status: string }> { + const response = await apiClient.post( + `/instances/${instanceId}/terminal/sessions/${sessionId}/reset`, + ); + return response.data; +} + +export async function renameTerminalSession( + instanceId: string, + sessionId: string, + name: string, +): Promise<{ id: string; name: string }> { + const response = await apiClient.post( + `/instances/${instanceId}/terminal/sessions/${sessionId}/rename`, + { name }, + ); + return response.data; +} diff --git a/apps/web/src/components/terminal-session-tabs.test.tsx b/apps/web/src/components/terminal-session-tabs.test.tsx new file mode 100644 index 0000000..b90eaac --- /dev/null +++ b/apps/web/src/components/terminal-session-tabs.test.tsx @@ -0,0 +1,161 @@ +import { render, screen, fireEvent, cleanup } from "@testing-library/react"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { + TerminalSessionTabs, + type TerminalSessionInfo, +} from "./terminal-session-tabs"; + +const mockSessions: TerminalSessionInfo[] = [ + { id: "s1", name: "Session 1", status: "connected" }, + { id: "s2", name: "Session 2", status: "connecting" }, + { id: "s3", name: "Session 3", status: "disconnected" }, +]; + +afterEach(() => { + cleanup(); +}); + +describe("TerminalSessionTabs", () => { + it("renders all tabs", () => { + render( + + ); + + expect(screen.getByText("Session 1")).toBeInTheDocument(); + expect(screen.getByText("Session 2")).toBeInTheDocument(); + expect(screen.getByText("Session 3")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: /new session/i })).toBeInTheDocument(); + }); + + it("clicking a tab calls onSelect", () => { + const onSelect = vi.fn(); + render( + + ); + + fireEvent.click(screen.getAllByText("Session 2")[0]); + expect(onSelect).toHaveBeenCalledWith("s2"); + }); + + it("close button calls onClose after confirmation", () => { + const onClose = vi.fn(); + render( + + ); + + const closeButton = screen.getByLabelText("Close session Session 1"); + // First click shows confirm + fireEvent.click(closeButton); + expect(screen.getByText("Close?")).toBeInTheDocument(); + + // Click confirm text + fireEvent.click(screen.getByText("Close?")); + expect(onClose).toHaveBeenCalledWith("s1"); + }); + + it("double-click enables rename and Enter commits", () => { + const onRename = vi.fn(); + render( + + ); + + fireEvent.doubleClick(screen.getAllByText("Session 1")[0]); + const input = screen.getByLabelText("Rename session"); + expect(input).toBeInTheDocument(); + + fireEvent.change(input, { target: { value: "Renamed" } }); + fireEvent.keyDown(input, { key: "Enter" }); + expect(onRename).toHaveBeenCalledWith("s1", "Renamed"); + }); + + it("double-click enables rename and Escape cancels", () => { + const onRename = vi.fn(); + render( + + ); + + fireEvent.doubleClick(screen.getAllByText("Session 1")[0]); + const input = screen.getByLabelText("Rename session"); + fireEvent.change(input, { target: { value: "Renamed" } }); + fireEvent.keyDown(input, { key: "Escape" }); + expect(onRename).not.toHaveBeenCalled(); + expect(screen.getByText("Session 1")).toBeInTheDocument(); + }); + + it("plus button is disabled at 5 sessions", () => { + const fiveSessions: TerminalSessionInfo[] = Array.from({ length: 5 }, (_, i) => ({ + id: `s${i + 1}`, + name: `Session ${i + 1}`, + status: "connected", + })); + + render( + + ); + + const newButton = screen.getByRole("button", { name: /new session/i }); + expect(newButton).toBeDisabled(); + }); + + it("status dot reflects connection state", () => { + render( + + ); + + const tabs = screen.getAllByRole("tab"); + expect(tabs).toHaveLength(3); + expect(tabs[0].querySelector(".connected")).toBeInTheDocument(); + expect(tabs[1].querySelector(".connecting")).toBeInTheDocument(); + expect(tabs[2].querySelector(".disconnected")).toBeInTheDocument(); + }); +}); diff --git a/apps/web/src/components/terminal-session-tabs.tsx b/apps/web/src/components/terminal-session-tabs.tsx new file mode 100644 index 0000000..0ff8c79 --- /dev/null +++ b/apps/web/src/components/terminal-session-tabs.tsx @@ -0,0 +1,167 @@ +import React, { useState, useRef, useCallback } from "react"; + +export interface TerminalSessionInfo { + id: string; + name: string; + status: "connecting" | "connected" | "disconnected" | "error" | "resetting"; +} + +export interface TerminalSessionTabsProps { + sessions: TerminalSessionInfo[]; + activeSessionId: string; + onSelect: (sessionId: string) => void; + onClose: (sessionId: string) => void; + onCreate: () => void; + onRename: (sessionId: string, newName: string) => void; + isMobile?: boolean; +} + +export const TerminalSessionTabs: React.FC = ({ + sessions, + activeSessionId, + onSelect, + onClose, + onCreate, + onRename, + isMobile = false, +}) => { + const [renamingId, setRenamingId] = useState(null); + const [renameValue, setRenameValue] = useState(""); + const [confirmCloseId, setConfirmCloseId] = useState(null); + const renameInputRef = useRef(null); + const scrollRef = useRef(null); + + const handleDoubleClick = useCallback((session: TerminalSessionInfo) => { + setRenamingId(session.id); + setRenameValue(session.name); + requestAnimationFrame(() => { + renameInputRef.current?.focus(); + renameInputRef.current?.select(); + }); + }, []); + + const commitRename = useCallback(() => { + if (renamingId && renameValue.trim()) { + onRename(renamingId, renameValue.trim()); + } + setRenamingId(null); + setRenameValue(""); + }, [renamingId, renameValue, onRename]); + + const cancelRename = useCallback(() => { + setRenamingId(null); + setRenameValue(""); + }, []); + + const handleRenameKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + commitRename(); + } else if (e.key === "Escape") { + cancelRename(); + } + }, + [commitRename, cancelRename], + ); + + const handleCloseClick = useCallback( + (e: React.MouseEvent, sessionId: string) => { + e.stopPropagation(); + if (confirmCloseId === sessionId) { + setConfirmCloseId(null); + onClose(sessionId); + } else { + setConfirmCloseId(sessionId); + // Auto-dismiss confirm after 3s + setTimeout(() => { + setConfirmCloseId((prev) => (prev === sessionId ? null : prev)); + }, 3000); + } + }, + [confirmCloseId, onClose], + ); + + const isMaxSessions = sessions.length >= 5; + + return ( +
+
+ {sessions.map((session) => { + const isActive = session.id === activeSessionId; + const isRenaming = renamingId === session.id; + const isConfirmingClose = confirmCloseId === session.id; + + return ( +
onSelect(session.id)} + onDoubleClick={() => handleDoubleClick(session)} + title={isRenaming ? "" : `${session.name} (${session.status})`} + > +
+ ); + })} + +
+
+ ); +}; diff --git a/apps/web/src/components/terminal.tsx b/apps/web/src/components/terminal.tsx index ca3ffcd..5588328 100644 --- a/apps/web/src/components/terminal.tsx +++ b/apps/web/src/components/terminal.tsx @@ -1,4 +1,10 @@ -import React, { useEffect, useRef, useState, useCallback } from "react"; +import React, { + useEffect, + useImperativeHandle, + useRef, + useState, + useCallback, +} from "react"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; import { WebLinksAddon } from "xterm-addon-web-links"; @@ -9,8 +15,9 @@ import { type ModifierKey, } from "../hooks/use-special-keys"; -interface TerminalProps { +export interface TerminalProps { instanceId: string; + sessionId?: string; onClose?: () => void; isMobile?: boolean; activeModifier?: ModifierKey | null; @@ -28,613 +35,663 @@ interface TerminalProps { ) => void; } +export interface TerminalRef { + fit: () => void; +} + const FONT_SIZE_KEY = "terminal-font-size"; const MIN_FONT_SIZE = 4; const MAX_FONT_SIZE = 24; const RECONNECT_ATTEMPTS = 3; const RECONNECT_DELAY_BASE = 1000; -export const TerminalComponent: React.FC = ({ - instanceId, - onClose, - isMobile = false, - activeModifier, - onModifierChange, - onTerminalReady, -}) => { - const terminalRef = useRef(null); - const hiddenInputRef = useRef(null); - const wsRef = useRef(null); - const termRef = useRef(null); - const fitAddonRef = useRef(null); - const reconnectAttemptsRef = useRef(0); - const onTerminalReadyRef = useRef(onTerminalReady); - onTerminalReadyRef.current = onTerminalReady; - const handleFontSizeChangeRef = useRef<(delta: number) => void>(() => {}); - const [status, setStatus] = useState< - "connecting" | "connected" | "disconnected" | "error" | "resetting" - >("connecting"); - const [error, setError] = useState(null); - const [showResetConfirm, setShowResetConfirm] = useState(false); - const activeModifierRef = useRef(activeModifier); - activeModifierRef.current = activeModifier; - const [fontSize, setFontSize] = useState(() => { - if (typeof window === "undefined") return isMobile ? 8 : 8; - const stored = localStorage.getItem(FONT_SIZE_KEY); - if (stored) { - const parsed = parseInt(stored, 10); - return Math.max(MIN_FONT_SIZE, Math.min(MAX_FONT_SIZE, parsed)); - } - return isMobile ? 8 : 8; - }); - const lastPingRef = useRef(0); - const heartbeatCheckRef = useRef(null); - const isUnmountingRef = useRef(false); - const permanentErrorRef = useRef(null); - - const calculateFontSize = useCallback(() => { - return fontSize; - }, [fontSize]); - - const connectWebSocket = useCallback(() => { - const apiUrl = import.meta.env.VITE_API_BASE_URL || ""; - const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:"; - const wsHost = apiUrl.replace(/^https?:\/\//, "").replace(/\/+$/, ""); - const wsUrl = `${wsProtocol}//${wsHost}/ws/tool-instances/${instanceId}/terminal`; - - // WebSocket connection established - const ws = new WebSocket(wsUrl); - wsRef.current = ws; - - ws.onopen = () => { - setStatus("connected"); - setError(null); - reconnectAttemptsRef.current = 0; - lastPingRef.current = Date.now(); - - // Send current terminal size immediately on connect - if (termRef.current) { - const { cols, rows } = termRef.current; - // Only send if we have valid dimensions - if (cols > 0 && rows > 0) { - ws.send(JSON.stringify({ type: "resize", cols, rows })); - } +export const TerminalComponent = React.forwardRef( + ( + { + instanceId, + sessionId, + onClose, + isMobile = false, + activeModifier, + onModifierChange, + onTerminalReady, + }, + ref, + ) => { + const terminalRef = useRef(null); + const hiddenInputRef = useRef(null); + const wsRef = useRef(null); + const termRef = useRef(null); + const fitAddonRef = useRef(null); + const reconnectAttemptsRef = useRef(0); + const onTerminalReadyRef = useRef(onTerminalReady); + onTerminalReadyRef.current = onTerminalReady; + const handleFontSizeChangeRef = useRef<(delta: number) => void>(() => {}); + const [status, setStatus] = useState< + "connecting" | "connected" | "disconnected" | "error" | "resetting" + >("connecting"); + const [error, setError] = useState(null); + const [showResetConfirm, setShowResetConfirm] = useState(false); + const activeModifierRef = useRef(activeModifier); + activeModifierRef.current = activeModifier; + const [fontSize, setFontSize] = useState(() => { + if (typeof window === "undefined") return isMobile ? 8 : 8; + const stored = localStorage.getItem(FONT_SIZE_KEY); + if (stored) { + const parsed = parseInt(stored, 10); + return Math.max(MIN_FONT_SIZE, Math.min(MAX_FONT_SIZE, parsed)); } + return isMobile ? 8 : 8; + }); + const lastPingRef = useRef(0); + const heartbeatCheckRef = useRef(null); + const isUnmountingRef = useRef(false); + const permanentErrorRef = useRef(null); - // Start heartbeat check - if (heartbeatCheckRef.current) { - window.clearInterval(heartbeatCheckRef.current); - } - heartbeatCheckRef.current = window.setInterval(() => { - const elapsed = Date.now() - lastPingRef.current; - if (elapsed > 60000) { - // No ping for 60 seconds, connection may be dead - ws.close(4000, "Heartbeat timeout"); - } - }, 30000); - }; + const calculateFontSize = useCallback(() => { + return fontSize; + }, [fontSize]); - ws.onmessage = (event) => { - if (!termRef.current) return; + const connectWebSocket = useCallback(() => { + const apiUrl = import.meta.env.VITE_API_BASE_URL || ""; + const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:"; + const wsHost = apiUrl.replace(/^https?:\/\//, "").replace(/\/+$/, ""); + const wsPath = sessionId + ? `/ws/tool-instances/${instanceId}/terminal/${sessionId}` + : `/ws/tool-instances/${instanceId}/terminal`; + const wsUrl = `${wsProtocol}//${wsHost}${wsPath}`; - if (event.data instanceof Blob) { - event.data.arrayBuffer().then((buffer) => { - const data = new Uint8Array(buffer); - termRef.current?.write(data); - }); - } else if (typeof event.data === "string") { - try { - const msg = JSON.parse(event.data); - if (msg.type === "status") { - if (msg.status === "connected") { - setStatus("connected"); - setError(null); - // Clear terminal and refit after reset/reconnect - if (termRef.current) { - termRef.current.clear(); - requestAnimationFrame(() => { - if (fitAddonRef.current && termRef.current) { - fitAddonRef.current.fit(); - const { cols, rows } = termRef.current; - const currentWs = wsRef.current; - if (currentWs?.readyState === WebSocket.OPEN) { - currentWs.send( - JSON.stringify({ type: "resize", cols, rows }), - ); - } - } - }); - } - } else if (msg.status === "resetting") { - setStatus("resetting"); - } - } else if (msg.type === "ping") { - // Respond with pong and update last ping time - lastPingRef.current = Date.now(); - if (ws.readyState === WebSocket.OPEN) { - ws.send(JSON.stringify({ type: "pong" })); - } + // WebSocket connection established + const ws = new WebSocket(wsUrl); + wsRef.current = ws; + + ws.onopen = () => { + setStatus("connected"); + setError(null); + reconnectAttemptsRef.current = 0; + lastPingRef.current = Date.now(); + + // Send current terminal size immediately on connect + if (termRef.current) { + const { cols, rows } = termRef.current; + // Only send if we have valid dimensions + if (cols > 0 && rows > 0) { + ws.send(JSON.stringify({ type: "resize", cols, rows })); } - } catch { - termRef.current?.write(event.data); } - } - }; - ws.onclose = (event) => { - // Clean up heartbeat check - if (heartbeatCheckRef.current) { - window.clearInterval(heartbeatCheckRef.current); - heartbeatCheckRef.current = null; - } + // Start heartbeat check + if (heartbeatCheckRef.current) { + window.clearInterval(heartbeatCheckRef.current); + } + heartbeatCheckRef.current = window.setInterval(() => { + const elapsed = Date.now() - lastPingRef.current; + if (elapsed > 60000) { + // No ping for 60 seconds, connection may be dead + ws.close(4000, "Heartbeat timeout"); + } + }, 30000); + }; - // Permanent errors: do not retry - if (event.code === 4001 || event.code === 4003 || event.code === 4004) { - const reason = event.reason || `Instance error (code: ${event.code})`; - setStatus("error"); - setError(reason); - permanentErrorRef.current = reason; - return; - } + ws.onmessage = (event) => { + if (!termRef.current) return; - if (event.code === 1000) { + if (event.data instanceof Blob) { + event.data.arrayBuffer().then((buffer) => { + const data = new Uint8Array(buffer); + termRef.current?.write(data); + }); + } else if (typeof event.data === "string") { + try { + const msg = JSON.parse(event.data); + if (msg.type === "status") { + if (msg.status === "connected") { + setStatus("connected"); + setError(null); + // Clear terminal and refit after reset/reconnect + if (termRef.current) { + termRef.current.clear(); + requestAnimationFrame(() => { + if (fitAddonRef.current && termRef.current) { + fitAddonRef.current.fit(); + const { cols, rows } = termRef.current; + const currentWs = wsRef.current; + if (currentWs?.readyState === WebSocket.OPEN) { + currentWs.send( + JSON.stringify({ type: "resize", cols, rows }), + ); + } + } + }); + } + } else if (msg.status === "resetting") { + setStatus("resetting"); + } + } else if (msg.type === "ping") { + // Respond with pong and update last ping time + lastPingRef.current = Date.now(); + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: "pong" })); + } + } + } catch { + termRef.current?.write(event.data); + } + } + }; + + ws.onclose = (event) => { + // Clean up heartbeat check + if (heartbeatCheckRef.current) { + window.clearInterval(heartbeatCheckRef.current); + heartbeatCheckRef.current = null; + } + + // Permanent errors: do not retry + if (event.code === 4001 || event.code === 4003 || event.code === 4004) { + const reason = event.reason || `Instance error (code: ${event.code})`; + setStatus("error"); + setError(reason); + permanentErrorRef.current = reason; + return; + } + + if (event.code === 1000) { + setStatus("disconnected"); + return; + } + + if (event.code === 4000) { + // Server closed old connection for concurrent connection - don't reconnect + // The new connection is already established + return; + } + + // Transient errors: attempt reconnection setStatus("disconnected"); - return; - } + setError(`Connection closed (code: ${event.code})`); - if (event.code === 4000) { - // Server closed old connection for concurrent connection - don't reconnect - // The new connection is already established - return; - } + if (reconnectAttemptsRef.current < RECONNECT_ATTEMPTS) { + reconnectAttemptsRef.current++; + const delay = + RECONNECT_DELAY_BASE * + Math.pow(2, reconnectAttemptsRef.current - 1); + setTimeout(() => { + if (isUnmountingRef.current) { + return; + } + if (document.visibilityState !== "hidden") { + connectWebSocket(); + } + }, delay); + } + }; - // Transient errors: attempt reconnection - setStatus("disconnected"); - setError(`Connection closed (code: ${event.code})`); + ws.onerror = () => { + setStatus("error"); + setError("WebSocket error"); + }; - if (reconnectAttemptsRef.current < RECONNECT_ATTEMPTS) { - reconnectAttemptsRef.current++; - const delay = - RECONNECT_DELAY_BASE * Math.pow(2, reconnectAttemptsRef.current - 1); - setTimeout(() => { - if (isUnmountingRef.current) { + return ws; + }, [instanceId, sessionId]); + + useEffect(() => { + if (!terminalRef.current) return; + + // Initialize terminal + const currentFontSize = calculateFontSize(); + const term = new Terminal({ + cursorBlink: true, + fontSize: currentFontSize, + fontFamily: 'Menlo, Monaco, "Courier New", monospace', + lineHeight: 1.2, + letterSpacing: 0, + allowTransparency: false, + theme: { + background: "#1e1e1e", + foreground: "#d4d4d4", + cursor: "#d4d4d4", + selectionBackground: "#264f78", + black: "#000000", + red: "#cd3131", + green: "#0dbc79", + yellow: "#e5e510", + blue: "#2472c8", + magenta: "#bc3fbc", + cyan: "#11a8cd", + white: "#e5e5e5", + brightBlack: "#666666", + brightRed: "#f14c4c", + brightGreen: "#23d18b", + brightYellow: "#f5f543", + brightBlue: "#3b8eea", + brightMagenta: "#d670d6", + brightCyan: "#29b8db", + brightWhite: "#e5e5e5", + }, + }); + + termRef.current = term; + + const fitAddon = new FitAddon(); + fitAddonRef.current = fitAddon; + term.loadAddon(fitAddon); + term.loadAddon(new WebLinksAddon()); + + const container = terminalRef.current; + + // Define fitTerminal before connectWebSocket so it's available in onmessage + const fitTerminal = () => { + if (!fitAddonRef.current || !termRef.current) return; + try { + fitAddonRef.current.fit(); + } catch { + // Ignore fit errors during initialization + return; + } + const { cols, rows } = termRef.current; + // Force refresh if dimensions are valid + if (cols > 0 && rows > 0) { + try { + termRef.current.refresh(0, rows - 1); + } catch { + // Ignore refresh errors + } + } + const currentWs = wsRef.current; + if (currentWs?.readyState === WebSocket.OPEN && cols > 0 && rows > 0) { + currentWs.send(JSON.stringify({ type: "resize", cols, rows })); + } + }; + + // Open xterm first (must happen before fit) + term.open(container); + const ws = connectWebSocket(); + + // Initial fit after layout settles (terminal must be opened first) + let fitAttempts = 0; + const doInitialFit = () => { + if (!container.isConnected) return; + fitAttempts++; + // Ensure container has dimensions before fitting + if (container.clientWidth > 0 && container.clientHeight > 0) { + fitTerminal(); + } else if (fitAttempts < 50) { + // Container not ready yet, try again (max 50 attempts ~ 1s) + requestAnimationFrame(doInitialFit); + } + }; + requestAnimationFrame(doInitialFit); + + // Refit after font load (metrics may change) + document.fonts.ready.then(() => { + requestAnimationFrame(() => fitTerminal()); + }); + + // Handle terminal input + term.onData((data) => { + const currentWs = wsRef.current; + if (currentWs?.readyState !== WebSocket.OPEN) return; + + // Apply active modifier to single-character input + const modifier = activeModifierRef.current; + if (modifier && data.length === 1) { + const modified = applyModifierToChar(data, modifier); + if (modified) { + currentWs.send(modified); + onModifierChange?.(null); return; } - if (document.visibilityState !== "hidden") { - connectWebSocket(); - } - }, delay); - } - }; - - ws.onerror = () => { - setStatus("error"); - setError("WebSocket error"); - }; - - return ws; - }, [instanceId]); - - useEffect(() => { - if (!terminalRef.current) return; - - // Initialize terminal - const currentFontSize = calculateFontSize(); - const term = new Terminal({ - cursorBlink: true, - fontSize: currentFontSize, - fontFamily: 'Menlo, Monaco, "Courier New", monospace', - lineHeight: 1.2, - letterSpacing: 0, - allowTransparency: false, - theme: { - background: "#1e1e1e", - foreground: "#d4d4d4", - cursor: "#d4d4d4", - selectionBackground: "#264f78", - black: "#000000", - red: "#cd3131", - green: "#0dbc79", - yellow: "#e5e510", - blue: "#2472c8", - magenta: "#bc3fbc", - cyan: "#11a8cd", - white: "#e5e5e5", - brightBlack: "#666666", - brightRed: "#f14c4c", - brightGreen: "#23d18b", - brightYellow: "#f5f543", - brightBlue: "#3b8eea", - brightMagenta: "#d670d6", - brightCyan: "#29b8db", - brightWhite: "#e5e5e5", - }, - }); - - termRef.current = term; - - const fitAddon = new FitAddon(); - fitAddonRef.current = fitAddon; - term.loadAddon(fitAddon); - term.loadAddon(new WebLinksAddon()); - - const container = terminalRef.current; - - // Define fitTerminal before connectWebSocket so it's available in onmessage - const fitTerminal = () => { - if (!fitAddonRef.current || !termRef.current) return; - try { - fitAddonRef.current.fit(); - } catch { - // Ignore fit errors during initialization - return; - } - const { cols, rows } = termRef.current; - // Force refresh if dimensions are valid - if (cols > 0 && rows > 0) { - try { - termRef.current.refresh(0, rows - 1); - } catch { - // Ignore refresh errors } - } - const currentWs = wsRef.current; - if (currentWs?.readyState === WebSocket.OPEN && cols > 0 && rows > 0) { - currentWs.send(JSON.stringify({ type: "resize", cols, rows })); - } - }; - // Open xterm first (must happen before fit) - term.open(container); - const ws = connectWebSocket(); + currentWs.send(data); + }); - // Initial fit after layout settles (terminal must be opened first) - let fitAttempts = 0; - const doInitialFit = () => { - if (!container.isConnected) return; - fitAttempts++; - // Ensure container has dimensions before fitting - if (container.clientWidth > 0 && container.clientHeight > 0) { + // Handle container resize with ResizeObserver for accurate dimension tracking + let resizeTimeout: ReturnType; + let lastWidth = 0; + let lastHeight = 0; + const resizeObserver = new ResizeObserver((entries) => { + const entry = entries[0]; + if (!entry) return; + + const { width, height } = entry.contentRect; + // Only trigger if dimensions actually changed + if (width === lastWidth && height === lastHeight) return; + lastWidth = width; + lastHeight = height; + + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + requestAnimationFrame(() => { + if (!container.isConnected) return; + fitTerminal(); + }); + }, 50); + }); + resizeObserver.observe(container); + + // Window resize fallback (for viewport changes that don't affect container dimensions) + let windowResizeTimeout: ReturnType; + const handleWindowResize = () => { + clearTimeout(windowResizeTimeout); + windowResizeTimeout = setTimeout(() => { + requestAnimationFrame(() => fitTerminal()); + }, 250); + }; + window.addEventListener("resize", handleWindowResize); + + // Refit after mobile header auto-hides (3s delay + 0.3s transition) + const headerHideTimeout = setTimeout(() => { fitTerminal(); - } else if (fitAttempts < 50) { - // Container not ready yet, try again (max 50 attempts ~ 1s) - requestAnimationFrame(doInitialFit); - } - }; - requestAnimationFrame(doInitialFit); + }, 4000); - // Refit after font load (metrics may change) - document.fonts.ready.then(() => { - requestAnimationFrame(() => fitTerminal()); - }); - - // Handle terminal input - term.onData((data) => { - const currentWs = wsRef.current; - if (currentWs?.readyState !== WebSocket.OPEN) return; - - // Apply active modifier to single-character input - const modifier = activeModifierRef.current; - if (modifier && data.length === 1) { - const modified = applyModifierToChar(data, modifier); - if (modified) { - currentWs.send(modified); - onModifierChange?.(null); - return; - } + // Notify parent about terminal readiness + if (onTerminalReadyRef.current) { + const sendData = (data: string) => { + const currentWs = wsRef.current; + if (currentWs?.readyState === WebSocket.OPEN) { + currentWs.send(data); + } + }; + const focusInput = () => { + termRef.current?.focus(); + }; + const changeFontSize = (delta: number) => { + handleFontSizeChangeRef.current(delta); + }; + onTerminalReadyRef.current( + sendData, + status, + focusInput, + changeFontSize, + ); } - currentWs.send(data); - }); - - // Handle container resize with ResizeObserver for accurate dimension tracking - let resizeTimeout: ReturnType; - let lastWidth = 0; - let lastHeight = 0; - const resizeObserver = new ResizeObserver((entries) => { - const entry = entries[0]; - if (!entry) return; - - const { width, height } = entry.contentRect; - // Only trigger if dimensions actually changed - if (width === lastWidth && height === lastHeight) return; - lastWidth = width; - lastHeight = height; - - clearTimeout(resizeTimeout); - resizeTimeout = setTimeout(() => { - requestAnimationFrame(() => { - if (!container.isConnected) return; - fitTerminal(); - }); - }, 50); - }); - resizeObserver.observe(container); - - // Window resize fallback (for viewport changes that don't affect container dimensions) - let windowResizeTimeout: ReturnType; - const handleWindowResize = () => { - clearTimeout(windowResizeTimeout); - windowResizeTimeout = setTimeout(() => { - requestAnimationFrame(() => fitTerminal()); - }, 250); - }; - window.addEventListener("resize", handleWindowResize); - - // Refit after mobile header auto-hides (3s delay + 0.3s transition) - const headerHideTimeout = setTimeout(() => { - fitTerminal(); - }, 4000); - - // Notify parent about terminal readiness - if (onTerminalReadyRef.current) { - const sendData = (data: string) => { - const currentWs = wsRef.current; - if (currentWs?.readyState === WebSocket.OPEN) { - currentWs.send(data); + // Visibility API for reconnection + const handleVisibilityChange = () => { + if ( + document.visibilityState === "visible" && + ws && + ws.readyState !== WebSocket.OPEN + ) { + if (permanentErrorRef.current) { + return; + } + reconnectAttemptsRef.current = 0; + connectWebSocket(); } }; - const focusInput = () => { - termRef.current?.focus(); - }; - const changeFontSize = (delta: number) => { - handleFontSizeChangeRef.current(delta); - }; - onTerminalReadyRef.current(sendData, status, focusInput, changeFontSize); - } + document.addEventListener("visibilitychange", handleVisibilityChange); - // Visibility API for reconnection - const handleVisibilityChange = () => { - if ( - document.visibilityState === "visible" && - ws && - ws.readyState !== WebSocket.OPEN - ) { - if (permanentErrorRef.current) { - return; + return () => { + isUnmountingRef.current = true; + clearTimeout(resizeTimeout); + clearTimeout(windowResizeTimeout); + clearTimeout(headerHideTimeout); + resizeObserver.disconnect(); + window.removeEventListener("resize", handleWindowResize); + document.removeEventListener( + "visibilitychange", + handleVisibilityChange, + ); + if (ws) { + ws.close(1000, "Component unmounting"); } - reconnectAttemptsRef.current = 0; - connectWebSocket(); - } - }; - document.addEventListener("visibilitychange", handleVisibilityChange); - - return () => { - isUnmountingRef.current = true; - clearTimeout(resizeTimeout); - clearTimeout(windowResizeTimeout); - clearTimeout(headerHideTimeout); - resizeObserver.disconnect(); - window.removeEventListener("resize", handleWindowResize); - document.removeEventListener("visibilitychange", handleVisibilityChange); - if (ws) { - ws.close(1000, "Component unmounting"); - } - if (heartbeatCheckRef.current) { - window.clearInterval(heartbeatCheckRef.current); - heartbeatCheckRef.current = null; - } - term.dispose(); - }; + if (heartbeatCheckRef.current) { + window.clearInterval(heartbeatCheckRef.current); + heartbeatCheckRef.current = null; + } + term.dispose(); + }; }, [instanceId, connectWebSocket]); - // Update parent about status changes - useEffect(() => { - if (onTerminalReady && termRef.current) { - const sendData = (data: string) => { - if (wsRef.current?.readyState === WebSocket.OPEN) { - wsRef.current.send(data); - } - }; - const focusInput = () => { - termRef.current?.focus(); - }; - const changeFontSize = (delta: number) => { - handleFontSizeChangeRef.current(delta); - }; - onTerminalReady(sendData, status, focusInput, changeFontSize); - } - }, [status, onTerminalReady]); - - const handleFontSizeChange = (delta: number) => { - const newSize = Math.max( - MIN_FONT_SIZE, - Math.min(MAX_FONT_SIZE, fontSize + delta), - ); - setFontSize(newSize); - localStorage.setItem(FONT_SIZE_KEY, newSize.toString()); - if (termRef.current && fitAddonRef.current) { - termRef.current.options.fontSize = newSize; - requestAnimationFrame(() => { - if (termRef.current && fitAddonRef.current) { + useImperativeHandle(ref, () => ({ + fit: () => { + if (fitAddonRef.current && termRef.current) { try { fitAddonRef.current.fit(); const { cols, rows } = termRef.current; - if (wsRef.current?.readyState === WebSocket.OPEN) { + if ( + wsRef.current?.readyState === WebSocket.OPEN && + cols > 0 && + rows > 0 + ) { wsRef.current.send( - JSON.stringify({ - type: "resize", - cols, - rows, - }), + JSON.stringify({ type: "resize", cols, rows }), ); } } catch { - // Ignore fit errors during re-initialization + // Ignore fit errors } } - }); - } - }; - handleFontSizeChangeRef.current = handleFontSizeChange; + }, + })); - const handleCopy = async () => { - if (!termRef.current) return; - const selection = termRef.current.getSelection(); - if (selection) { + // Update parent about status changes + useEffect(() => { + if (onTerminalReady && termRef.current) { + const sendData = (data: string) => { + if (wsRef.current?.readyState === WebSocket.OPEN) { + wsRef.current.send(data); + } + }; + const focusInput = () => { + termRef.current?.focus(); + }; + const changeFontSize = (delta: number) => { + handleFontSizeChangeRef.current(delta); + }; + onTerminalReady(sendData, status, focusInput, changeFontSize); + } + }, [status, onTerminalReady]); + + const handleFontSizeChange = (delta: number) => { + const newSize = Math.max( + MIN_FONT_SIZE, + Math.min(MAX_FONT_SIZE, fontSize + delta), + ); + setFontSize(newSize); + localStorage.setItem(FONT_SIZE_KEY, newSize.toString()); + if (termRef.current && fitAddonRef.current) { + termRef.current.options.fontSize = newSize; + requestAnimationFrame(() => { + if (termRef.current && fitAddonRef.current) { + try { + fitAddonRef.current.fit(); + const { cols, rows } = termRef.current; + if (wsRef.current?.readyState === WebSocket.OPEN) { + wsRef.current.send( + JSON.stringify({ + type: "resize", + cols, + rows, + }), + ); + } + } catch { + // Ignore fit errors during re-initialization + } + } + }); + } + }; + handleFontSizeChangeRef.current = handleFontSizeChange; + + const handleCopy = async () => { + if (!termRef.current) return; + const selection = termRef.current.getSelection(); + if (selection) { + try { + await navigator.clipboard.writeText(selection); + } catch { + // Fallback for older browsers + const textarea = document.createElement("textarea"); + textarea.value = selection; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand("copy"); + document.body.removeChild(textarea); + } + } + }; + + const handlePaste = async () => { try { - await navigator.clipboard.writeText(selection); + const text = await navigator.clipboard.readText(); + if (wsRef.current?.readyState === WebSocket.OPEN) { + wsRef.current.send(text); + } } catch { - // Fallback for older browsers - const textarea = document.createElement("textarea"); - textarea.value = selection; - document.body.appendChild(textarea); - textarea.select(); - document.execCommand("copy"); - document.body.removeChild(textarea); + // Clipboard API not available } - } - }; + }; - const handlePaste = async () => { - try { - const text = await navigator.clipboard.readText(); - if (wsRef.current?.readyState === WebSocket.OPEN) { - wsRef.current.send(text); + // Focus terminal on mobile to keep keyboard open + const handleTerminalClick = () => { + if (isMobile && termRef.current) { + termRef.current.focus(); } - } catch { - // Clipboard API not available - } - }; + }; - // Focus terminal on mobile to keep keyboard open - const handleTerminalClick = () => { - if (isMobile && termRef.current) { - termRef.current.focus(); - } - }; - - return ( -
-
-
-
- - - {status === "resetting" - ? "Resetting..." - : reconnectAttemptsRef.current > 0 && status !== "connected" - ? `Reconnecting (${reconnectAttemptsRef.current}/${RECONNECT_ATTEMPTS})...` - : status} - + return ( +
+
+
+
+ + + {status === "resetting" + ? "Resetting..." + : reconnectAttemptsRef.current > 0 && status !== "connected" + ? `Reconnecting (${reconnectAttemptsRef.current}/${RECONNECT_ATTEMPTS})...` + : status} + +
+ {isMobile && ( + <> + + + + )}
- {isMobile && ( - <> - - - - )} -
-
- - - - {onClose && ( - - )} -
-
- {showResetConfirm && ( -
-
-

- Reset terminal? This will kill the current shell session and start - fresh. -

-
+ + + {onClose && ( + )} +
+
+ {showResetConfirm && ( +
+
+

+ Reset terminal? This will kill the current shell session and + start fresh. +

+
+ + +
+
+
+ )} + {error && ( +
+ {error} + {status === "error" && ( -
+ )}
-
- )} - {error && ( -
- {error} - {status === "error" && ( - - )} -
- )} -
- {isMobile && ( - - )} -
- ); -}; + {isMobile && ( + + )} +
+ ); + }, +); + +TerminalComponent.displayName = "TerminalComponent"; diff --git a/apps/web/src/hooks/use-terminal-sessions.ts b/apps/web/src/hooks/use-terminal-sessions.ts new file mode 100644 index 0000000..e05f527 --- /dev/null +++ b/apps/web/src/hooks/use-terminal-sessions.ts @@ -0,0 +1,145 @@ +import { useCallback, useEffect, useState } from "react"; +import { + listTerminalSessions, + createTerminalSession, + closeTerminalSession, + resetTerminalSession, + renameTerminalSession, + type TerminalSession, +} from "../api/terminal"; + +export interface UseTerminalSessionsResult { + sessions: TerminalSession[]; + activeSessionId: string | null; + setActiveSessionId: (id: string) => void; + createSession: (name?: string) => Promise; + closeSession: (sessionId: string) => Promise; + renameSession: (sessionId: string, name: string) => Promise; + resetSession: (sessionId: string) => Promise; + loading: boolean; + error: string | null; +} + +export function useTerminalSessions( + instanceId: string, +): UseTerminalSessionsResult { + const [sessions, setSessions] = useState([]); + const [activeSessionId, setActiveSessionId] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const loadSessions = useCallback(async () => { + setLoading(true); + setError(null); + try { + const sess = await listTerminalSessions(instanceId); + setSessions(sess); + if (sess.length > 0 && !activeSessionId) { + setActiveSessionId(sess[0].id); + } + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to load sessions"); + } finally { + setLoading(false); + } + }, [instanceId, activeSessionId]); + + const createSession = useCallback( + async (name?: string) => { + setError(null); + try { + const newSession = await createTerminalSession(instanceId, name); + const session: TerminalSession = { + id: newSession.id, + name: newSession.name, + status: newSession.status, + has_websockets: false, + created_at: newSession.created_at, + last_activity_at: null, + }; + setSessions((prev) => [...prev, session]); + setActiveSessionId(session.id); + return session; + } catch (err) { + const msg = + err instanceof Error ? err.message : "Failed to create session"; + setError(msg); + return null; + } + }, + [instanceId], + ); + + const closeSession = useCallback( + async (sessionId: string) => { + setError(null); + try { + await closeTerminalSession(instanceId, sessionId); + setSessions((prev) => { + const filtered = prev.filter((s) => s.id !== sessionId); + if (activeSessionId === sessionId && filtered.length > 0) { + setActiveSessionId(filtered[0].id); + } else if (filtered.length === 0) { + setActiveSessionId(null); + } + return filtered; + }); + } catch (err) { + setError( + err instanceof Error ? err.message : "Failed to close session", + ); + } + }, + [instanceId, activeSessionId], + ); + + const renameSession = useCallback( + async (sessionId: string, name: string) => { + setError(null); + try { + await renameTerminalSession(instanceId, sessionId, name); + setSessions((prev) => + prev.map((s) => (s.id === sessionId ? { ...s, name } : s)), + ); + } catch (err) { + setError( + err instanceof Error ? err.message : "Failed to rename session", + ); + } + }, + [instanceId], + ); + + const resetSession = useCallback( + async (sessionId: string) => { + setError(null); + try { + await resetTerminalSession(instanceId, sessionId); + // Refetch to get updated session info + await loadSessions(); + } catch (err) { + setError( + err instanceof Error ? err.message : "Failed to reset session", + ); + } + }, + [instanceId, loadSessions], + ); + + // Initial load + useEffect(() => { + void loadSessions(); + }, [loadSessions]); + + return { + sessions, + activeSessionId, + setActiveSessionId, + createSession, + closeSession, + renameSession, + resetSession, + loading, + error, + }; +} diff --git a/apps/web/src/pages/terminal.tsx b/apps/web/src/pages/terminal.tsx index e5801df..95837f4 100644 --- a/apps/web/src/pages/terminal.tsx +++ b/apps/web/src/pages/terminal.tsx @@ -1,50 +1,317 @@ -import React from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; -import { TerminalComponent } from "../components/terminal"; -import { MobileTerminalWrapper } from "../components/mobile-terminal-wrapper"; +import { TerminalComponent, type TerminalRef } from "../components/terminal"; +import { + TerminalSessionTabs, + type TerminalSessionInfo, +} from "../components/terminal-session-tabs"; import { useMobileViewport } from "../hooks/use-mobile-viewport"; +import { useAutoHide } from "../hooks/use-auto-hide"; +import { useTerminalSessions } from "../hooks/use-terminal-sessions"; +import type { TerminalSession } from "../api/terminal"; + +const SESSIONS_TO_INFO = (sessions: TerminalSession[]): TerminalSessionInfo[] => + sessions.map((s) => ({ + id: s.id, + name: s.name, + status: s.status as TerminalSessionInfo["status"], + })); export const TerminalPage: React.FC = () => { - const { instanceId } = useParams<{ instanceId: string }>(); - const navigate = useNavigate(); - const isMobile = useMobileViewport(); + const { instanceId } = useParams<{ + instanceId: string; + }>(); + const navigate = useNavigate(); + const isMobile = useMobileViewport(); + const [isFullscreen, setIsFullscreen] = useState(false); + const terminalRefs = useRef>>({}); + const headerAutoHide = useAutoHide({ timeout: 3000, enabled: isMobile }); - if (!instanceId) { - return ( -
-

Terminal

-

No instance ID provided.

-
- ); - } + const { + sessions, + activeSessionId, + setActiveSessionId, + createSession, + closeSession, + renameSession, + resetSession, + loading, + error, + } = useTerminalSessions(instanceId ?? ""); - if (isMobile) { - return ( - navigate(-1)} - onClose={() => navigate(-1)} - /> - ); - } + // Auto-create default session if none exist + useEffect(() => { + if (!loading && sessions.length === 0 && !error && instanceId) { + void createSession("Session 1"); + } + }, [loading, sessions.length, error, instanceId, createSession]); - return ( -
-
- -

Terminal

-
- navigate(-1)} - isMobile={false} - /> -
- ); + // Ensure refs map is kept in sync with sessions + useEffect(() => { + for (const session of sessions) { + if (!terminalRefs.current[session.id]) { + terminalRefs.current[session.id] = React.createRef(); + } + } + // Clean up refs for closed sessions + const currentIds = new Set(sessions.map((s) => s.id)); + for (const id of Object.keys(terminalRefs.current)) { + if (!currentIds.has(id)) { + delete terminalRefs.current[id]; + } + } + }, [sessions]); + + // Fit active terminal when switching tabs + useEffect(() => { + if (activeSessionId && terminalRefs.current[activeSessionId]) { + const ref = terminalRefs.current[activeSessionId]; + // Small delay to allow display:block to apply + const timer = setTimeout(() => { + ref.current?.fit(); + }, 50); + return () => clearTimeout(timer); + } + }, [activeSessionId]); + + // Keyboard shortcuts + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + const isAltShift = e.altKey && e.shiftKey && !e.ctrlKey && !e.metaKey; + if (!isAltShift) return; + + switch (e.key.toLowerCase()) { + case "n": + e.preventDefault(); + if (sessions.length < 5) { + void createSession(`Session ${sessions.length + 1}`); + } + break; + case "w": + e.preventDefault(); + if ( + activeSessionId && + window.confirm("Close this terminal session?") + ) { + void closeSession(activeSessionId); + } + break; + case "arrowleft": + e.preventDefault(); + if (activeSessionId) { + const idx = sessions.findIndex((s) => s.id === activeSessionId); + if (idx > 0) { + setActiveSessionId(sessions[idx - 1].id); + } + } + break; + case "arrowright": + e.preventDefault(); + if (activeSessionId) { + const idx = sessions.findIndex((s) => s.id === activeSessionId); + if (idx < sessions.length - 1) { + setActiveSessionId(sessions[idx + 1].id); + } + } + break; + case "r": + e.preventDefault(); + if (activeSessionId) { + void resetSession(activeSessionId); + } + break; + case "f": + e.preventDefault(); + setIsFullscreen((prev) => !prev); + break; + default: + break; + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [ + sessions, + activeSessionId, + createSession, + closeSession, + resetSession, + setActiveSessionId, + ]); + + // Exit fullscreen on Escape + useEffect(() => { + if (!isFullscreen) return; + const handleEscape = (e: KeyboardEvent) => { + if (e.key === "Escape") { + setIsFullscreen(false); + } + }; + window.addEventListener("keydown", handleEscape); + return () => window.removeEventListener("keydown", handleEscape); + }, [isFullscreen]); + + const handleSelect = useCallback( + (sessionId: string) => { + setActiveSessionId(sessionId); + }, + [setActiveSessionId], + ); + + const handleClose = useCallback( + async (sessionId: string) => { + await closeSession(sessionId); + }, + [closeSession], + ); + + const handleCreate = useCallback(() => { + void createSession(`Session ${sessions.length + 1}`); + }, [createSession, sessions.length]); + + const handleRename = useCallback( + (sessionId: string, newName: string) => { + void renameSession(sessionId, newName); + }, + [renameSession], + ); + + if (!instanceId) { + return ( +
+

Terminal

+

No instance ID provided.

+
+ ); + } + + const sessionInfos = SESSIONS_TO_INFO(sessions); + + if (isMobile) { + return ( +
+
headerAutoHide.show()} + > + +

Terminal

+ +
+
headerAutoHide.show()} + > + +
+
+ {error &&
{error}
} + {sessions.map((session) => ( +
+ handleClose(session.id)} + isMobile={true} + /> +
+ ))} + {sessions.length === 0 && !loading && ( +
+

No terminal sessions. Press Alt+Shift+N to create one.

+
+ )} +
+
+ ); + } + + return ( +
+ {!isFullscreen && ( +
+ +

Terminal

+ +
+ )} + +
+ {error &&
{error}
} + {sessions.map((session) => ( +
+ handleClose(session.id)} + isMobile={false} + /> +
+ ))} + {sessions.length === 0 && !loading && ( +
+

No terminal sessions. Press Alt+Shift+N to create one.

+
+ )} +
+
+ ); }; diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index 8c00b45..dfedd03 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -1,1969 +1,1977 @@ :root { - color-scheme: light; - font-family: "Inter", "IBM Plex Sans", "Segoe UI", sans-serif; - --bg: #f4f1ea; - --panel: #fffef9; - --ink: #1d1d1b; - --muted: #5f5b55; - --brand: #275d4b; - --brand-strong: #154236; - --border: #d8d0c5; - --primary: #275d4b; - --primary-fg: #fffef9; - --color-primary: #275d4b; - --success: #2f8f62; - --success-light: rgba(47, 143, 98, 0.14); - --warning: #c08a1e; - --warning-light: rgba(192, 138, 30, 0.14); - --danger: #b94a3c; - --danger-light: rgba(185, 74, 60, 0.14); - --info: #4f7fb8; - --info-light: rgba(79, 127, 184, 0.14); + color-scheme: light; + font-family: "Inter", "IBM Plex Sans", "Segoe UI", sans-serif; + --bg: #f4f1ea; + --panel: #fffef9; + --ink: #1d1d1b; + --muted: #5f5b55; + --brand: #275d4b; + --brand-strong: #154236; + --border: #d8d0c5; + --primary: #275d4b; + --primary-fg: #fffef9; + --color-primary: #275d4b; + --success: #2f8f62; + --success-light: rgba(47, 143, 98, 0.14); + --warning: #c08a1e; + --warning-light: rgba(192, 138, 30, 0.14); + --danger: #b94a3c; + --danger-light: rgba(185, 74, 60, 0.14); + --info: #4f7fb8; + --info-light: rgba(79, 127, 184, 0.14); - /* Spacing Scale (4px base) */ - --space-1: 0.25rem; - --space-2: 0.5rem; - --space-3: 0.75rem; - --space-4: 1rem; - --space-5: 1.5rem; - --space-6: 2rem; - --space-8: 3rem; - --space-10: 4rem; + /* Spacing Scale (4px base) */ + --space-1: 0.25rem; + --space-2: 0.5rem; + --space-3: 0.75rem; + --space-4: 1rem; + --space-5: 1.5rem; + --space-6: 2rem; + --space-8: 3rem; + --space-10: 4rem; - /* Breakpoints */ - --bp-sm: 480px; - --bp-md: 768px; - --bp-lg: 1024px; - --bp-xl: 1280px; + /* Breakpoints */ + --bp-sm: 480px; + --bp-md: 768px; + --bp-lg: 1024px; + --bp-xl: 1280px; - /* Fluid Typography */ - --font-size-xs: clamp(0.625rem, 0.6rem + 0.125vw, 0.75rem); - --font-size-sm: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem); - --font-size-base: clamp(0.875rem, 0.8rem + 0.35vw, 1rem); - --font-size-lg: clamp(1rem, 0.9rem + 0.5vw, 1.25rem); - --font-size-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem); - --font-size-2xl: clamp(1.5rem, 1.3rem + 1vw, 2rem); + /* Fluid Typography */ + --font-size-xs: clamp(0.625rem, 0.6rem + 0.125vw, 0.75rem); + --font-size-sm: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem); + --font-size-base: clamp(0.875rem, 0.8rem + 0.35vw, 1rem); + --font-size-lg: clamp(1rem, 0.9rem + 0.5vw, 1.25rem); + --font-size-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.5rem); + --font-size-2xl: clamp(1.5rem, 1.3rem + 1vw, 2rem); } [data-theme="dark"] { - color-scheme: dark; - --bg: #171613; - --panel: #22201d; - --ink: #ece7df; - --muted: #a59d92; - --brand: #5fa889; - --brand-strong: #4d9175; - --border: #39342d; - --primary: #5fa889; - --primary-fg: #171613; - --color-primary: #5fa889; - --success: #22c55e; - --success-light: rgba(34, 197, 94, 0.15); - --warning: #f59e0b; - --warning-light: rgba(245, 158, 11, 0.15); - --danger: #ef4444; - --danger-light: rgba(239, 68, 68, 0.15); - --info: #3b82f6; - --info-light: rgba(59, 130, 246, 0.15); + color-scheme: dark; + --bg: #171613; + --panel: #22201d; + --ink: #ece7df; + --muted: #a59d92; + --brand: #5fa889; + --brand-strong: #4d9175; + --border: #39342d; + --primary: #5fa889; + --primary-fg: #171613; + --color-primary: #5fa889; + --success: #22c55e; + --success-light: rgba(34, 197, 94, 0.15); + --warning: #f59e0b; + --warning-light: rgba(245, 158, 11, 0.15); + --danger: #ef4444; + --danger-light: rgba(239, 68, 68, 0.15); + --info: #3b82f6; + --info-light: rgba(59, 130, 246, 0.15); } * { - box-sizing: border-box; + box-sizing: border-box; } body { - margin: 0; - background: var(--bg); - color: var(--ink); + margin: 0; + background: var(--bg); + color: var(--ink); } [data-theme="dark"] body { - background: radial-gradient(circle at top right, #2a2520, var(--bg)); + background: radial-gradient(circle at top right, #2a2520, var(--bg)); } a { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } .shell { - min-height: 100vh; - display: flex; - flex-direction: column; + min-height: 100vh; + display: flex; + flex-direction: column; } .shell-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.85rem 1.25rem; - border-bottom: 1px solid var(--border); - background: color-mix(in srgb, var(--panel) 88%, transparent); - backdrop-filter: blur(7px); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.85rem 1.25rem; + border-bottom: 1px solid var(--border); + background: color-mix(in srgb, var(--panel) 88%, transparent); + backdrop-filter: blur(7px); } [data-theme="dark"] .shell-header { - background: color-mix(in srgb, var(--panel) 88%, transparent); + background: color-mix(in srgb, var(--panel) 88%, transparent); } .brand { - font-weight: 700; - letter-spacing: 0.02em; + font-weight: 700; + letter-spacing: 0.02em; } .header-actions { - display: flex; - align-items: center; - gap: 0.75rem; + display: flex; + align-items: center; + gap: 0.75rem; } .shell-body { - display: grid; - grid-template-columns: 230px 1fr; - height: calc(100vh - 57px); - flex: 1; + display: grid; + grid-template-columns: 230px 1fr; + height: calc(100vh - 57px); + flex: 1; } .shell-nav { - border-right: 1px solid var(--border); - padding: 1rem 0.75rem; - display: flex; - flex-direction: column; - gap: 0.4rem; - background: color-mix(in srgb, var(--panel) 65%, transparent); + border-right: 1px solid var(--border); + padding: 1rem 0.75rem; + display: flex; + flex-direction: column; + gap: 0.4rem; + background: color-mix(in srgb, var(--panel) 65%, transparent); } .nav-item { - padding: 0.65rem 0.75rem; - border-radius: 10px; - color: var(--muted); + padding: 0.65rem 0.75rem; + border-radius: 10px; + color: var(--muted); } .nav-item:hover { - background: #ece7df; - color: var(--ink); + background: #ece7df; + color: var(--ink); } .nav-item-active { - background: var(--brand); - color: #f7fff7; + background: var(--brand); + color: #f7fff7; } .nav-section-title { - margin-top: 0.5rem; - padding: 0.25rem 0.75rem; - font-size: var(--font-size-xs); - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--muted); + margin-top: 0.5rem; + padding: 0.25rem 0.75rem; + font-size: var(--font-size-xs); + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--muted); } .nav-divider { - height: 1px; - background: var(--border); - margin: 0.5rem 0; + height: 1px; + background: var(--border); + margin: 0.5rem 0; } .shell-content { - padding: 1.25rem; - overflow-x: hidden; - display: flex; - flex-direction: column; - min-height: 0; - height: 100%; + padding: 1.25rem; + overflow-x: hidden; + display: flex; + flex-direction: column; + min-height: 0; + height: 100%; } .eyebrow { - margin: 0; - font-size: var(--font-size-xs); - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--muted); + margin: 0; + font-size: var(--font-size-xs); + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--muted); } .home-page, .settings-page { - max-width: 1240px; + max-width: 1240px; } .home-hero { - display: flex; - justify-content: space-between; - gap: var(--space-4); - align-items: flex-start; + display: flex; + justify-content: space-between; + gap: var(--space-4); + align-items: flex-start; } .home-hero-actions { - display: flex; - gap: var(--space-2); - flex-wrap: wrap; + display: flex; + gap: var(--space-2); + flex-wrap: wrap; } .home-summary-grid, .home-project-grid, .home-session-grid { - display: grid; - gap: var(--space-4); + display: grid; + gap: var(--space-4); } .home-summary-grid { - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); } .home-project-grid, .home-session-grid { - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } .home-section h2, .settings-header h1, .settings-panel h2 { - margin: 0; + margin: 0; } .home-section h3, .home-section p { - margin: 0; + margin: 0; } .row-tight { - gap: var(--space-2); + gap: var(--space-2); } .settings-tabs { - display: flex; - gap: var(--space-2); - flex-wrap: wrap; + display: flex; + gap: var(--space-2); + flex-wrap: wrap; } .settings-tab { - padding: 0.6rem 0.9rem; - border-radius: 999px; - border: 1px solid var(--border); - color: var(--muted); - background: var(--panel); + padding: 0.6rem 0.9rem; + border-radius: 999px; + border: 1px solid var(--border); + color: var(--muted); + background: var(--panel); } .settings-tab.active { - background: var(--brand); - color: white; - border-color: transparent; + background: var(--brand); + color: white; + border-color: transparent; } .settings-panel { - padding: 1.5rem; + padding: 1.5rem; } .settings-actions, .form-actions { - display: flex; - gap: var(--space-3); - align-items: center; - flex-wrap: wrap; + display: flex; + gap: var(--space-3); + align-items: center; + flex-wrap: wrap; } .error-text { - color: var(--danger); + color: var(--danger); } .success-text { - color: var(--success); + color: var(--success); } .small { - padding: 0.42rem 0.7rem; - min-height: 38px; + padding: 0.42rem 0.7rem; + min-height: 38px; } .session-card, .project-card, .recent-session-item { - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.02); } /* Responsive Shell */ @media (max-width: 767px) { - .shell-body { - grid-template-columns: 1fr; - grid-template-rows: auto 1fr; - } + .shell-body { + grid-template-columns: 1fr; + grid-template-rows: auto 1fr; + } - .shell-nav { - flex-direction: row; - flex-wrap: wrap; - gap: 0.25rem; - padding: 0.5rem; - border-right: none; - border-bottom: 1px solid var(--border); - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } + .shell-nav { + flex-direction: row; + flex-wrap: wrap; + gap: 0.25rem; + padding: 0.5rem; + border-right: none; + border-bottom: 1px solid var(--border); + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } - .nav-item { - padding: 0.5rem 0.75rem; - white-space: nowrap; - font-size: var(--font-size-sm); - } + .nav-item { + padding: 0.5rem 0.75rem; + white-space: nowrap; + font-size: var(--font-size-sm); + } - .shell-content { - padding: var(--space-4); - height: 100%; - } + .shell-content { + padding: var(--space-4); + height: 100%; + } } .stack { - display: flex; - flex-direction: column; - gap: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; } .muted { - color: var(--muted); + color: var(--muted); } .card-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); - gap: var(--space-4); + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); + gap: var(--space-4); } @media (min-width: 768px) { - .card-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } + .card-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } } @media (min-width: 1024px) { - .card-grid { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } + .card-grid { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } } .card { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 14px; - padding: 1rem; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 14px; + padding: 1rem; } .card-label { - margin: 0; - color: var(--muted); + margin: 0; + color: var(--muted); } .card-value { - margin: 0.45rem 0 0; - font-size: 1.6rem; - font-weight: 700; + margin: 0.45rem 0 0; + font-size: 1.6rem; + font-weight: 700; } .quick-actions { - display: flex; - gap: 0.6rem; + display: flex; + gap: 0.6rem; } .primary-button, .secondary-button, .ghost-button { - border-radius: 10px; - border: 1px solid transparent; - padding: 0.58rem 0.85rem; - cursor: pointer; - font: inherit; + border-radius: 10px; + border: 1px solid transparent; + padding: 0.58rem 0.85rem; + cursor: pointer; + font: inherit; } .primary-button { - background: var(--brand); - color: white; + background: var(--brand); + color: white; } .primary-button:hover { - background: var(--brand-strong); + background: var(--brand-strong); } .secondary-button { - border-color: var(--border); - background: var(--panel); + border-color: var(--border); + background: var(--panel); } .ghost-button { - border-color: var(--border); - background: transparent; + border-color: var(--border); + background: transparent; } .user-chip { - border: 1px solid var(--border); - background: var(--panel); - border-radius: 999px; - padding: 0.35rem 0.7rem; - font-size: 0.9rem; + border: 1px solid var(--border); + background: var(--panel); + border-radius: 999px; + padding: 0.35rem 0.7rem; + font-size: 0.9rem; } .center-screen { - min-height: 55vh; - display: grid; - place-content: center; - text-align: center; + min-height: 55vh; + display: grid; + place-content: center; + text-align: center; } .page-header { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: var(--space-3); + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: var(--space-3); } @media (max-width: 767px) { - .page-header { - flex-direction: column; - align-items: flex-start; - } + .page-header { + flex-direction: column; + align-items: flex-start; + } } .project-list { - display: flex; - flex-direction: column; - gap: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.75rem; } .project-card { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 1rem; + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 1rem; } .project-info h3 { - margin: 0 0 0.35rem; + margin: 0 0 0.35rem; } .project-info p { - margin: 0; + margin: 0; } .project-actions { - display: flex; - gap: 0.5rem; - align-items: center; - flex-shrink: 0; + display: flex; + gap: 0.5rem; + align-items: center; + flex-shrink: 0; } .delete-confirm { - display: flex; - gap: 0.5rem; - align-items: center; + display: flex; + gap: 0.5rem; + align-items: center; } .danger-button { - border-radius: 10px; - border: 1px solid transparent; - padding: 0.58rem 0.85rem; - cursor: pointer; - font: inherit; - background: #b91c1c; - color: white; + border-radius: 10px; + border: 1px solid transparent; + padding: 0.58rem 0.85rem; + cursor: pointer; + font: inherit; + background: #b91c1c; + color: white; } .danger-text { - color: #b91c1c; + color: #b91c1c; } .error-text { - color: #b91c1c; - margin: 0; + color: #b91c1c; + margin: 0; } .dialog-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.35); - display: grid; - place-content: center; - z-index: 50; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.35); + display: grid; + place-content: center; + z-index: 50; } .dialog { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 14px; - padding: var(--space-5); - width: min(560px, 100vw - 2rem); - max-height: min(800px, 100vh - 2rem); - overflow-y: auto; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 14px; + padding: var(--space-5); + width: min(560px, 100vw - 2rem); + max-height: min(800px, 100vh - 2rem); + overflow-y: auto; } .dialog-lg { - width: min(800px, 100vw - 2rem); + width: min(800px, 100vw - 2rem); } @media (max-width: 767px) { - .dialog { - width: 100vw; - height: 100vh; - max-height: 100vh; - border-radius: 0; - padding: var(--space-4); - } + .dialog { + width: 100vw; + height: 100vh; + max-height: 100vh; + border-radius: 0; + padding: var(--space-4); + } - .dialog-overlay { - padding: 0; - } + .dialog-overlay { + padding: 0; + } } .dialog h2 { - margin: 0 0 1rem; + margin: 0 0 1rem; } .form-field { - display: flex; - flex-direction: column; - gap: 0.35rem; + display: flex; + flex-direction: column; + gap: 0.35rem; } .form-field input, .form-field textarea, .form-field select { - padding: 0.55rem 0.7rem; - border: 1px solid var(--border); - border-radius: 10px; - font: inherit; - background: var(--panel); - color: var(--ink); + padding: 0.55rem 0.7rem; + border: 1px solid var(--border); + border-radius: 10px; + font: inherit; + background: var(--panel); + color: var(--ink); } .dialog-actions { - display: flex; - justify-content: flex-end; - gap: 0.6rem; + display: flex; + justify-content: flex-end; + gap: 0.6rem; } .keys-list { - display: flex; - flex-direction: column; - gap: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.75rem; } .key-card { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 14px; - padding: 1rem; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 14px; + padding: 1rem; } .key-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 0.5rem; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.5rem; } .key-header h3 { - margin: 0; + margin: 0; } .key-meta { - margin-bottom: 0.75rem; + margin-bottom: 0.75rem; } .key-public { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.5rem; - background: #f5f3ee; - border-radius: 8px; + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.5rem; + background: #f5f3ee; + border-radius: 8px; } .key-public code { - font-size: 0.85rem; - word-break: break-all; - flex: 1; + font-size: 0.85rem; + word-break: break-all; + flex: 1; } .form-group { - display: flex; - flex-direction: column; - gap: 0.35rem; + display: flex; + flex-direction: column; + gap: 0.35rem; } .form-group input { - padding: 0.55rem 0.7rem; - border: 1px solid var(--border); - border-radius: 10px; - font: inherit; + padding: 0.55rem 0.7rem; + border: 1px solid var(--border); + border-radius: 10px; + font: inherit; } .error { - color: #b91c1c; - padding: 0.75rem; - background: #fef2f2; - border-radius: 10px; + color: #b91c1c; + padding: 0.75rem; + background: #fef2f2; + border-radius: 10px; } @media (max-width: 860px) { - .shell-body { - grid-template-columns: 1fr; - } + .shell-body { + grid-template-columns: 1fr; + } - .shell-nav { - flex-direction: row; - overflow-x: auto; - border-right: 0; - border-bottom: 1px solid var(--border); - } + .shell-nav { + flex-direction: row; + overflow-x: auto; + border-right: 0; + border-bottom: 1px solid var(--border); + } - .card-grid { - grid-template-columns: 1fr; - } + .card-grid { + grid-template-columns: 1fr; + } - .quick-actions { - flex-direction: column; - } + .quick-actions { + flex-direction: column; + } - .project-card { - flex-direction: column; - } + .project-card { + flex-direction: column; + } } /* URL Validation Styles */ .valid-url { - border-color: var(--success, #16a34a) !important; - background-color: var(--success-light, #f0fdf4) !important; + border-color: var(--success, #16a34a) !important; + background-color: var(--success-light, #f0fdf4) !important; } .needs-parsing-url { - border-color: var(--warning, #ca8a04) !important; - background-color: var(--warning-light, #fefce8) !important; + border-color: var(--warning, #ca8a04) !important; + background-color: var(--warning-light, #fefce8) !important; } .invalid-url { - border-color: var(--danger, #dc2626) !important; - background-color: var(--danger-light, #fef2f2) !important; + border-color: var(--danger, #dc2626) !important; + background-color: var(--danger-light, #fef2f2) !important; } .validation-status { - font-size: 0.85rem; - margin-top: 0.25rem; - display: block; + font-size: 0.85rem; + margin-top: 0.25rem; + display: block; } .validation-status.valid { - color: var(--success, #16a34a); + color: var(--success, #16a34a); } .validation-status.warning { - color: var(--warning, #ca8a04); + color: var(--warning, #ca8a04); } .validation-status.invalid { - color: #dc2626; + color: #dc2626; } .validation-status.validating { - color: var(--muted); + color: var(--muted); } .url-suggestion { - margin-top: 0.5rem; - padding: 0.5rem; - background: #fefce8; - border-radius: 8px; - border: 1px solid #fde047; + margin-top: 0.5rem; + padding: 0.5rem; + background: #fefce8; + border-radius: 8px; + border: 1px solid #fde047; } .suggestion-actions { - display: flex; - align-items: center; - gap: 0.75rem; - margin-top: 0.35rem; + display: flex; + align-items: center; + gap: 0.75rem; + margin-top: 0.35rem; } .suggested-url { - font-size: 0.85rem; - color: #854d0e; - flex: 1; - word-break: break-all; + font-size: 0.85rem; + color: #854d0e; + flex: 1; + word-break: break-all; } .secondary-button.small { - padding: 0.35rem 0.6rem; - font-size: 0.85rem; + padding: 0.35rem 0.6rem; + font-size: 0.85rem; } /* Git History Page Styles */ .history-actions { - display: flex; - gap: 0.75rem; - align-items: center; + display: flex; + gap: 0.75rem; + align-items: center; } .branch-selector { - padding: 0.45rem 0.7rem; - border: 1px solid var(--border); - border-radius: 10px; - font: inherit; - background: var(--panel); - color: var(--ink); + padding: 0.45rem 0.7rem; + border: 1px solid var(--border); + border-radius: 10px; + font: inherit; + background: var(--panel); + color: var(--ink); } .history-container { - display: grid; - grid-template-columns: 1fr; - gap: 1rem; - min-height: 60vh; + display: grid; + grid-template-columns: 1fr; + gap: 1rem; + min-height: 60vh; } .commit-list { - display: flex; - flex-direction: column; - gap: 0.5rem; - overflow-y: auto; - max-height: 70vh; + display: flex; + flex-direction: column; + gap: 0.5rem; + overflow-y: auto; + max-height: 70vh; } .commit-list.with-detail { - grid-column: 1; + grid-column: 1; } .commit-item { - display: flex; - gap: 0.75rem; - padding: 0.75rem; - background: var(--panel); - border: 1px solid var(--border); - border-radius: 10px; - cursor: pointer; - transition: background-color 0.15s ease; + display: flex; + gap: 0.75rem; + padding: 0.75rem; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 10px; + cursor: pointer; + transition: background-color 0.15s ease; } .commit-item:hover { - background: #ece7df; + background: #ece7df; } .commit-item.selected { - border-color: var(--brand); - background: #f0f7f4; + border-color: var(--brand); + background: #f0f7f4; } .commit-graph { - font-family: monospace; - font-size: 0.9rem; - color: var(--brand); - white-space: pre; - flex-shrink: 0; - min-width: 60px; + font-family: monospace; + font-size: 0.9rem; + color: var(--brand); + white-space: pre; + flex-shrink: 0; + min-width: 60px; } .graph-line { - display: inline-block; + display: inline-block; } .commit-content { - flex: 1; - min-width: 0; + flex: 1; + min-width: 0; } .commit-header { - display: flex; - gap: 0.5rem; - align-items: center; - margin-bottom: 0.35rem; + display: flex; + gap: 0.5rem; + align-items: center; + margin-bottom: 0.35rem; } .commit-hash { - font-family: monospace; - font-size: 0.85rem; - color: var(--brand); - background: #f0f7f4; - padding: 0.15rem 0.4rem; - border-radius: 6px; + font-family: monospace; + font-size: 0.85rem; + color: var(--brand); + background: #f0f7f4; + padding: 0.15rem 0.4rem; + border-radius: 6px; } .commit-refs { - display: flex; - gap: 0.35rem; - flex-wrap: wrap; + display: flex; + gap: 0.35rem; + flex-wrap: wrap; } .ref-tag { - font-size: 0.75rem; - padding: 0.15rem 0.4rem; - background: var(--brand); - color: white; - border-radius: 999px; + font-size: 0.75rem; + padding: 0.15rem 0.4rem; + background: var(--brand); + color: white; + border-radius: 999px; } .commit-message { - margin: 0 0 0.35rem; - font-weight: 500; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + margin: 0 0 0.35rem; + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .commit-meta { - display: flex; - gap: 0.75rem; - font-size: 0.85rem; - color: var(--muted); + display: flex; + gap: 0.75rem; + font-size: 0.85rem; + color: var(--muted); } .commit-detail-panel { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 14px; - padding: 1.25rem; - overflow-y: auto; - max-height: 70vh; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 14px; + padding: 1.25rem; + overflow-y: auto; + max-height: 70vh; } .detail-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 1rem; - padding-bottom: 0.75rem; - border-bottom: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; + padding-bottom: 0.75rem; + border-bottom: 1px solid var(--border); } .detail-header h3 { - margin: 0; + margin: 0; } .detail-content { - display: flex; - flex-direction: column; - gap: 1.25rem; + display: flex; + flex-direction: column; + gap: 1.25rem; } .detail-section { - display: flex; - flex-direction: column; - gap: 0.35rem; + display: flex; + flex-direction: column; + gap: 0.35rem; } .detail-section h4 { - margin: 0 0 0.5rem; - color: var(--muted); - font-size: 0.9rem; - text-transform: uppercase; - letter-spacing: 0.05em; + margin: 0 0 0.5rem; + color: var(--muted); + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 0.05em; } .commit-hash-full { - font-family: monospace; - font-size: 0.85rem; - color: var(--brand); - margin: 0; + font-family: monospace; + font-size: 0.85rem; + color: var(--brand); + margin: 0; } .commit-message-full { - margin: 0.5rem 0 0; - line-height: 1.5; - white-space: pre-wrap; + margin: 0.5rem 0 0; + line-height: 1.5; + white-space: pre-wrap; } .stats-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 0.75rem; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0.75rem; } .stat { - display: flex; - flex-direction: column; - align-items: center; - padding: 0.75rem; - background: #f5f3ee; - border-radius: 10px; + display: flex; + flex-direction: column; + align-items: center; + padding: 0.75rem; + background: #f5f3ee; + border-radius: 10px; } .stat.additions { - background: #f0fdf4; + background: #f0fdf4; } .stat.deletions { - background: #fef2f2; + background: #fef2f2; } .stat-value { - font-size: 1.25rem; - font-weight: 700; - color: var(--ink); + font-size: 1.25rem; + font-weight: 700; + color: var(--ink); } .stat.additions .stat-value { - color: #16a34a; + color: #16a34a; } .stat.deletions .stat-value { - color: #dc2626; + color: #dc2626; } .stat-label { - font-size: 0.8rem; - color: var(--muted); + font-size: 0.8rem; + color: var(--muted); } .parent-list { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; + display: flex; + gap: 0.5rem; + flex-wrap: wrap; } .parent-hash { - font-family: monospace; - font-size: 0.85rem; - padding: 0.2rem 0.5rem; - background: #f5f3ee; - border-radius: 6px; + font-family: monospace; + font-size: 0.85rem; + padding: 0.2rem 0.5rem; + background: #f5f3ee; + border-radius: 6px; } .diff-content { - font-family: monospace; - font-size: 0.8rem; - line-height: 1.5; - background: #f5f3ee; - padding: 0.75rem; - border-radius: 10px; - overflow-x: auto; - white-space: pre-wrap; - word-break: break-all; + font-family: monospace; + font-size: 0.8rem; + line-height: 1.5; + background: #f5f3ee; + padding: 0.75rem; + border-radius: 10px; + overflow-x: auto; + white-space: pre-wrap; + word-break: break-all; } @media (min-width: 1024px) { - .history-container { - grid-template-columns: 1fr 400px; - } + .history-container { + grid-template-columns: 1fr 400px; + } - .commit-list.with-detail { - grid-column: 1; - } + .commit-list.with-detail { + grid-column: 1; + } - .commit-detail-panel { - grid-column: 2; - position: sticky; - top: 1rem; - } + .commit-detail-panel { + grid-column: 2; + position: sticky; + top: 1rem; + } } /* Repository Workspace */ .repo-workspace { - display: flex; - flex-direction: column; - height: calc(100vh - 60px); - overflow: hidden; + display: flex; + flex-direction: column; + height: calc(100vh - 60px); + overflow: hidden; } .workspace-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 1.5rem; - border-bottom: 1px solid var(--border); - background: var(--panel); + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--border); + background: var(--panel); } .workspace-header-left { - display: flex; - align-items: center; - gap: 0.75rem; + display: flex; + align-items: center; + gap: 0.75rem; } .workspace-header-icon { - font-size: 1.5rem; + font-size: 1.5rem; } .workspace-header-info { - display: flex; - flex-direction: column; - gap: 0.25rem; + display: flex; + flex-direction: column; + gap: 0.25rem; } .workspace-header-title { - margin: 0; - font-size: 1.25rem; - font-weight: 600; + margin: 0; + font-size: 1.25rem; + font-weight: 600; } .workspace-header-subtitle { - color: var(--muted); - font-size: 0.875rem; + color: var(--muted); + font-size: 0.875rem; } .workspace-header-actions { - display: flex; - gap: 0.5rem; + display: flex; + gap: 0.5rem; } .workspace-header-action-btn { - display: flex; - align-items: center; - gap: 0.5rem; - padding: 0.5rem 1rem; - border: 1px solid var(--border); - border-radius: 8px; - background: var(--panel); - color: var(--ink); - font-size: 0.875rem; - cursor: pointer; - transition: all 0.2s; + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + border: 1px solid var(--border); + border-radius: 8px; + background: var(--panel); + color: var(--ink); + font-size: 0.875rem; + cursor: pointer; + transition: all 0.2s; } .workspace-header-action-btn:hover { - background: var(--bg); - border-color: var(--brand); + background: var(--bg); + border-color: var(--brand); } .workspace-title { - display: flex; - align-items: center; - gap: 1rem; + display: flex; + align-items: center; + gap: 1rem; } .workspace-title h1 { - margin: 0; - font-size: 1.25rem; + margin: 0; + font-size: 1.25rem; } .repo-name { - color: var(--muted); - font-size: 0.875rem; + color: var(--muted); + font-size: 0.875rem; } .workspace-layout { - display: flex; - flex: 1; - overflow: hidden; + display: flex; + flex: 1; + overflow: hidden; } .workspace-sidebar { - width: 280px; - min-width: 280px; - border-right: 1px solid var(--border); - background: var(--panel); - display: flex; - flex-direction: column; - overflow: hidden; + width: 280px; + min-width: 280px; + border-right: 1px solid var(--border); + background: var(--panel); + display: flex; + flex-direction: column; + overflow: hidden; } @media (max-width: 767px) { - .workspace-layout { - flex-direction: column; - } + .workspace-layout { + flex-direction: column; + } - .workspace-sidebar { - width: 100%; - min-width: auto; - max-height: 40vh; - border-right: none; - border-bottom: 1px solid var(--border); - } + .workspace-sidebar { + width: 100%; + min-width: auto; + max-height: 40vh; + border-right: none; + border-bottom: 1px solid var(--border); + } - .workspace-header { - flex-direction: column; - gap: var(--space-3); - align-items: flex-start; - padding: var(--space-4); - } + .workspace-header { + flex-direction: column; + gap: var(--space-3); + align-items: flex-start; + padding: var(--space-4); + } - .workspace-header-actions { - width: 100%; - flex-wrap: wrap; - } + .workspace-header-actions { + width: 100%; + flex-wrap: wrap; + } } .sidebar-section { - padding: 1rem; - border-bottom: 1px solid var(--border); + padding: 1rem; + border-bottom: 1px solid var(--border); } .sidebar-section label { - margin: 0; + margin: 0; } .workspace-main { - flex: 1; - overflow: hidden; - padding: 1rem; - background: var(--bg); - display: flex; - flex-direction: column; + flex: 1; + overflow: hidden; + padding: 1rem; + background: var(--bg); + display: flex; + flex-direction: column; } /* File Tree */ .file-tree { - flex: 1; - overflow: auto; - padding: 0.5rem; + flex: 1; + overflow: auto; + padding: 0.5rem; } .tree-entry { - display: block; - width: 100%; - padding: 0.375rem 0.5rem; - border: none; - background: none; - color: var(--ink); - text-align: left; - cursor: pointer; - border-radius: 4px; - font-size: 0.875rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + display: block; + width: 100%; + padding: 0.375rem 0.5rem; + border: none; + background: none; + color: var(--ink); + text-align: left; + cursor: pointer; + border-radius: 4px; + font-size: 0.875rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .tree-entry:hover { - background: var(--bg); + background: var(--bg); } .tree-directory { - font-weight: 500; + font-weight: 500; } .tree-up { - color: var(--muted); - font-style: italic; + color: var(--muted); + font-style: italic; } /* File Viewer */ .file-viewer { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 8px; - overflow: hidden; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; } .file-viewer-header { - padding: 0.75rem 1rem; - border-bottom: 1px solid var(--border); - background: var(--bg); + padding: 0.75rem 1rem; + border-bottom: 1px solid var(--border); + background: var(--bg); } .file-breadcrumbs { - font-size: 0.875rem; - font-family: monospace; + font-size: 0.875rem; + font-family: monospace; } .breadcrumb-sep { - color: var(--muted); - margin: 0 0.25rem; + color: var(--muted); + margin: 0 0.25rem; } .file-content { - padding: 1rem; - overflow: auto; - max-height: calc(100vh - 200px); + padding: 1rem; + overflow: auto; + max-height: calc(100vh - 200px); } .file-content pre { - margin: 0; - font-family: "IBM Plex Mono", monospace; - font-size: 0.875rem; - line-height: 1.5; - white-space: pre-wrap; - word-wrap: break-word; + margin: 0; + font-family: "IBM Plex Mono", monospace; + font-size: 0.875rem; + line-height: 1.5; + white-space: pre-wrap; + word-wrap: break-word; } .file-viewer-empty { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - min-height: 300px; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + min-height: 300px; } /* File Status Indicators */ .file-status-indicator { - float: right; - font-size: 0.75rem; - font-weight: bold; - padding: 0 0.375rem; - border-radius: 3px; - margin-left: 0.5rem; + float: right; + font-size: 0.75rem; + font-weight: bold; + padding: 0 0.375rem; + border-radius: 3px; + margin-left: 0.5rem; } .file-status-indicator.modified { - color: #f59e0b; - background: rgba(245, 158, 11, 0.1); + color: #f59e0b; + background: rgba(245, 158, 11, 0.1); } .file-status-indicator.added { - color: #10b981; - background: rgba(16, 185, 129, 0.1); + color: #10b981; + background: rgba(16, 185, 129, 0.1); } .file-status-indicator.deleted { - color: #ef4444; - background: rgba(239, 68, 68, 0.1); + color: #ef4444; + background: rgba(239, 68, 68, 0.1); } .file-status-indicator.untracked { - color: #6b7280; - background: rgba(107, 114, 128, 0.1); + color: #6b7280; + background: rgba(107, 114, 128, 0.1); } /* Commit Panel */ .commit-panel { - padding: 1rem; - border-top: 1px solid var(--border); - background: var(--panel); + padding: 1rem; + border-top: 1px solid var(--border); + background: var(--panel); } .commit-panel h4 { - margin: 0 0 0.5rem 0; - font-size: 0.875rem; - font-weight: 600; + margin: 0 0 0.5rem 0; + font-size: 0.875rem; + font-weight: 600; } .file-list { - max-height: 150px; - overflow: auto; - margin-bottom: 0.75rem; + max-height: 150px; + overflow: auto; + margin-bottom: 0.75rem; } .file-item { - display: flex; - align-items: center; - gap: 0.5rem; - padding: 0.25rem 0; - font-size: 0.8125rem; + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.25rem 0; + font-size: 0.8125rem; } .file-status { - font-weight: bold; - font-size: 0.75rem; - width: 1rem; - text-align: center; + font-weight: bold; + font-size: 0.75rem; + width: 1rem; + text-align: center; } -.file-item.modified .file-status { color: #f59e0b; } -.file-item.added .file-status { color: #10b981; } -.file-item.deleted .file-status { color: #ef4444; } -.file-item.untracked .file-status { color: #6b7280; } +.file-item.modified .file-status { + color: #f59e0b; +} +.file-item.added .file-status { + color: #10b981; +} +.file-item.deleted .file-status { + color: #ef4444; +} +.file-item.untracked .file-status { + color: #6b7280; +} .commit-form { - display: flex; - flex-direction: column; - gap: 0.5rem; + display: flex; + flex-direction: column; + gap: 0.5rem; } .commit-message-input { - width: 100%; - padding: 0.5rem; - border: 1px solid var(--border); - border-radius: 4px; - background: var(--bg); - color: var(--ink); - font-family: inherit; - font-size: 0.875rem; - resize: vertical; + width: 100%; + padding: 0.5rem; + border: 1px solid var(--border); + border-radius: 4px; + background: var(--bg); + color: var(--ink); + font-family: inherit; + font-size: 0.875rem; + resize: vertical; } .commit-button { - padding: 0.5rem 1rem; - background: var(--primary); - color: white; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 0.875rem; - font-weight: 500; + padding: 0.5rem 1rem; + background: var(--primary); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; } .commit-button:disabled { - opacity: 0.5; - cursor: not-allowed; + opacity: 0.5; + cursor: not-allowed; } .commit-error { - color: #ef4444; - font-size: 0.8125rem; + color: #ef4444; + font-size: 0.8125rem; } /* Modal Styles */ .modal-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; } .modal-content { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 8px; - padding: 1.5rem; - min-width: 400px; - max-width: 600px; - max-height: 80vh; - overflow: auto; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 8px; + padding: 1.5rem; + min-width: 400px; + max-width: 600px; + max-height: 80vh; + overflow: auto; } .modal-content h2 { - margin: 0 0 1rem 0; - font-size: 1.25rem; + margin: 0 0 1rem 0; + font-size: 1.25rem; } .modal-actions { - display: flex; - justify-content: flex-end; - gap: 0.75rem; - margin-top: 1.5rem; + display: flex; + justify-content: flex-end; + gap: 0.75rem; + margin-top: 1.5rem; } /* Merge Dialog */ .merge-form { - display: flex; - flex-direction: column; - gap: 1rem; + display: flex; + flex-direction: column; + gap: 1rem; } .merge-form .form-field { - display: flex; - flex-direction: column; - gap: 0.375rem; + display: flex; + flex-direction: column; + gap: 0.375rem; } .merge-form label { - font-size: 0.875rem; - font-weight: 500; + font-size: 0.875rem; + font-weight: 500; } .merge-form select, .merge-form input, .merge-form textarea { - padding: 0.5rem; - border: 1px solid var(--border); - border-radius: 4px; - background: var(--bg); - color: var(--ink); - font-family: inherit; - font-size: 0.875rem; + padding: 0.5rem; + border: 1px solid var(--border); + border-radius: 4px; + background: var(--bg); + color: var(--ink); + font-family: inherit; + font-size: 0.875rem; } .merge-form textarea { - resize: vertical; + resize: vertical; } .input-disabled { - opacity: 0.6; - cursor: not-allowed; + opacity: 0.6; + cursor: not-allowed; } .success-text { - color: #10b981; - font-size: 0.875rem; - padding: 0.5rem; - background: rgba(16, 185, 129, 0.1); - border-radius: 4px; + color: #10b981; + font-size: 0.875rem; + padding: 0.5rem; + background: rgba(16, 185, 129, 0.1); + border-radius: 4px; } /* Settings Layout */ .settings-layout { - display: flex; - gap: 2rem; - padding: 1.5rem 0; + display: flex; + gap: 2rem; + padding: 1.5rem 0; } .settings-sidebar { - width: 200px; - flex-shrink: 0; + width: 200px; + flex-shrink: 0; } .settings-nav { - display: flex; - flex-direction: column; - gap: 0.25rem; + display: flex; + flex-direction: column; + gap: 0.25rem; } .settings-nav-link { - padding: 0.625rem 1rem; - border-radius: 8px; - color: var(--muted); - text-decoration: none; - font-size: 0.95rem; - transition: all 0.2s; + padding: 0.625rem 1rem; + border-radius: 8px; + color: var(--muted); + text-decoration: none; + font-size: 0.95rem; + transition: all 0.2s; } .settings-nav-link:hover { - background: var(--bg); - color: var(--ink); + background: var(--bg); + color: var(--ink); } .settings-nav-link.active { - background: var(--brand); - color: white; - font-weight: 500; + background: var(--brand); + color: white; + font-weight: 500; } .settings-content { - flex: 1; - min-width: 0; + flex: 1; + min-width: 0; } .settings-panel { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 14px; - padding: 1.5rem; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 14px; + padding: 1.5rem; } /* Mobile responsiveness */ @media (max-width: 768px) { - .settings-layout { - flex-direction: column; - gap: 1rem; - } + .settings-layout { + flex-direction: column; + gap: 1rem; + } - .settings-sidebar { - width: 100%; - } + .settings-sidebar { + width: 100%; + } - .settings-nav { - flex-direction: row; - overflow-x: auto; - padding-bottom: 0.5rem; - } + .settings-nav { + flex-direction: row; + overflow-x: auto; + padding-bottom: 0.5rem; + } - .settings-nav-link { - white-space: nowrap; - padding: 0.5rem 0.75rem; - font-size: 0.875rem; - } + .settings-nav-link { + white-space: nowrap; + padding: 0.5rem 0.75rem; + font-size: 0.875rem; + } - .workspace-header { - flex-direction: column; - gap: 1rem; - align-items: flex-start; - } + .workspace-header { + flex-direction: column; + gap: 1rem; + align-items: flex-start; + } - .workspace-header-actions { - width: 100%; - justify-content: flex-start; - } + .workspace-header-actions { + width: 100%; + justify-content: flex-start; + } } .settings-panel h2 { - margin: 0 0 1.25rem; - font-size: 1.25rem; + margin: 0 0 1.25rem; + font-size: 1.25rem; } .settings-breadcrumb { - display: flex; - align-items: center; - gap: 0.5rem; - font-size: 0.9rem; - color: var(--muted); - margin-bottom: 1rem; + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.9rem; + color: var(--muted); + margin-bottom: 1rem; } .settings-breadcrumb a { - color: var(--brand); - text-decoration: none; + color: var(--brand); + text-decoration: none; } .settings-breadcrumb a:hover { - text-decoration: underline; + text-decoration: underline; } .project-settings-page { - padding: 1.5rem; + padding: 1.5rem; } /* Repositories Settings Tab */ .repositories-settings-tab h2 { - margin: 0 0 1.25rem; - font-size: 1.25rem; + margin: 0 0 1.25rem; + font-size: 1.25rem; } .repositories-list { - display: flex; - flex-direction: column; - gap: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.75rem; } .repository-card { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - background: var(--bg); - border: 1px solid var(--border); - border-radius: 10px; + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 10px; } .repository-info h3 { - margin: 0 0 0.25rem; - font-size: 1rem; + margin: 0 0 0.25rem; + font-size: 1rem; } .repository-info p { - margin: 0 0 0.5rem; - font-size: 0.85rem; - color: var(--muted); + margin: 0 0 0.5rem; + font-size: 0.85rem; + color: var(--muted); } .repo-type { - font-size: 0.75rem; - padding: 0.2rem 0.5rem; - background: var(--brand); - color: white; - border-radius: 999px; + font-size: 0.75rem; + padding: 0.2rem 0.5rem; + background: var(--brand); + color: white; + border-radius: 999px; } /* Git Toolbar - Top Bar Styles */ .git-toolbar { - display: flex; - align-items: center; - gap: 1rem; - padding: 0.5rem 1.5rem; - background: var(--bg); - border-bottom: 1px solid var(--border); - min-height: 48px; + display: flex; + align-items: center; + gap: 1rem; + padding: 0.5rem 1.5rem; + background: var(--bg); + border-bottom: 1px solid var(--border); + min-height: 48px; } .toolbar-row { - display: flex; - align-items: center; - gap: 0.75rem; - flex-wrap: wrap; + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; } .toolbar-group { - display: flex; - align-items: center; - gap: 0.5rem; + display: flex; + align-items: center; + gap: 0.5rem; } .toolbar-button { - display: flex; - align-items: center; - gap: 0.35rem; - padding: 0.4rem 0.75rem; - border: 1px solid var(--border); - border-radius: 6px; - background: var(--panel); - color: var(--ink); - font-size: 0.85rem; - cursor: pointer; - transition: all 0.2s; - white-space: nowrap; + display: flex; + align-items: center; + gap: 0.35rem; + padding: 0.4rem 0.75rem; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--panel); + color: var(--ink); + font-size: 0.85rem; + cursor: pointer; + transition: all 0.2s; + white-space: nowrap; } .toolbar-button:hover:not(:disabled) { - background: var(--brand); - color: white; - border-color: var(--brand); + background: var(--brand); + color: white; + border-color: var(--brand); } .toolbar-button:disabled { - opacity: 0.5; - cursor: not-allowed; + opacity: 0.5; + cursor: not-allowed; } .toolbar-button.primary { - background: var(--brand); - color: white; - border-color: var(--brand); + background: var(--brand); + color: white; + border-color: var(--brand); } .branch-select { - padding: 0.4rem 0.75rem; - border: 1px solid var(--border); - border-radius: 6px; - background: var(--panel); - color: var(--ink); - font-size: 0.85rem; - cursor: pointer; - min-width: 140px; + padding: 0.4rem 0.75rem; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--panel); + color: var(--ink); + font-size: 0.85rem; + cursor: pointer; + min-width: 140px; } .badge { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 18px; - height: 18px; - padding: 0 4px; - background: var(--brand); - color: white; - font-size: 0.7rem; - font-weight: 600; - border-radius: 999px; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 18px; + height: 18px; + padding: 0 4px; + background: var(--brand); + color: white; + font-size: 0.7rem; + font-weight: 600; + border-radius: 999px; } .toolbar-error { - color: #ef4444; - font-size: 0.85rem; - padding: 0.25rem 0.5rem; - background: rgba(239, 68, 68, 0.1); - border-radius: 4px; + color: #ef4444; + font-size: 0.85rem; + padding: 0.25rem 0.5rem; + background: rgba(239, 68, 68, 0.1); + border-radius: 4px; } .toolbar-input { - padding: 0.4rem 0.75rem; - border: 1px solid var(--border); - border-radius: 6px; - background: var(--panel); - color: var(--ink); - font-size: 0.85rem; + padding: 0.4rem 0.75rem; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--panel); + color: var(--ink); + font-size: 0.85rem; } .new-branch-form { - padding: 0.75rem; - background: var(--panel); - border: 1px solid var(--border); - border-radius: 8px; - margin-top: 0.5rem; + padding: 0.75rem; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 8px; + margin-top: 0.5rem; } .status-summary { - gap: 0.75rem; + gap: 0.75rem; } .status-badge { - display: inline-flex; - align-items: center; - gap: 0.25rem; - padding: 0.2rem 0.5rem; - border-radius: 4px; - font-size: 0.8rem; + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.2rem 0.5rem; + border-radius: 4px; + font-size: 0.8rem; } .status-badge.modified { - background: rgba(245, 158, 11, 0.1); - color: #d97706; + background: rgba(245, 158, 11, 0.1); + color: #d97706; } .status-badge.added { - background: rgba(16, 185, 129, 0.1); - color: #059669; + background: rgba(16, 185, 129, 0.1); + color: #059669; } .status-badge.deleted { - background: rgba(239, 68, 68, 0.1); - color: #dc2626; + background: rgba(239, 68, 68, 0.1); + color: #dc2626; } .status-badge.untracked { - background: rgba(107, 114, 128, 0.1); - color: #4b5563; + background: rgba(107, 114, 128, 0.1); + color: #4b5563; } /* File Editor */ .file-editor { - display: flex; - flex-direction: column; - height: 100%; - overflow: hidden; + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; } .file-editor-toolbar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.75rem 1rem; - background: var(--panel); - border-bottom: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem 1rem; + background: var(--panel); + border-bottom: 1px solid var(--border); } .file-actions { - display: flex; - gap: 0.5rem; + display: flex; + gap: 0.5rem; } .file-editor-content { - flex: 1; - overflow: hidden; - background: var(--bg); - display: flex; - flex-direction: column; + flex: 1; + overflow: hidden; + background: var(--bg); + display: flex; + flex-direction: column; } /* Syntax Highlighter */ .syntax-highlighter { - display: flex; - flex-direction: column; - height: 100%; + display: flex; + flex-direction: column; + height: 100%; } .highlighter-toolbar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.5rem 1rem; - background: var(--panel); - border-bottom: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 1rem; + background: var(--panel); + border-bottom: 1px solid var(--border); } .language-badge { - font-size: 0.8rem; - padding: 0.2rem 0.5rem; - background: var(--bg); - border-radius: 4px; - color: var(--muted); + font-size: 0.8rem; + padding: 0.2rem 0.5rem; + background: var(--bg); + border-radius: 4px; + color: var(--muted); } .copy-button { - font-size: 0.8rem; - padding: 0.25rem 0.5rem; - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; - cursor: pointer; - color: var(--ink); + font-size: 0.8rem; + padding: 0.25rem 0.5rem; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 4px; + cursor: pointer; + color: var(--ink); } .copy-button:hover { - background: var(--brand); - color: white; - border-color: var(--brand); + background: var(--brand); + color: white; + border-color: var(--brand); } .code-container { - display: flex; - flex: 1; - overflow: auto; - font-family: 'Fira Code', 'Monaco', 'Courier New', monospace; - font-size: 14px; - line-height: 1.5; + display: flex; + flex: 1; + overflow: auto; + font-family: "Fira Code", "Monaco", "Courier New", monospace; + font-size: 14px; + line-height: 1.5; } .line-numbers { - display: flex; - flex-direction: column; - padding: 1rem 0.5rem; - background: var(--panel); - border-right: 1px solid var(--border); - color: var(--muted); - text-align: right; - user-select: none; - min-width: 3rem; + display: flex; + flex-direction: column; + padding: 1rem 0.5rem; + background: var(--panel); + border-right: 1px solid var(--border); + color: var(--muted); + text-align: right; + user-select: none; + min-width: 3rem; } .line-number { - padding: 0 0.5rem; + padding: 0 0.5rem; } .code-block { - flex: 1; - margin: 0; - padding: 1rem; - overflow: visible; - background: transparent; + flex: 1; + margin: 0; + padding: 1rem; + overflow: visible; + background: transparent; } .code-block code { - display: block; - background: transparent; + display: block; + background: transparent; } /* Code Editor */ .code-editor { - height: 100%; - overflow: auto; + height: 100%; + overflow: auto; } .editor-textarea { - font-family: 'Fira Code', 'Monaco', 'Courier New', monospace; - font-size: 14px; - line-height: 1.5; - min-height: 100%; + font-family: "Fira Code", "Monaco", "Courier New", monospace; + font-size: 14px; + line-height: 1.5; + min-height: 100%; } .editor-textarea-input { - background: transparent; - color: var(--ink); - caret-color: var(--ink); + background: transparent; + color: var(--ink); + caret-color: var(--ink); } .editor-line { - display: flex; + display: flex; } .editor-line-number { - display: inline-block; - width: 3rem; - padding: 0 0.5rem; - text-align: right; - color: var(--muted); - user-select: none; - background: var(--panel); - border-right: 1px solid var(--border); + display: inline-block; + width: 3rem; + padding: 0 0.5rem; + text-align: right; + color: var(--muted); + user-select: none; + background: var(--panel); + border-right: 1px solid var(--border); } .editor-line-content { - flex: 1; - padding: 0 0.5rem; - white-space: pre; + flex: 1; + padding: 0 0.5rem; + white-space: pre; } /* Commit Dialog */ .dialog-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - padding: 1rem; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 1rem; } .commit-dialog { - background: var(--panel); - border-radius: 14px; - width: 100%; - max-width: 600px; - max-height: 90vh; - overflow: auto; - box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); + background: var(--panel); + border-radius: 14px; + width: 100%; + max-width: 600px; + max-height: 90vh; + overflow: auto; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); } .dialog-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 1.5rem; - border-bottom: 1px solid var(--border); + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--border); } .dialog-header h3 { - margin: 0; - font-size: 1.1rem; + margin: 0; + font-size: 1.1rem; } .dialog-close { - background: none; - border: none; - font-size: 1.5rem; - cursor: pointer; - color: var(--muted); - padding: 0; - width: 2rem; - height: 2rem; - display: flex; - align-items: center; - justify-content: center; - border-radius: 6px; + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: var(--muted); + padding: 0; + width: 2rem; + height: 2rem; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; } .dialog-close:hover { - background: var(--bg); - color: var(--ink); + background: var(--bg); + color: var(--ink); } .dialog-body { - padding: 1.5rem; + padding: 1.5rem; } .file-info { - margin: 0 0 1rem; - color: var(--muted); + margin: 0 0 1rem; + color: var(--muted); } .diff-preview { - margin-bottom: 1.5rem; + margin-bottom: 1.5rem; } .diff-preview h4 { - margin: 0 0 0.75rem; - font-size: 0.9rem; - color: var(--muted); + margin: 0 0 0.75rem; + font-size: 0.9rem; + color: var(--muted); } .diff-content { - background: var(--bg); - border: 1px solid var(--border); - border-radius: 8px; - overflow: auto; - max-height: 300px; - font-family: 'Fira Code', 'Monaco', 'Courier New', monospace; - font-size: 13px; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 8px; + overflow: auto; + max-height: 300px; + font-family: "Fira Code", "Monaco", "Courier New", monospace; + font-size: 13px; } .diff-line { - display: flex; - padding: 0.15rem 0.5rem; - gap: 0.5rem; + display: flex; + padding: 0.15rem 0.5rem; + gap: 0.5rem; } .diff-line-number { - color: var(--muted); - min-width: 2rem; - text-align: right; - user-select: none; + color: var(--muted); + min-width: 2rem; + text-align: right; + user-select: none; } .diff-marker { - width: 1rem; - text-align: center; - font-weight: bold; + width: 1rem; + text-align: center; + font-weight: bold; } .diff-added { - background: rgba(16, 185, 129, 0.1); + background: rgba(16, 185, 129, 0.1); } .diff-added .diff-marker { - color: #059669; + color: #059669; } .diff-removed { - background: rgba(239, 68, 68, 0.1); + background: rgba(239, 68, 68, 0.1); } .diff-removed .diff-marker { - color: #dc2626; + color: #dc2626; } .diff-same { - background: transparent; + background: transparent; } .warning-message { - padding: 0.75rem; - background: rgba(245, 158, 11, 0.1); - color: #d97706; - border-radius: 8px; - margin-bottom: 1rem; + padding: 0.75rem; + background: rgba(245, 158, 11, 0.1); + color: #d97706; + border-radius: 8px; + margin-bottom: 1rem; } .dialog-footer { - display: flex; - justify-content: flex-end; - gap: 0.75rem; - padding: 1rem 1.5rem; - border-top: 1px solid var(--border); + display: flex; + justify-content: flex-end; + gap: 0.75rem; + padding: 1rem 1.5rem; + border-top: 1px solid var(--border); } /* Prism.js Theme Integration */ code[class*="language-"], pre[class*="language-"] { - color: var(--ink); - text-shadow: none; - font-family: 'Fira Code', 'Monaco', 'Courier New', monospace; - font-size: 14px; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - tab-size: 2; - hyphens: none; + color: var(--ink); + text-shadow: none; + font-family: "Fira Code", "Monaco", "Courier New", monospace; + font-size: 14px; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + tab-size: 2; + hyphens: none; } /* Syntax Highlighting Colors */ @@ -1971,15 +1979,15 @@ pre[class*="language-"] { .token.prolog, .token.doctype, .token.cdata { - color: var(--muted); + color: var(--muted); } .token.punctuation { - color: var(--ink); + color: var(--ink); } .token.namespace { - opacity: 0.7; + opacity: 0.7; } .token.property, @@ -1989,7 +1997,7 @@ pre[class*="language-"] { .token.constant, .token.symbol, .token.deleted { - color: #f59e0b; + color: #f59e0b; } .token.selector, @@ -1998,7 +2006,7 @@ pre[class*="language-"] { .token.char, .token.builtin, .token.inserted { - color: #10b981; + color: #10b981; } .token.operator, @@ -2006,78 +2014,78 @@ pre[class*="language-"] { .token.url, .language-css .token.string, .style .token.string { - color: #f43f5e; + color: #f43f5e; } .token.atrule, .token.attr-value, .token.keyword { - color: #3b82f6; + color: #3b82f6; } .token.function, .token.class-name { - color: #8b5cf6; + color: #8b5cf6; } .token.regex, .token.important, .token.variable { - color: #ec4899; + color: #ec4899; } /* Icon System */ .icon { - display: inline-flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - vertical-align: middle; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + vertical-align: middle; } .icon svg { - display: block; + display: block; } .icon-sm { - width: 16px; - height: 16px; + width: 16px; + height: 16px; } .icon-md { - width: 20px; - height: 20px; + width: 20px; + height: 20px; } .icon-lg { - width: 24px; - height: 24px; + width: 24px; + height: 24px; } .icon-xl { - width: 32px; - height: 32px; + width: 32px; + height: 32px; } /* Button icons */ button .icon, a .icon { - margin-right: 0.35rem; + margin-right: 0.35rem; } button .icon:last-child, a .icon:last-child { - margin-right: 0; + margin-right: 0; } /* Navigation icons */ .nav-item .icon { - margin-right: 0.5rem; + margin-right: 0.5rem; } /* Status badge icons */ .status-badge .icon { - margin-right: 0.25rem; + margin-right: 0.25rem; } /* ============================================ @@ -2086,61 +2094,61 @@ a .icon:last-child { /* Layout Utilities */ .container { - width: 100%; - max-width: min(1200px, 100vw - 2rem); - margin-inline: auto; - padding-inline: var(--space-4); + width: 100%; + max-width: min(1200px, 100vw - 2rem); + margin-inline: auto; + padding-inline: var(--space-4); } .stack { - display: flex; - flex-direction: column; - gap: var(--space-4); + display: flex; + flex-direction: column; + gap: var(--space-4); } .stack-sm { - gap: var(--space-2); + gap: var(--space-2); } .stack-md { - gap: var(--space-4); + gap: var(--space-4); } .stack-lg { - gap: var(--space-6); + gap: var(--space-6); } .row { - display: flex; - flex-wrap: wrap; - gap: var(--space-4); - align-items: center; + display: flex; + flex-wrap: wrap; + gap: var(--space-4); + align-items: center; } .grid { - display: grid; - gap: var(--space-4); - grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); + display: grid; + gap: var(--space-4); + grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); } /* Text Utilities */ .truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .truncate-multiline { - display: -webkit-box; - -webkit-line-clamp: 3; - -webkit-box-orient: vertical; - overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; } .break-word { - overflow-wrap: break-word; - word-wrap: break-word; - hyphens: auto; + overflow-wrap: break-word; + word-wrap: break-word; + hyphens: auto; } /* Touch Targets */ @@ -2149,104 +2157,104 @@ a .icon:last-child { .icon-button, button, [role="button"] { - min-height: 44px; - min-width: 44px; + min-height: 44px; + min-width: 44px; } /* Dialog Responsive */ .dialog { - width: min(560px, 100vw - 2rem); - max-height: min(800px, 100vh - 2rem); - overflow-y: auto; + width: min(560px, 100vw - 2rem); + max-height: min(800px, 100vh - 2rem); + overflow-y: auto; } .dialog-lg { - width: min(800px, 100vw - 2rem); + width: min(800px, 100vw - 2rem); } /* Table Responsive */ .table-responsive { - overflow-x: auto; - -webkit-overflow-scrolling: touch; + overflow-x: auto; + -webkit-overflow-scrolling: touch; } .table-responsive table { - min-width: 100%; + min-width: 100%; } /* Mobile-first Media Queries */ @media (max-width: 767px) { - /* Card layout for tables on mobile */ - .table-responsive thead { - display: none; - } + /* Card layout for tables on mobile */ + .table-responsive thead { + display: none; + } - .table-responsive tbody tr { - display: block; - margin-bottom: var(--space-4); - border: 1px solid var(--border); - border-radius: 8px; - padding: var(--space-4); - } + .table-responsive tbody tr { + display: block; + margin-bottom: var(--space-4); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--space-4); + } - .table-responsive td { - display: flex; - justify-content: space-between; - padding: var(--space-2) 0; - border-bottom: 1px solid var(--border); - } + .table-responsive td { + display: flex; + justify-content: space-between; + padding: var(--space-2) 0; + border-bottom: 1px solid var(--border); + } - .table-responsive td:last-child { - border-bottom: none; - } + .table-responsive td:last-child { + border-bottom: none; + } - .table-responsive td::before { - content: attr(data-label); - font-weight: 600; - margin-right: var(--space-2); - } + .table-responsive td::before { + content: attr(data-label); + font-weight: 600; + margin-right: var(--space-2); + } - /* Larger touch targets on mobile */ - .button, - button { - padding: var(--space-3) var(--space-4); - } + /* Larger touch targets on mobile */ + .button, + button { + padding: var(--space-3) var(--space-4); + } - /* Full-width inputs on mobile */ - input, - select, - textarea { - width: 100%; - min-height: 44px; - } + /* Full-width inputs on mobile */ + input, + select, + textarea { + width: 100%; + min-height: 44px; + } } /* Small devices */ @media (min-width: 480px) { - .container { - padding-inline: var(--space-5); - } + .container { + padding-inline: var(--space-5); + } } /* Medium devices */ @media (min-width: 768px) { - .container { - padding-inline: var(--space-6); - } + .container { + padding-inline: var(--space-6); + } } /* Large devices */ @media (min-width: 1024px) { - .container { - padding-inline: var(--space-8); - } + .container { + padding-inline: var(--space-8); + } } /* Extra large devices */ @media (min-width: 1280px) { - .container { - max-width: 1200px; - } + .container { + max-width: 1200px; + } } /* ============================================ @@ -2255,74 +2263,74 @@ button, /* Forms - Full width on mobile */ @media (max-width: 767px) { - .form-field input, - .form-field textarea, - .form-field select { - width: 100%; - min-height: 44px; - } + .form-field input, + .form-field textarea, + .form-field select { + width: 100%; + min-height: 44px; + } - /* Settings page stack */ - .settings-layout { - flex-direction: column; - } + /* Settings page stack */ + .settings-layout { + flex-direction: column; + } - .settings-nav { - flex-direction: row; - overflow-x: auto; - padding-bottom: var(--space-2); - } + .settings-nav { + flex-direction: row; + overflow-x: auto; + padding-bottom: var(--space-2); + } - /* Project cards full width */ - .project-card { - flex-direction: column; - gap: var(--space-3); - } + /* Project cards full width */ + .project-card { + flex-direction: column; + gap: var(--space-3); + } - .project-actions { - width: 100%; - justify-content: flex-start; - } + .project-actions { + width: 100%; + justify-content: flex-start; + } - /* Repository cards */ - .repository-card { - flex-direction: column; - gap: var(--space-3); - align-items: flex-start; - } + /* Repository cards */ + .repository-card { + flex-direction: column; + gap: var(--space-3); + align-items: flex-start; + } - .repository-actions { - width: 100%; - justify-content: flex-start; - } + .repository-actions { + width: 100%; + justify-content: flex-start; + } - /* Git toolbar wrap */ - .git-toolbar { - flex-wrap: wrap; - gap: var(--space-2); - } + /* Git toolbar wrap */ + .git-toolbar { + flex-wrap: wrap; + gap: var(--space-2); + } - /* Dashboard cards */ - .dashboard-grid { - grid-template-columns: 1fr; - } + /* Dashboard cards */ + .dashboard-grid { + grid-template-columns: 1fr; + } - /* Stack form actions */ - .form-actions { - flex-direction: column; - width: 100%; - } + /* Stack form actions */ + .form-actions { + flex-direction: column; + width: 100%; + } - .form-actions button { - width: 100%; - justify-content: center; - } + .form-actions button { + width: 100%; + justify-content: center; + } } /* Ensure all pages have proper padding */ .stack > h1, .stack > h2 { - margin-top: 0; + margin-top: 0; } /* Touch target verification override */ @@ -2330,193 +2338,193 @@ button, [role="button"], a.nav-item, .tree-entry { - min-height: 44px; + min-height: 44px; } /* Table horizontal scroll wrapper */ .table-wrapper { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + width: 100%; } /* Dialog content spacing */ .dialog-body { - padding: var(--space-4) 0; + padding: var(--space-4) 0; } /* Prevent text overflow in cards */ .card h3, .card p { - overflow: hidden; - text-overflow: ellipsis; + overflow: hidden; + text-overflow: ellipsis; } /* SSH keys table responsive */ .ssh-key-list { - display: flex; - flex-direction: column; - gap: var(--space-3); + display: flex; + flex-direction: column; + gap: var(--space-3); } .ssh-key-item { - display: flex; - flex-direction: column; - gap: var(--space-2); - padding: var(--space-4); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 10px; + display: flex; + flex-direction: column; + gap: var(--space-2); + padding: var(--space-4); + background: var(--bg); + border: 1px solid var(--border); + border-radius: 10px; } @media (min-width: 768px) { - .ssh-key-item { - flex-direction: row; - justify-content: space-between; - align-items: center; - } + .ssh-key-item { + flex-direction: row; + justify-content: space-between; + align-items: center; + } } /* Session Navigation */ .session-item { - position: relative; - padding-left: var(--space-6); + position: relative; + padding-left: var(--space-6); } .session-status { - position: absolute; - left: var(--space-2); - top: 50%; - transform: translateY(-50%); - width: 8px; - height: 8px; - border-radius: 50%; - background: var(--muted); + position: absolute; + left: var(--space-2); + top: 50%; + transform: translateY(-50%); + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--muted); } .session-status.running { - background: var(--success); + background: var(--success); } .session-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 140px; } .nav-divider { - height: 1px; - background: var(--border); - margin: var(--space-2) var(--space-3); + height: 1px; + background: var(--border); + margin: var(--space-2) var(--space-3); } .nav-section-title { - padding: var(--space-2) var(--space-4); - font-size: var(--text-xs); - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - color: var(--muted); + padding: var(--space-2) var(--space-4); + font-size: var(--text-xs); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--muted); } /* Instance List */ .instance-list { - margin-top: var(--space-4); + margin-top: var(--space-4); } .instance-list-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: var(--space-4); + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--space-4); } .instance-list-header h3 { - margin: 0; + margin: 0; } .instance-grid { - display: grid; - gap: var(--space-3); + display: grid; + gap: var(--space-3); } .instance-card { - display: flex; - justify-content: space-between; - align-items: center; - padding: var(--space-4); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 10px; - position: relative; + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-4); + background: var(--bg); + border: 1px solid var(--border); + border-radius: 10px; + position: relative; } .instance-info { - display: flex; - flex-direction: column; - gap: var(--space-1); + display: flex; + flex-direction: column; + gap: var(--space-1); } .instance-name { - font-weight: 600; + font-weight: 600; } .instance-meta { - display: flex; - align-items: center; - gap: var(--space-2); - font-size: var(--text-sm); - color: var(--muted); + display: flex; + align-items: center; + gap: var(--space-2); + font-size: var(--text-sm); + color: var(--muted); } .status-dot { - width: 8px; - height: 8px; - border-radius: 50%; + width: 8px; + height: 8px; + border-radius: 50%; } .instance-actions { - display: flex; - gap: var(--space-2); - align-items: center; + display: flex; + gap: var(--space-2); + align-items: center; } .instance-card.busy { - opacity: 0.7; + opacity: 0.7; } .instance-busy-overlay { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - gap: var(--space-2); - background: rgba(var(--bg-rgb, 255, 255, 255), 0.8); - border-radius: 10px; - z-index: 1; - font-size: var(--text-sm); - color: var(--muted); + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + gap: var(--space-2); + background: rgba(var(--bg-rgb, 255, 255, 255), 0.8); + border-radius: 10px; + z-index: 1; + font-size: var(--text-sm); + color: var(--muted); } .session-card { - position: relative; + position: relative; } .session-card.busy { - opacity: 0.7; + opacity: 0.7; } .session-busy-overlay { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - background: rgba(var(--bg-rgb, 255, 255, 255), 0.8); - border-radius: var(--space-2); - z-index: 1; + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + background: rgba(var(--bg-rgb, 255, 255, 255), 0.8); + border-radius: var(--space-2); + z-index: 1; } /* ============================================ @@ -2524,143 +2532,417 @@ a.nav-item, ============================================ */ .terminal-page { - display: flex; - flex-direction: column; - height: 100%; - min-height: 0; - padding: var(--space-4); - gap: var(--space-4); + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + padding: var(--space-4); + gap: var(--space-4); } .terminal-page-header { - display: flex; - align-items: center; - gap: var(--space-4); - flex-shrink: 0; + display: flex; + align-items: center; + gap: var(--space-4); + flex-shrink: 0; } .terminal-page-header h1 { - margin: 0; + margin: 0; } .terminal-wrapper { - display: grid; - grid-template-rows: auto 1fr; - flex: 1; - min-height: 0; - border: 1px solid var(--border); - border-radius: 10px; - overflow: hidden; - background: #1e1e1e; + display: grid; + grid-template-rows: auto 1fr; + flex: 1; + min-height: 0; + border: 1px solid var(--border); + border-radius: 10px; + overflow: hidden; + background: #1e1e1e; } .terminal-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: var(--space-3) var(--space-4); - background: #2d2d2d; - border-bottom: 1px solid #3e3e3e; - flex-shrink: 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-3) var(--space-4); + background: #2d2d2d; + border-bottom: 1px solid #3e3e3e; + flex-shrink: 0; } .terminal-status { - display: flex; - align-items: center; - gap: var(--space-2); + display: flex; + align-items: center; + gap: var(--space-2); } .status-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: #666; + width: 8px; + height: 8px; + border-radius: 50%; + background: #666; } .status-dot.connecting { - background: #f5f543; - animation: pulse 1.5s infinite; + background: #f5f543; + animation: pulse 1.5s infinite; } .status-dot.connected { - background: #0dbc79; + background: #0dbc79; } .status-dot.disconnected, .status-dot.error { - background: #cd3131; + background: #cd3131; } @keyframes pulse { - 0%, - 100% { - opacity: 1; - } - 50% { - opacity: 0.5; - } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } .status-text { - font-size: 0.875rem; - color: #d4d4d4; - text-transform: capitalize; + font-size: 0.875rem; + color: #d4d4d4; + text-transform: capitalize; } .terminal-close { - padding: var(--space-1) var(--space-3); - background: transparent; - border: 1px solid #666; - border-radius: 6px; - color: #d4d4d4; - cursor: pointer; - font-size: 0.875rem; + padding: var(--space-1) var(--space-3); + background: transparent; + border: 1px solid #666; + border-radius: 6px; + color: #d4d4d4; + cursor: pointer; + font-size: 0.875rem; } .terminal-close:hover { - background: #3e3e3e; + background: #3e3e3e; } .terminal-error { - padding: var(--space-3) var(--space-4); - background: #cd3131; - color: white; - font-size: 0.875rem; - flex-shrink: 0; + padding: var(--space-3) var(--space-4); + background: #cd3131; + color: white; + font-size: 0.875rem; + flex-shrink: 0; } .terminal-container { - position: relative; - width: 100%; - height: 100%; - padding: 0; - overflow: hidden; + position: relative; + width: 100%; + height: 100%; + padding: 0; + overflow: hidden; } /* xterm.js manages its own positioning and sizing */ .terminal-container canvas { - display: block; + display: block; } /* xterm.js manages its own viewport dimensions - do not override */ /* Mobile terminal container - no padding to maximize space */ .terminal-wrapper.mobile .terminal-container { - padding: 0; + padding: 0; } /* Ensure xterm viewport fills container properly */ /* Responsive terminal */ @media (max-width: 767px) { - .terminal-page { - padding: var(--space-2); - gap: var(--space-2); - } + .terminal-page { + padding: var(--space-2); + gap: var(--space-2); + } - .terminal-page-header h1 { - font-size: 1.25rem; - } + .terminal-page-header h1 { + font-size: 1.25rem; + } +} + +/* ============================================ + Terminal Session Tabs + ============================================ */ + +.terminal-session-tabs { + display: flex; + flex-shrink: 0; + background: #2d2d2d; + border-bottom: 1px solid #3e3e3e; + overflow: hidden; +} + +.terminal-session-tabs.mobile { + background: #1e1e1e; +} + +.terminal-session-tabs-scroll { + display: flex; + gap: 2px; + padding: var(--space-1) var(--space-2); + overflow-x: auto; + scrollbar-width: thin; + scrollbar-color: #555 transparent; + flex: 1; + min-width: 0; +} + +.terminal-session-tabs-scroll::-webkit-scrollbar { + height: 4px; +} + +.terminal-session-tabs-scroll::-webkit-scrollbar-thumb { + background: #555; + border-radius: 2px; +} + +.terminal-session-tab { + display: flex; + align-items: center; + gap: var(--space-1); + padding: var(--space-1) var(--space-2); + border: 1px solid transparent; + border-radius: 6px; + background: transparent; + color: #888; + cursor: pointer; + font-size: 0.8125rem; + white-space: nowrap; + transition: + background 0.15s, + color 0.15s, + border-color 0.15s; + user-select: none; + min-width: 0; +} + +.terminal-session-tab:hover { + background: #3e3e3e; + color: #ccc; +} + +.terminal-session-tab.active { + background: #1e1e1e; + color: #d4d4d4; + border-color: #3e3e3e; +} + +.terminal-session-tab-status { + width: 6px; + height: 6px; + border-radius: 50%; + flex-shrink: 0; +} + +.terminal-session-tab-status.connecting { + background: #f5f543; + animation: pulse 1.5s infinite; +} + +.terminal-session-tab-status.connected { + background: #0dbc79; +} + +.terminal-session-tab-status.disconnected, +.terminal-session-tab-status.error { + background: #cd3131; +} + +.terminal-session-tab-name { + max-width: 120px; + overflow: hidden; + text-overflow: ellipsis; +} + +.terminal-session-tab-input { + background: #1e1e1e; + border: 1px solid var(--brand); + border-radius: 4px; + color: #d4d4d4; + font-size: 0.8125rem; + padding: 1px 4px; + width: 100px; + outline: none; +} + +.terminal-session-tab-close { + display: flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + padding: 0; + margin: 0; + background: transparent; + border: none; + color: #888; + cursor: pointer; + font-size: 0.875rem; + line-height: 1; + border-radius: 3px; + opacity: 0; + transition: + opacity 0.15s, + background 0.15s; +} + +.terminal-session-tab:hover .terminal-session-tab-close { + opacity: 1; +} + +.terminal-session-tab-close:hover { + background: #cd3131; + color: white; +} + +.terminal-session-tab-confirm { + font-size: 0.6875rem; + color: #cd3131; + padding: 1px 4px; + border-radius: 3px; + background: rgba(205, 49, 49, 0.15); + white-space: nowrap; +} + +.terminal-session-tab.new-session { + font-weight: 600; + font-size: 1rem; + line-height: 1; + padding: var(--space-1) var(--space-2); + color: #888; +} + +.terminal-session-tab.new-session:hover { + background: #3e3e3e; + color: #d4d4d4; +} + +.terminal-session-tab.new-session:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +/* Terminal page with multi-session */ +.terminal-page-content { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + border: 1px solid var(--border); + border-radius: 10px; + overflow: hidden; + background: #1e1e1e; +} + +.terminal-instance { + flex: 1; + min-height: 0; + display: none; +} + +.terminal-instance.active { + display: flex; +} + +.terminal-empty-state { + display: flex; + align-items: center; + justify-content: center; + flex: 1; + color: #888; + font-size: 0.875rem; +} + +.terminal-error-banner { + padding: var(--space-2) var(--space-4); + background: var(--danger-light); + color: var(--danger); + font-size: 0.875rem; + border-bottom: 1px solid var(--danger-light); +} + +/* Fullscreen mode */ +.terminal-page.fullscreen { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + padding: 0; + gap: 0; + background: #1e1e1e; +} + +.terminal-page.fullscreen .terminal-page-content { + border: none; + border-radius: 0; +} + +.terminal-page.fullscreen .terminal-session-tabs { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10; + opacity: 0; + transition: opacity 0.3s; +} + +.terminal-page.fullscreen .terminal-session-tabs:hover { + opacity: 1; +} + +/* Mobile auto-hide header and tabs */ +.terminal-page.mobile .terminal-page-header, +.mobile-tabs-container { + transition: + transform 0.3s ease, + opacity 0.3s ease; +} + +.terminal-page.mobile .terminal-page-header.hidden, +.mobile-tabs-container.hidden { + transform: translateY(-100%); + opacity: 0; + pointer-events: none; +} + +.terminal-page.mobile .terminal-page-header.visible, +.mobile-tabs-container.visible { + transform: translateY(0); + opacity: 1; +} + +/* Mobile fullscreen */ +@media (max-width: 767px) { + .terminal-page.fullscreen { + padding: 0; + } + + .terminal-page.mobile .terminal-page-header { + padding: var(--space-2); + gap: var(--space-2); + } + + .terminal-page.mobile .terminal-page-header h1 { + font-size: 1rem; + } + + .terminal-session-tab-name { + max-width: 80px; + } } /* ============================================ @@ -2668,435 +2950,435 @@ a.nav-item, ============================================ */ .nav-badge { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 18px; - height: 18px; - padding: 0 5px; - background: var(--primary); - color: var(--primary-fg); - border-radius: 9px; - font-size: 11px; - font-weight: 600; - margin-left: auto; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 18px; + height: 18px; + padding: 0 5px; + background: var(--primary); + color: var(--primary-fg); + border-radius: 9px; + font-size: 11px; + font-weight: 600; + margin-left: auto; } .sessions-page { - max-width: 1200px; + max-width: 1200px; } .last-session-section { - margin-bottom: var(--space-6); + margin-bottom: var(--space-6); } .last-session-card { - display: flex; - justify-content: space-between; - align-items: center; - gap: var(--space-4); - padding: var(--space-5); - border: 2px solid var(--primary); + display: flex; + justify-content: space-between; + align-items: center; + gap: var(--space-4); + padding: var(--space-5); + border: 2px solid var(--primary); } .last-session-info h3 { - margin: 0 0 var(--space-1) 0; - font-size: 1.25rem; + margin: 0 0 var(--space-1) 0; + font-size: 1.25rem; } .active-sessions-section { - position: relative; - margin-bottom: var(--space-6); + position: relative; + margin-bottom: var(--space-6); } .active-sessions-section.dimmed { - opacity: 0.5; - pointer-events: none; + opacity: 0.5; + pointer-events: none; } .active-sessions-section h2 { - display: flex; - align-items: center; - gap: var(--space-2); + display: flex; + align-items: center; + gap: var(--space-2); } .active-sessions-section .badge { - display: inline-flex; - align-items: center; - justify-content: center; - min-width: 24px; - height: 24px; - padding: 0 6px; - background: var(--success); - color: white; - border-radius: 12px; - font-size: 12px; - font-weight: 600; + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 24px; + height: 24px; + padding: 0 6px; + background: var(--success); + color: white; + border-radius: 12px; + font-size: 12px; + font-weight: 600; } .sessions-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: var(--space-4); + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: var(--space-4); } .session-card { - display: flex; - flex-direction: column; - gap: var(--space-3); - padding: var(--space-4); + display: flex; + flex-direction: column; + gap: var(--space-3); + padding: var(--space-4); } .session-info h4 { - margin: 0 0 var(--space-1) 0; - font-size: 1rem; + margin: 0 0 var(--space-1) 0; + font-size: 1rem; } .session-url { - margin: var(--space-1) 0; - font-size: 0.8rem; - word-break: break-all; + margin: var(--space-1) 0; + font-size: 0.8rem; + word-break: break-all; } .session-url a { - color: var(--color-primary); - text-decoration: none; + color: var(--color-primary); + text-decoration: none; } .session-url a:hover { - text-decoration: underline; + text-decoration: underline; } .session-actions { - display: flex; - gap: var(--space-2); + display: flex; + gap: var(--space-2); } /* Session Card - Unified Component */ .session-card-content { - flex: 1; + flex: 1; } .session-card-header { - display: flex; - flex-direction: column; - gap: var(--space-2); + display: flex; + flex-direction: column; + gap: var(--space-2); } .session-card-title { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: var(--space-2); + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: var(--space-2); } .session-card-title h4 { - margin: 0; - font-size: 1rem; - font-weight: 600; + margin: 0; + font-size: 1rem; + font-weight: 600; } .session-card-status-badges { - display: flex; - gap: var(--space-1); - flex-wrap: wrap; + display: flex; + gap: var(--space-1); + flex-wrap: wrap; } .session-card-meta { - font-size: 0.85rem; - margin: 0; + font-size: 0.85rem; + margin: 0; } .session-card-meta .icon { - margin-right: var(--space-1); - vertical-align: text-bottom; + margin-right: var(--space-1); + vertical-align: text-bottom; } .session-card-url { - margin: var(--space-1) 0; - font-size: 0.8rem; - word-break: break-all; + margin: var(--space-1) 0; + font-size: 0.8rem; + word-break: break-all; } .session-card-url a { - color: var(--color-primary); - text-decoration: none; + color: var(--color-primary); + text-decoration: none; } .session-card-url a:hover { - text-decoration: underline; + text-decoration: underline; } .session-card-actions { - display: flex; - gap: var(--space-2); - flex-wrap: wrap; - margin-top: var(--space-2); - padding-top: var(--space-3); - border-top: 1px solid var(--color-border); + display: flex; + gap: var(--space-2); + flex-wrap: wrap; + margin-top: var(--space-2); + padding-top: var(--space-3); + border-top: 1px solid var(--color-border); } /* Session List - Unified Component */ .session-list { - display: flex; - flex-direction: column; - gap: var(--space-6); + display: flex; + flex-direction: column; + gap: var(--space-6); } .session-group { - display: flex; - flex-direction: column; - gap: var(--space-3); + display: flex; + flex-direction: column; + gap: var(--space-3); } .session-group-header { - display: flex; - align-items: center; - gap: var(--space-2); + display: flex; + align-items: center; + gap: var(--space-2); } .session-group-header h3 { - margin: 0; - font-size: 1.1rem; - font-weight: 600; + margin: 0; + font-size: 1.1rem; + font-weight: 600; } /* Action labels - hidden on mobile */ .action-label { - margin-left: var(--space-1); + margin-left: var(--space-1); } @media (max-width: 640px) { - .action-label { - display: none; - } + .action-label { + display: none; + } - .session-card-actions { - gap: var(--space-1); - } + .session-card-actions { + gap: var(--space-1); + } - .session-card-actions button, - .session-card-actions a { - padding: var(--space-1); - } + .session-card-actions button, + .session-card-actions a { + padding: var(--space-1); + } } .recent-sessions-section { - margin-bottom: var(--space-6); + margin-bottom: var(--space-6); } /* Loading overlay for sessions */ .sessions-grid { - position: relative; + position: relative; } .sessions-grid.dimmed { - opacity: 0.5; - pointer-events: none; + opacity: 0.5; + pointer-events: none; } .create-session-form-wrapper { - position: relative; + position: relative; } .loading-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; - z-index: 10; - background: rgba(255, 254, 249, 0.7); - border-radius: var(--space-2); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + background: rgba(255, 254, 249, 0.7); + border-radius: var(--space-2); } .loading-content { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--space-3); - padding: var(--space-6); - background: var(--panel); - border: 1px solid var(--border); - border-radius: var(--space-2); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-3); + padding: var(--space-6); + background: var(--panel); + border: 1px solid var(--border); + border-radius: var(--space-2); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .loading-content .icon { - animation: spin 1s linear infinite; - color: var(--brand); + animation: spin 1s linear infinite; + color: var(--brand); } .loading-content p { - margin: 0; - font-size: var(--font-size-base); - color: var(--muted); + margin: 0; + font-size: var(--font-size-base); + color: var(--muted); } @keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } .recent-sessions-list { - display: flex; - flex-direction: column; - gap: var(--space-2); + display: flex; + flex-direction: column; + gap: var(--space-2); } .recent-session-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: var(--space-3) var(--space-4); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 8px; + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-3) var(--space-4); + background: var(--bg); + border: 1px solid var(--border); + border-radius: 8px; } .recent-session-info { - display: flex; - flex-direction: column; - gap: var(--space-1); + display: flex; + flex-direction: column; + gap: var(--space-1); } .recent-session-name { - font-weight: 500; + font-weight: 500; } .recent-session-actions { - display: flex; - gap: var(--space-2); - align-items: center; + display: flex; + gap: var(--space-2); + align-items: center; } .delete-confirm-inline, .stop-confirm-inline { - display: flex; - gap: var(--space-2); - align-items: center; + display: flex; + gap: var(--space-2); + align-items: center; } .confirm-text { - font-size: 13px; - color: var(--muted); - font-weight: 500; + font-size: 13px; + color: var(--muted); + font-weight: 500; } .create-session-section { - position: relative; - margin-bottom: var(--space-6); + position: relative; + margin-bottom: var(--space-6); } .create-session-section.dimmed { - opacity: 0.5; - pointer-events: none; + opacity: 0.5; + pointer-events: none; } .create-session-form { - max-width: 600px; + max-width: 600px; } .create-session-form .form-row { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: var(--space-4); + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: var(--space-4); } /* Workflow Step Styles */ .workflow-form { - display: flex; - flex-direction: column; - gap: var(--space-6); + display: flex; + flex-direction: column; + gap: var(--space-6); } .workflow-step { - opacity: 0.4; - pointer-events: none; - transition: opacity 0.2s ease; + opacity: 0.4; + pointer-events: none; + transition: opacity 0.2s ease; } .workflow-step.active { - opacity: 1; - pointer-events: auto; + opacity: 1; + pointer-events: auto; } .workflow-step.complete { - opacity: 0.7; - pointer-events: auto; + opacity: 0.7; + pointer-events: auto; } .workflow-step-header { - display: flex; - align-items: center; - gap: var(--space-3); - margin-bottom: var(--space-3); - font-weight: 600; - color: var(--text-muted); + display: flex; + align-items: center; + gap: var(--space-3); + margin-bottom: var(--space-3); + font-weight: 600; + color: var(--text-muted); } .workflow-step.active .workflow-step-header { - color: var(--text-primary); + color: var(--text-primary); } .workflow-step-number { - display: flex; - align-items: center; - justify-content: center; - width: 28px; - height: 28px; - border-radius: 50%; - background: var(--bg-muted); - color: var(--text-muted); - font-size: 14px; - font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + background: var(--bg-muted); + color: var(--text-muted); + font-size: 14px; + font-weight: 600; } .workflow-step.active .workflow-step-number { - background: var(--primary); - color: white; + background: var(--primary); + color: white; } .workflow-step.complete .workflow-step-number { - background: var(--success); - color: white; + background: var(--success); + color: white; } .status-badge { - display: inline-flex; - align-items: center; - padding: 2px 8px; - border-radius: 4px; - font-size: 12px; - font-weight: 500; - text-transform: capitalize; + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + text-transform: capitalize; } .status-badge.running { - background: var(--success-light, #dcfce7); - color: var(--success, #16a34a); + background: var(--success-light, #dcfce7); + color: var(--success, #16a34a); } .status-badge.stopped { - background: var(--muted-bg, #f3f4f6); - color: var(--muted, #6b7280); + background: var(--muted-bg, #f3f4f6); + color: var(--muted, #6b7280); } .status-badge.pending { - background: var(--warning-light, #fef3c7); - color: var(--warning, #d97706); + background: var(--warning-light, #fef3c7); + color: var(--warning, #d97706); } .status-badge.error { - background: var(--danger-light, #fee2e2); - color: var(--danger, #dc2626); + background: var(--danger-light, #fee2e2); + color: var(--danger, #dc2626); } /* ============================================ @@ -3105,154 +3387,159 @@ a.nav-item, /* Mobile terminal shell - fills viewport */ .shell.mobile-terminal-shell { - height: 100vh; - height: 100dvh; - overflow: hidden; - display: flex; - flex-direction: column; + height: 100vh; + height: 100dvh; + overflow: hidden; + display: flex; + flex-direction: column; } .mobile-terminal-wrapper { - display: flex; - flex-direction: column; - height: 100%; - min-height: 0; - background: #1e1e1e; - position: relative; - overflow: hidden; + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + background: #1e1e1e; + position: relative; + overflow: hidden; } /* Mobile Terminal Header */ .mobile-terminal-header { - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--space-2) var(--space-3); - background: #2d2d2d; - border-bottom: 1px solid #3e3e3e; - transition: transform 0.3s ease, opacity 0.3s ease, height 0.3s ease, padding 0.3s ease, margin 0.3s ease; - z-index: 100; - overflow: hidden; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--space-2) var(--space-3); + background: #2d2d2d; + border-bottom: 1px solid #3e3e3e; + transition: + transform 0.3s ease, + opacity 0.3s ease, + height 0.3s ease, + padding 0.3s ease, + margin 0.3s ease; + z-index: 100; + overflow: hidden; } .mobile-terminal-header.hidden { - transform: translateY(-100%); - opacity: 0; - pointer-events: none; - height: 0; - padding-top: 0; - padding-bottom: 0; - margin-top: 0; - margin-bottom: 0; - border-width: 0; - flex-shrink: 1; + transform: translateY(-100%); + opacity: 0; + pointer-events: none; + height: 0; + padding-top: 0; + padding-bottom: 0; + margin-top: 0; + margin-bottom: 0; + border-width: 0; + flex-shrink: 1; } .mobile-terminal-header.visible { - transform: translateY(0); - opacity: 1; - height: auto; + transform: translateY(0); + opacity: 1; + height: auto; } .mobile-terminal-header-left, .mobile-terminal-header-right { - display: flex; - align-items: center; - gap: var(--space-2); - flex: 0 0 auto; + display: flex; + align-items: center; + gap: var(--space-2); + flex: 0 0 auto; } .mobile-terminal-header-center { - display: flex; - align-items: center; - gap: var(--space-2); - flex: 1; - justify-content: center; - min-width: 0; + display: flex; + align-items: center; + gap: var(--space-2); + flex: 1; + justify-content: center; + min-width: 0; } .mobile-terminal-header-title { - font-size: 0.875rem; - font-weight: 500; - color: #d4d4d4; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + font-size: 0.875rem; + font-weight: 500; + color: #d4d4d4; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .mobile-terminal-header-button { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - padding: 0; - background: transparent; - border: 1px solid #3e3e3e; - border-radius: 6px; - color: #d4d4d4; - cursor: pointer; - font-size: 0.875rem; - transition: background 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + padding: 0; + background: transparent; + border: 1px solid #3e3e3e; + border-radius: 6px; + color: #d4d4d4; + cursor: pointer; + font-size: 0.875rem; + transition: background 0.2s ease; } .mobile-terminal-header-button:hover { - background: #3e3e3e; + background: #3e3e3e; } .mobile-terminal-header-status { - width: 8px; - height: 8px; - border-radius: 50%; - background: #666; - flex-shrink: 0; + width: 8px; + height: 8px; + border-radius: 50%; + background: #666; + flex-shrink: 0; } .mobile-terminal-header-status.connecting { - background: #f5f543; - animation: pulse 1.5s infinite; + background: #f5f543; + animation: pulse 1.5s infinite; } .mobile-terminal-header-status.connected { - background: #0dbc79; + background: #0dbc79; } .mobile-terminal-header-status.disconnected, .mobile-terminal-header-status.error { - background: #cd3131; + background: #cd3131; } /* Mobile Terminal Content */ .mobile-terminal-content { - flex: 1; - min-height: 0; - overflow: hidden; - position: relative; - background: #1e1e1e; - display: flex; - flex-direction: column; + flex: 1; + min-height: 0; + overflow: hidden; + position: relative; + background: #1e1e1e; + display: flex; + flex-direction: column; } /* Terminal wrapper - fills content area */ .terminal-wrapper.mobile { - border: none; - border-radius: 0; - flex: 1; - min-height: 0; - width: 100%; - overflow: hidden; - display: flex; - flex-direction: column; + border: none; + border-radius: 0; + flex: 1; + min-height: 0; + width: 100%; + overflow: hidden; + display: flex; + flex-direction: column; } .terminal-wrapper.mobile .terminal-container { - width: 100%; - flex: 1; - min-height: 0; - padding: 0; - overflow: hidden; - position: relative; + width: 100%; + flex: 1; + min-height: 0; + padding: 0; + overflow: hidden; + position: relative; } /* xterm.js manages its own sizing */ @@ -3261,898 +3548,907 @@ a.nav-item, /* Special Keys Strip */ .special-keys-strip { - flex-shrink: 0; - display: flex; - align-items: center; - gap: 2px; - padding: var(--space-1) var(--space-2); - background: #2d2d2d; - border-top: 1px solid #3e3e3e; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; - transition: transform 0.3s ease, opacity 0.3s ease; - z-index: 100; + flex-shrink: 0; + display: flex; + align-items: center; + gap: 2px; + padding: var(--space-1) var(--space-2); + background: #2d2d2d; + border-top: 1px solid #3e3e3e; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + transition: + transform 0.3s ease, + opacity 0.3s ease; + z-index: 100; } .special-keys-strip.hidden { - transform: translateY(100%); - opacity: 0; - pointer-events: none; + transform: translateY(100%); + opacity: 0; + pointer-events: none; } .special-keys-strip.visible { - transform: translateY(0); - opacity: 1; + transform: translateY(0); + opacity: 1; } .special-keys-strip::-webkit-scrollbar { - display: none; + display: none; } .special-key-button { - display: flex; - align-items: center; - justify-content: center; - min-width: 44px; - height: 44px; - padding: 0 var(--space-2); - background: #3e3e3e; - border: 1px solid #4e4e4e; - border-radius: 6px; - color: #d4d4d4; - font-size: 0.75rem; - font-weight: 500; - cursor: pointer; - white-space: nowrap; - flex-shrink: 0; - transition: background 0.15s ease, transform 0.1s ease; - user-select: none; - -webkit-user-select: none; - touch-action: manipulation; + display: flex; + align-items: center; + justify-content: center; + min-width: 44px; + height: 44px; + padding: 0 var(--space-2); + background: #3e3e3e; + border: 1px solid #4e4e4e; + border-radius: 6px; + color: #d4d4d4; + font-size: 0.75rem; + font-weight: 500; + cursor: pointer; + white-space: nowrap; + flex-shrink: 0; + transition: + background 0.15s ease, + transform 0.1s ease; + user-select: none; + -webkit-user-select: none; + touch-action: manipulation; } .special-key-button:active { - background: #4e4e4e; - transform: scale(0.95); + background: #4e4e4e; + transform: scale(0.95); } .special-key-more { - background: #2472c8; - border-color: #2472c8; - color: white; + background: #2472c8; + border-color: #2472c8; + color: white; } .special-key-more:active { - background: #1e5fa8; + background: #1e5fa8; } .special-key-button.active-modifier { - background: #f5f543; - color: #1e1e1e; - border-color: #f5f543; - font-weight: 700; - box-shadow: 0 0 8px rgba(245, 245, 67, 0.5); + background: #f5f543; + color: #1e1e1e; + border-color: #f5f543; + font-weight: 700; + box-shadow: 0 0 8px rgba(245, 245, 67, 0.5); } /* Special Keys Panel */ .special-keys-panel-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 200; - display: flex; - align-items: flex-end; - justify-content: center; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 200; + display: flex; + align-items: flex-end; + justify-content: center; } .special-keys-panel { - background: #2d2d2d; - border-top: 1px solid #3e3e3e; - border-radius: 12px 12px 0 0; - padding: var(--space-4); - width: 100%; - max-height: 70vh; - overflow-y: auto; - animation: slideUp 0.2s ease; + background: #2d2d2d; + border-top: 1px solid #3e3e3e; + border-radius: 12px 12px 0 0; + padding: var(--space-4); + width: 100%; + max-height: 70vh; + overflow-y: auto; + animation: slideUp 0.2s ease; } .special-keys-panel-section { - display: flex; - flex-wrap: wrap; - gap: var(--space-2); - margin-bottom: var(--space-3); + display: flex; + flex-wrap: wrap; + gap: var(--space-2); + margin-bottom: var(--space-3); } .special-keys-panel-section:last-child { - margin-bottom: 0; + margin-bottom: 0; } .special-keys-panel-divider { - height: 1px; - background: #3e3e3e; - margin: var(--space-3) 0; + height: 1px; + background: #3e3e3e; + margin: var(--space-3) 0; } /* Terminal Component Updates */ /* Note: .terminal-wrapper.mobile is defined above with position: absolute to fill grid cell */ .terminal-wrapper.mobile .terminal-header { - display: none; + display: none; } .terminal-header-left { - display: flex; - align-items: center; - gap: var(--space-2); + display: flex; + align-items: center; + gap: var(--space-2); } .terminal-header-right { - display: flex; - align-items: center; - gap: var(--space-2); + display: flex; + align-items: center; + gap: var(--space-2); } .terminal-header-button { - padding: var(--space-1) var(--space-2); - background: transparent; - border: 1px solid #666; - border-radius: 4px; - color: #d4d4d4; - cursor: pointer; - font-size: 0.75rem; - transition: background 0.2s ease; + padding: var(--space-1) var(--space-2); + background: transparent; + border: 1px solid #666; + border-radius: 4px; + color: #d4d4d4; + cursor: pointer; + font-size: 0.75rem; + transition: background 0.2s ease; } .terminal-header-button:hover { - background: #3e3e3e; + background: #3e3e3e; } .terminal-reconnect { - margin-left: var(--space-2); - padding: var(--space-1) var(--space-2); - background: #2472c8; - border: none; - border-radius: 4px; - color: white; - cursor: pointer; - font-size: 0.75rem; + margin-left: var(--space-2); + padding: var(--space-1) var(--space-2); + background: #2472c8; + border: none; + border-radius: 4px; + color: white; + cursor: pointer; + font-size: 0.75rem; } .terminal-reset-confirm { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.8); - display: flex; - align-items: center; - justify-content: center; - z-index: 100; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.8); + display: flex; + align-items: center; + justify-content: center; + z-index: 100; } .terminal-reset-confirm-content { - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: 8px; - padding: var(--space-4); - max-width: 400px; - text-align: center; + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: 8px; + padding: var(--space-4); + max-width: 400px; + text-align: center; } .terminal-reset-confirm-content p { - margin: 0 0 var(--space-4) 0; - color: var(--text-primary); + margin: 0 0 var(--space-4) 0; + color: var(--text-primary); } .terminal-reset-confirm-buttons { - display: flex; - gap: var(--space-2); - justify-content: center; + display: flex; + gap: var(--space-2); + justify-content: center; } .terminal-reset-confirm-button { - padding: var(--space-2) var(--space-4); - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 0.875rem; + padding: var(--space-2) var(--space-4); + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 0.875rem; } .terminal-reset-confirm-button.cancel { - background: var(--bg-elevated); - color: var(--text-primary); + background: var(--bg-elevated); + color: var(--text-primary); } .terminal-reset-confirm-button.confirm { - background: #cd3131; - color: white; + background: #cd3131; + color: white; } .terminal-hidden-input { - position: fixed; - left: -9999px; - top: -9999px; - width: 1px; - height: 1px; - opacity: 0; - pointer-events: none; - user-select: none; - -webkit-user-select: none; + position: fixed; + left: -9999px; + top: -9999px; + width: 1px; + height: 1px; + opacity: 0; + pointer-events: none; + user-select: none; + -webkit-user-select: none; } /* Disable zoom on mobile terminal */ @media (max-width: 767px) { - .mobile-terminal-wrapper { - touch-action: pan-y; - -webkit-text-size-adjust: none; - } + .mobile-terminal-wrapper { + touch-action: pan-y; + -webkit-text-size-adjust: none; + } - .mobile-terminal-wrapper button, - .mobile-terminal-wrapper .special-key-button { - touch-action: manipulation; - } + .mobile-terminal-wrapper button, + .mobile-terminal-wrapper .special-key-button { + touch-action: manipulation; + } - .terminal-container { - touch-action: pan-y; - padding: 0; - } + .terminal-container { + touch-action: pan-y; + padding: 0; + } } /* Animations */ @keyframes slideUp { - from { - transform: translateY(100%); - } - to { - transform: translateY(0); - } + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } } @keyframes pulse { - 0%, 100% { - opacity: 1; - } - 50% { - opacity: 0.5; - } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } /* Mobile Menu Overlay */ .mobile-menu-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 50; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 50; } .mobile-menu-close { - position: absolute; - top: var(--space-2); - right: var(--space-2); - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - background: transparent; - border: none; - color: var(--text); - cursor: pointer; + position: absolute; + top: var(--space-2); + right: var(--space-2); + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + background: transparent; + border: none; + color: var(--text); + cursor: pointer; } /* AppShell mobile menu */ @media (max-width: 767px) { - .shell-nav { - position: fixed; - top: 0; - left: 0; - bottom: 0; - width: 260px; - background: var(--bg); - z-index: 100; - transform: translateX(-100%); - transition: transform 0.3s ease; - padding-top: var(--space-8); - } + .shell-nav { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: 260px; + background: var(--bg); + z-index: 100; + transform: translateX(-100%); + transition: transform 0.3s ease; + padding-top: var(--space-8); + } - .shell-nav.mobile-open { - transform: translateX(0); - } + .shell-nav.mobile-open { + transform: translateX(0); + } } /* Mobile Navigation */ .mobile-nav { - position: fixed; - bottom: 0; - left: 0; - right: 0; - display: flex; - justify-content: space-around; - align-items: center; - background: var(--panel); - border-top: 1px solid var(--border); - padding-bottom: env(safe-area-inset-bottom, 0); - z-index: 100; - height: 64px; + position: fixed; + bottom: 0; + left: 0; + right: 0; + display: flex; + justify-content: space-around; + align-items: center; + background: var(--panel); + border-top: 1px solid var(--border); + padding-bottom: env(safe-area-inset-bottom, 0); + z-index: 100; + height: 64px; } .mobile-nav-item { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 2px; - padding: 8px 12px; - color: var(--muted); - text-decoration: none; - font-size: 11px; - min-width: 64px; - min-height: 44px; - border-radius: 8px; - transition: color 0.15s ease; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2px; + padding: 8px 12px; + color: var(--muted); + text-decoration: none; + font-size: 11px; + min-width: 64px; + min-height: 44px; + border-radius: 8px; + transition: color 0.15s ease; } .mobile-nav-item.active { - color: var(--brand); + color: var(--brand); } .mobile-nav-icon-wrapper { - position: relative; - display: flex; - align-items: center; - justify-content: center; + position: relative; + display: flex; + align-items: center; + justify-content: center; } .mobile-nav-badge { - position: absolute; - top: -6px; - right: -8px; - background: var(--danger); - color: white; - font-size: 10px; - font-weight: 600; - min-width: 16px; - height: 16px; - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; - padding: 0 4px; + position: absolute; + top: -6px; + right: -8px; + background: var(--danger); + color: white; + font-size: 10px; + font-weight: 600; + min-width: 16px; + height: 16px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + padding: 0 4px; } /* Mobile Bottom Sheet */ .mobile-bottom-sheet-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 200; - display: flex; - align-items: flex-end; - justify-content: center; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 200; + display: flex; + align-items: flex-end; + justify-content: center; } .mobile-bottom-sheet { - background: var(--panel); - border-radius: 16px 16px 0 0; - width: 100%; - max-width: 600px; - max-height: 70vh; - display: flex; - flex-direction: column; - animation: slide-up 0.2s ease-out; + background: var(--panel); + border-radius: 16px 16px 0 0; + width: 100%; + max-width: 600px; + max-height: 70vh; + display: flex; + flex-direction: column; + animation: slide-up 0.2s ease-out; } @keyframes slide-up { - from { - transform: translateY(100%); - } - to { - transform: translateY(0); - } + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } } .mobile-bottom-sheet-header { - display: flex; - flex-direction: column; - align-items: center; - padding: 12px 16px 8px; - border-bottom: 1px solid var(--border); + display: flex; + flex-direction: column; + align-items: center; + padding: 12px 16px 8px; + border-bottom: 1px solid var(--border); } .mobile-bottom-sheet-handle { - width: 36px; - height: 4px; - background: var(--border); - border-radius: 2px; - margin-bottom: 8px; + width: 36px; + height: 4px; + background: var(--border); + border-radius: 2px; + margin-bottom: 8px; } .mobile-bottom-sheet-title { - font-size: 16px; - font-weight: 600; - margin: 0; + font-size: 16px; + font-weight: 600; + margin: 0; } .mobile-bottom-sheet-content { - padding: 8px 0; - overflow-y: auto; + padding: 8px 0; + overflow-y: auto; } .mobile-bottom-sheet-item { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - padding: 16px; - background: none; - border: none; - color: var(--text); - font-size: 16px; - text-align: left; - cursor: pointer; - min-height: 44px; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 16px; + background: none; + border: none; + color: var(--text); + font-size: 16px; + text-align: left; + cursor: pointer; + min-height: 44px; } .mobile-bottom-sheet-item:active { - background: var(--hover); + background: var(--hover); } .mobile-bottom-sheet-item.active { - color: var(--brand); + color: var(--brand); } /* Mobile Page Header */ .mobile-page-header { - display: flex; - align-items: center; - gap: var(--space-2); - padding: var(--space-2) 0; - margin-bottom: var(--space-3); - border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + gap: var(--space-2); + padding: var(--space-2) 0; + margin-bottom: var(--space-3); + border-bottom: 1px solid var(--border); } .mobile-page-header-back { - display: flex; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - background: transparent; - border: none; - color: var(--text); - cursor: pointer; - border-radius: 8px; - padding: 0; + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + background: transparent; + border: none; + color: var(--text); + cursor: pointer; + border-radius: 8px; + padding: 0; } .mobile-page-header-back:active { - background: var(--color-border); + background: var(--color-border); } .mobile-page-header h1 { - margin: 0; - font-size: 1.1rem; - font-weight: 600; - flex: 1; + margin: 0; + font-size: 1.1rem; + font-weight: 600; + flex: 1; } .mobile-page-header-actions { - display: flex; - gap: var(--space-2); + display: flex; + gap: var(--space-2); } .mobile-nav-label { - font-size: 11px; - font-weight: 500; + font-size: 11px; + font-weight: 500; } /* Mobile shell content padding adjustment */ .shell-content.mobile { - padding-bottom: calc(1.25rem + 64px); + padding-bottom: calc(1.25rem + 64px); } - - /* Ensure minimum touch targets on mobile */ - button, - a, - input, - select, - textarea, - [role="button"] { - min-height: 44px; - min-width: 44px; - } - - /* Active states for touch feedback */ - button:active, - a:active, - [role="button"]:active { - opacity: 0.8; - transform: scale(0.98); - } - - /* Remove transform on buttons that shouldn't scale */ - .mobile-nav-item:active, - .mobile-action-sheet-button:active, - .mobile-action-sheet-cancel:active { - transform: none; - } -@media (max-width: 767px) { - .dialog-actions { - flex-direction: column-reverse; - gap: 0.5rem; - } - - .dialog-actions button { - width: 100%; - min-height: 44px; - } +/* Ensure minimum touch targets on mobile */ +button, +a, +input, +select, +textarea, +[role="button"] { + min-height: 44px; + min-width: 44px; } +/* Active states for touch feedback */ +button:active, +a:active, +[role="button"]:active { + opacity: 0.8; + transform: scale(0.98); +} - .workspace-main { - padding: var(--space-2); - } - - .tree-entry { - padding: 0.5rem; - min-height: 44px; - display: flex; - align-items: center; - } +/* Remove transform on buttons that shouldn't scale */ +.mobile-nav-item:active, +.mobile-action-sheet-button:active, +.mobile-action-sheet-cancel:active { + transform: none; +} @media (max-width: 767px) { - .modal-content { - min-width: auto; - width: calc(100% - 2rem); - max-width: 100%; - margin: 1rem; - padding: 1rem; - max-height: calc(100vh - 2rem); - } + .dialog-actions { + flex-direction: column-reverse; + gap: 0.5rem; + } - .modal-actions { - flex-direction: column-reverse; - gap: 0.5rem; - } + .dialog-actions button { + width: 100%; + min-height: 44px; + } +} - .modal-actions button { - width: 100%; - min-height: 44px; - } +.workspace-main { + padding: var(--space-2); +} + +.tree-entry { + padding: 0.5rem; + min-height: 44px; + display: flex; + align-items: center; +} +@media (max-width: 767px) { + .modal-content { + min-width: auto; + width: calc(100% - 2rem); + max-width: 100%; + margin: 1rem; + padding: 1rem; + max-height: calc(100vh - 2rem); + } + + .modal-actions { + flex-direction: column-reverse; + gap: 0.5rem; + } + + .modal-actions button { + width: 100%; + min-height: 44px; + } } /* Mobile Sessions Page */ @media (max-width: 767px) { - .sessions-page { - padding: var(--space-2); - } + .sessions-page { + padding: var(--space-2); + } - .sessions-page .page-header { - margin-bottom: var(--space-3); - } + .sessions-page .page-header { + margin-bottom: var(--space-3); + } - .sessions-page .page-header h1 { - font-size: 1.25rem; - } + .sessions-page .page-header h1 { + font-size: 1.25rem; + } - .last-session-section { - margin-bottom: var(--space-4); - } + .last-session-section { + margin-bottom: var(--space-4); + } - .last-session-section h2 { - font-size: 1rem; - margin-bottom: var(--space-2); - } + .last-session-section h2 { + font-size: 1rem; + margin-bottom: var(--space-2); + } - .create-session-section { - padding: var(--space-3); - } + .create-session-section { + padding: var(--space-3); + } - .create-session-section h2 { - font-size: 1rem; - margin-bottom: var(--space-2); - } + .create-session-section h2 { + font-size: 1rem; + margin-bottom: var(--space-2); + } } +.session-card-actions.mobile { + display: flex; + gap: var(--space-2); + padding-top: var(--space-3); + border-top: 1px solid var(--color-border); +} - .session-card-actions.mobile { - display: flex; - gap: var(--space-2); - padding-top: var(--space-3); - border-top: 1px solid var(--color-border); - } +.session-card-actions.mobile .mobile-primary { + flex: 1; + justify-content: center; + min-height: 44px; + padding: var(--space-2) var(--space-3); +} - .session-card-actions.mobile .mobile-primary { - flex: 1; - justify-content: center; - min-height: 44px; - padding: var(--space-2) var(--space-3); - } - - .session-card-actions.mobile .mobile-more { - min-width: 44px; - min-height: 44px; - display: flex; - align-items: center; - justify-content: center; - padding: var(--space-2); - } +.session-card-actions.mobile .mobile-more { + min-width: 44px; + min-height: 44px; + display: flex; + align-items: center; + justify-content: center; + padding: var(--space-2); +} @media (max-width: 767px) { - .create-session-form .form-row { - grid-template-columns: 1fr; - gap: var(--space-3); - } + .create-session-form .form-row { + grid-template-columns: 1fr; + gap: var(--space-3); + } - .create-session-form input, - .create-session-form select, - .create-session-form textarea, - .create-session-form button { - min-height: 44px; - } + .create-session-form input, + .create-session-form select, + .create-session-form textarea, + .create-session-form button { + min-height: 44px; + } } /* Mobile Action Sheet */ .mobile-action-sheet-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 200; - display: flex; - align-items: flex-end; - justify-content: center; - animation: fadeIn 0.2s ease; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 200; + display: flex; + align-items: flex-end; + justify-content: center; + animation: fadeIn 0.2s ease; } .mobile-action-sheet { - background: var(--bg); - border-radius: 16px 16px 0 0; - width: 100%; - max-width: 500px; - max-height: 80vh; - overflow-y: auto; - animation: slideUp 0.3s ease; - padding-bottom: env(safe-area-inset-bottom, 0); + background: var(--bg); + border-radius: 16px 16px 0 0; + width: 100%; + max-width: 500px; + max-height: 80vh; + overflow-y: auto; + animation: slideUp 0.3s ease; + padding-bottom: env(safe-area-inset-bottom, 0); } .mobile-action-sheet-header { - padding: var(--space-3) var(--space-4) var(--space-2); - text-align: center; + padding: var(--space-3) var(--space-4) var(--space-2); + text-align: center; } .mobile-action-sheet-handle { - width: 36px; - height: 4px; - background: var(--color-border); - border-radius: 2px; - margin: 0 auto var(--space-3); + width: 36px; + height: 4px; + background: var(--color-border); + border-radius: 2px; + margin: 0 auto var(--space-3); } .mobile-action-sheet-header h3 { - margin: 0; - font-size: 1rem; - font-weight: 600; + margin: 0; + font-size: 1rem; + font-weight: 600; } .mobile-action-sheet-actions { - display: flex; - flex-direction: column; - gap: 1px; - background: var(--color-border); - margin: 0 var(--space-2); - border-radius: 12px; - overflow: hidden; + display: flex; + flex-direction: column; + gap: 1px; + background: var(--color-border); + margin: 0 var(--space-2); + border-radius: 12px; + overflow: hidden; } .mobile-action-sheet-button { - display: flex; - align-items: center; - gap: var(--space-3); - width: 100%; - padding: var(--space-3) var(--space-4); - background: var(--bg); - border: none; - color: var(--text); - font-size: 1rem; - cursor: pointer; - min-height: 56px; - text-align: left; + display: flex; + align-items: center; + gap: var(--space-3); + width: 100%; + padding: var(--space-3) var(--space-4); + background: var(--bg); + border: none; + color: var(--text); + font-size: 1rem; + cursor: pointer; + min-height: 56px; + text-align: left; } .mobile-action-sheet-button.danger { - color: #cd3131; + color: #cd3131; } .mobile-action-sheet-button:active { - background: var(--color-border); + background: var(--color-border); } .mobile-action-sheet-cancel { - display: block; - width: calc(100% - var(--space-4)); - margin: var(--space-3) var(--space-2); - padding: var(--space-3); - background: var(--bg); - border: 1px solid var(--color-border); - border-radius: 12px; - color: var(--text); - font-size: 1rem; - font-weight: 600; - cursor: pointer; - min-height: 56px; + display: block; + width: calc(100% - var(--space-4)); + margin: var(--space-3) var(--space-2); + padding: var(--space-3); + background: var(--bg); + border: 1px solid var(--color-border); + border-radius: 12px; + color: var(--text); + font-size: 1rem; + font-weight: 600; + cursor: pointer; + min-height: 56px; } .mobile-action-sheet-cancel:active { - background: var(--color-border); + background: var(--color-border); } @keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes slideUp { - from { transform: translateY(100%); } - to { transform: translateY(0); } + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } } /* Git Mount Editor Styles */ .git-mount-editor { - margin-top: 1rem; + margin-top: 1rem; } .git-mount-editor .section-subtitle { - margin: 0 0 0.75rem 0; - font-size: 1rem; - font-weight: 600; + margin: 0 0 0.75rem 0; + font-size: 1rem; + font-weight: 600; } .git-mount-list { - display: flex; - flex-direction: column; - gap: 0.5rem; - margin-bottom: 1rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-bottom: 1rem; } .git-mount-item { - background: var(--surface); - border: 1px solid var(--border); - border-radius: 0.5rem; - padding: 0.75rem; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 0.5rem; + padding: 0.75rem; } .git-mount-display { - display: flex; - justify-content: space-between; - align-items: center; - gap: 0.5rem; + display: flex; + justify-content: space-between; + align-items: center; + gap: 0.5rem; } .git-mount-info { - display: flex; - flex-direction: column; - gap: 0.25rem; + display: flex; + flex-direction: column; + gap: 0.25rem; } .git-mount-repo { - font-weight: 600; - color: var(--text); + font-weight: 600; + color: var(--text); } .git-mount-paths { - font-size: 0.875rem; - color: var(--text-muted); - font-family: monospace; + font-size: 0.875rem; + color: var(--text-muted); + font-family: monospace; } .git-mount-branch { - font-size: 0.75rem; - color: var(--accent); - background: var(--accent-bg); - padding: 0.125rem 0.375rem; - border-radius: 0.25rem; - width: fit-content; + font-size: 0.75rem; + color: var(--accent); + background: var(--accent-bg); + padding: 0.125rem 0.375rem; + border-radius: 0.25rem; + width: fit-content; } .git-mount-actions { - display: flex; - gap: 0.25rem; + display: flex; + gap: 0.25rem; } .git-mount-add { - border-top: 1px solid var(--border); - padding-top: 1rem; - margin-top: 1rem; + border-top: 1px solid var(--border); + padding-top: 1rem; + margin-top: 1rem; } .git-mount-add h5 { - margin: 0 0 0.75rem 0; - font-size: 0.875rem; - font-weight: 600; - color: var(--text-muted); + margin: 0 0 0.75rem 0; + font-size: 0.875rem; + font-weight: 600; + color: var(--text-muted); } .git-mount-form { - display: flex; - flex-direction: column; - gap: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.75rem; } .git-mount-form .form-row { - display: flex; - flex-direction: column; - gap: 0.25rem; + display: flex; + flex-direction: column; + gap: 0.25rem; } .git-mount-form .form-row label { - font-size: 0.875rem; - font-weight: 500; - color: var(--text); + font-size: 0.875rem; + font-weight: 500; + color: var(--text); } .git-mount-form .form-row input, .git-mount-form .form-row select { - padding: 0.5rem; - border: 1px solid var(--border); - border-radius: 0.375rem; - background: var(--bg); - color: var(--text); - font-size: 0.875rem; + padding: 0.5rem; + border: 1px solid var(--border); + border-radius: 0.375rem; + background: var(--bg); + color: var(--text); + font-size: 0.875rem; } .git-mount-form .form-row input.error, .git-mount-form .form-row select.error { - border-color: #cd3131; + border-color: #cd3131; } .git-mount-form .form-row .hint { - font-size: 0.75rem; - color: var(--text-muted); + font-size: 0.75rem; + color: var(--text-muted); } .git-mount-form .form-row .error-text { - font-size: 0.75rem; - color: #cd3131; + font-size: 0.75rem; + color: #cd3131; } .git-mount-form .form-actions { - display: flex; - gap: 0.5rem; - margin-top: 0.5rem; + display: flex; + gap: 0.5rem; + margin-top: 0.5rem; } .new-repo-form { - display: flex; - flex-direction: column; - gap: 0.5rem; - padding: 0.75rem; - background: var(--bg); - border: 1px solid var(--border); - border-radius: 0.375rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + padding: 0.75rem; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 0.375rem; } .new-repo-form input { - padding: 0.5rem; - border: 1px solid var(--border); - border-radius: 0.375rem; - background: var(--surface); - color: var(--text); - font-size: 0.875rem; + padding: 0.5rem; + border: 1px solid var(--border); + border-radius: 0.375rem; + background: var(--surface); + color: var(--text); + font-size: 0.875rem; } .new-repo-actions { - display: flex; - gap: 0.5rem; - margin-top: 0.25rem; + display: flex; + gap: 0.5rem; + margin-top: 0.25rem; } - diff --git a/openspec/changes/multi-session-terminal-ux/.openspec.yaml b/openspec/changes/multi-session-terminal-ux/.openspec.yaml new file mode 100644 index 0000000..58544e9 --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/.openspec.yaml @@ -0,0 +1,3 @@ +name: multi-session-terminal-ux +status: exploring +started_at: 2026-05-28 diff --git a/openspec/changes/multi-session-terminal-ux/apply-pr1.md b/openspec/changes/multi-session-terminal-ux/apply-pr1.md new file mode 100644 index 0000000..925d255 --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/apply-pr1.md @@ -0,0 +1,74 @@ +# Apply Report: PR 1 – Database + Backend Core for Multi-Session Terminal UX + +## Summary + +Implemented the database schema, Alembic migration, TerminalManager multi-session core, and TerminalSession name/status tracking for the multi-session terminal UX feature. All changes are backward-compatible with the existing single-session `/terminal` WebSocket endpoint. + +### Key Changes + +1. **Database Schema** – Added `terminal_sessions` table with `UUIDPrimaryKeyMixin` + `TimestampMixin`, storing `instance_id`, `name`, `status`, `last_activity_at`, and `closed_at`. +2. **Alembic Migration** – Created migration `2026_05_28_add_terminal_sessions` (down-revision from `20260527_160017_add_pi_agent`). +3. **TerminalSession** – Added `name` (auto-generated as "Session N"), `status` field (`active`/`resetting`/`closed`), and updated `reset()`/`close()` to set status appropriately. +4. **TerminalManager** – Migrated `_sessions` dict from `dict[str, TerminalSession]` to `dict[tuple[str, str], TerminalSession]`. Added `create_session()`, `get_session()`, `get_sessions_for_instance()`, `close_session()`, and updated `reset_session()` to accept an optional `session_id`. Preserved `get_or_create_session()` for backward compatibility (uses `"default"` session_id). Idle cleanup now operates on composite keys and fires DB status updates asynchronously. +5. **Tests** – Created 7 unit tests covering session creation, max-5 enforcement, filtering, close/removal, WebSocket isolation, default session keying, and idle cleanup DB updates. + +## Files Created + +- `apps/api/src/models/terminal_session.py` +- `apps/api/alembic/versions/2026_05_28_add_terminal_sessions_table.py` +- `apps/api/tests/services/test_terminal_manager_multi.py` + +## Files Modified + +- `apps/api/src/models/__init__.py` – Imported `TerminalSessionModel` +- `apps/api/src/main.py` – Imported `TerminalSessionModel` for Alembic model discovery +- `apps/api/src/services/terminal_manager.py` – Full refactor to composite-key session management with DB fire-and-forget helpers +- `apps/api/src/services/terminal_session.py` – Added `name`, `status`, `_instance_counters`, and status transitions + +## Test Results + +### New Tests (7/7 passed) + +``` +$ cd apps/api && python -m pytest tests/services/test_terminal_manager_multi.py -v + +tests/services/test_terminal_manager_multi.py::test_create_session_increases_count PASSED +tests/services/test_terminal_manager_multi.py::test_create_session_enforces_max_5 PASSED +tests/services/test_terminal_manager_multi.py::test_get_sessions_for_instance_filters_by_instance PASSED +tests/services/test_terminal_manager_multi.py::test_close_session_removes_from_dict PASSED +tests/services/test_terminal_manager_multi.py::test_attach_websocket_only_closes_same_session PASSED +tests/services/test_terminal_manager_multi.py::test_default_session_keyed_separately PASSED +tests/services/test_terminal_manager_multi.py::test_idle_cleanup_updates_db_status PASSED + +======================== 7 passed, 4 warnings in 0.11s ========================= +``` + +### Full Suite (no regressions) + +``` +$ cd apps/api && python -m pytest tests/ -q + +51 failed, 174 passed, 6 warnings in 15.96s +``` + +- **Baseline failures**: 51 (pre-existing, unchanged by this PR) +- **New passes**: +7 (from `test_terminal_manager_multi.py`) +- **No new failures introduced** + +## Deviations from Design + +1. **Duplicate `created_at` column** – The design spec and its Alembic snippet listed `created_at` twice (once explicitly, once from `TimestampMixin`). I removed the explicit `created_at` from the model and migration, relying on `TimestampMixin` which provides `server_default=func.now()`. +2. **DB write implementation** – The design showed DB writes inside `TerminalManager` but didn't specify the exact async pattern. I implemented them as `asyncio.create_task`-wrapped coroutines using `SessionLocal()` so they are non-blocking. Unit tests mock `_mark_closed_in_db` and `_insert_db_session_row` to verify calls without needing a live DB. +3. **`get_or_create_session` auto-name** – The design said default session should count toward the 5-session limit. The current implementation does count it, but `get_or_create_session` creates the default session outside the `create_session` path (to preserve backward compat). Future REST endpoints can enforce the limit at the API layer before calling either path. + +## Blockers / Risks + +- **Global singleton test isolation** – `TerminalManager` is still a global singleton (`terminal_manager = TerminalManager()`). The unit tests create fresh instances via the `manager` fixture, but integration tests that import the global may need care to reset state between tests. +- **DB fire-and-forget in tests** – The aiosqlite background thread emits `RuntimeError: Event loop is closed` warnings when the test event loop tears down before the fire-and-forget DB task completes. This is harmless in tests but worth monitoring. +- **Migration head** – The migration chains from `20260527_160017_add_pi_agent`. If a new migration lands on `dev` before this PR merges, the `down_revision` must be updated. + +## Next Recommended Action + +1. **Task 5 (WebSocket endpoint + REST API)** – Implement the new `/ws/tool-instances/{instance_id}/terminal/{session_id}` WebSocket route and the REST endpoints (`GET/POST/DELETE .../terminal/sessions`) in `apps/api/src/api/terminal.py`. Extract the shared auth/validation/I/O loop into `_handle_terminal_websocket()` as specified in the design. +2. **Run migration in a staging environment** – Verify `alembic upgrade head` applies cleanly and `downgrade` reverses without data loss. +3. **Integration tests for WebSocket multi-session** – Create `apps/api/tests/api/test_terminal_ws_multi.py` to validate concurrent session isolation and the default-session alias. diff --git a/openspec/changes/multi-session-terminal-ux/apply-pr2.md b/openspec/changes/multi-session-terminal-ux/apply-pr2.md new file mode 100644 index 0000000..e69de29 diff --git a/openspec/changes/multi-session-terminal-ux/apply-pr3.md b/openspec/changes/multi-session-terminal-ux/apply-pr3.md new file mode 100644 index 0000000..083e391 --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/apply-pr3.md @@ -0,0 +1,40 @@ +# PR 3: Frontend Multi-Session Terminal UI + +## Summary +Implemented the frontend UI for multi-session terminal support: tabbed session management, fullscreen mode, keyboard shortcuts, and mobile integration. + +## Files Created +- `apps/web/src/components/terminal-session-tabs.tsx` — Tab bar component with rename, close, status dots, overflow scroll +- `apps/web/src/components/terminal-session-tabs.test.tsx` — 7 passing component tests + +## Files Modified +- `apps/web/src/components/terminal.tsx` — Added `sessionId` prop, `TerminalRef` with `fit()`, `forwardRef` wrapper +- `apps/web/src/pages/terminal.tsx` — Multi-session orchestration with tabs, fullscreen, keyboard shortcuts +- `apps/web/src/hooks/use-terminal-sessions.ts` — Hook for session CRUD + state management +- `apps/web/src/api/terminal.ts` — API client for terminal session endpoints +- `apps/web/src/styles.css` — Terminal tab styles, fullscreen mode, mobile responsive +- `apps/api/src/services/terminal_manager.py` — Added lookup by internal session_id fallback + +## Acceptance Criteria +- [x] TerminalComponent accepts optional sessionId prop +- [x] WS URL includes sessionId when provided +- [x] TerminalSessionTabs renders sessions with status dots +- [x] Double-click to rename, click × to close (with confirm) +- [x] New session (+) button, disabled at 5 sessions +- [x] Tab switching updates active terminal, calls fit() +- [x] Fullscreen toggle (Alt+Shift+F), exit via Esc +- [x] Keyboard shortcuts: Alt+Shift+N (new), W (close), ←/→ (navigate), R (reset) +- [x] Auto-creates default session if none exist +- [x] Closing last session auto-creates new default +- [x] Mobile: tabs in compact strip, same keyboard shortcuts +- [x] No browser shortcuts overridden (uses Alt+Shift, not Ctrl+Shift) + +## Quality Gates +- TypeScript typecheck: ✅ clean +- Frontend tests: ✅ 7/7 terminal-session-tabs tests passing +- Backend tests: ✅ 182 passed, 51 pre-existing failures (no regressions) +- Lint: ✅ 0 errors + +## Blockers / Deviations +- MobileTerminalWrapper was not fully integrated with session tabs due to complexity. Mobile path uses inline tab rendering instead. +- This is acceptable for MVP; full mobile integration can be refined in follow-up. diff --git a/openspec/changes/multi-session-terminal-ux/design.md b/openspec/changes/multi-session-terminal-ux/design.md new file mode 100644 index 0000000..9d8a62a --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/design.md @@ -0,0 +1,867 @@ +# SDD Design: Multi-Session Terminal UX + +## Architecture Overview + +The multi-session terminal extends the existing persistent-session foundation to support up to 5 concurrent terminal sessions per tool instance. The architecture uses a **hybrid storage model**: active PTY processes and WebSocket routing live in-memory (performance-critical path), while session metadata (name, status, timestamps) persists in a new `terminal_sessions` database table. + +### High-Level Flow + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ Frontend (React) │ +│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ +│ │ TerminalSession │ │ TerminalSession │ │ TerminalSession │ ... │ +│ │ Tabs (Desktop) │ │ Tabs (Mobile) │ │ FullscreenMgr │ │ +│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ +│ │ │ │ │ +│ ┌────────▼──────────────────────▼──────────────────────▼─────────┐ │ +│ │ TerminalSessionManager │ │ +│ │ (React state: sessions[], activeSessionId) │ │ +│ └────────┬──────────────────────┬──────────────────────┬─────────┘ │ +│ │ │ │ │ +│ ┌────────▼─────────┐ ┌────────▼─────────┐ ┌────────▼─────────┐ │ +│ │ TerminalComponent│ │ TerminalComponent│ │ TerminalComponent│ ... │ +│ │ (xterm.js + WS) │ │ (xterm.js + WS) │ │ (xterm.js + WS) │ │ +│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ +└───────────┼─────────────────────┼─────────────────────┼────────────────────┘ + │ │ │ + ▼ ▼ ▼ + ┌─────────────────────────────────────────────────────────────┐ + │ FastAPI Backend │ + │ ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐ │ + │ │ /terminal │ │ /terminal/{sid} │ │ REST /ses- │ │ + │ │ (default alias) │ │ (specific sess) │ │ sions │ │ + │ └────────┬─────────┘ └────────┬─────────┘ └─────┬──────┘ │ + │ │ │ │ │ + │ ┌────────▼──────────────────────▼────────────────────▼─────┐ │ + │ │ TerminalManager │ │ + │ │ dict[(instance_id, session_id)] → TerminalSession │ │ + │ └────────┬──────────────────────┬──────────────────────────┘ │ + │ │ │ │ + │ ┌────────▼─────────┐ ┌────────▼─────────┐ │ + │ │ TerminalSession │ │ TerminalSession │ ... │ + │ │ (PTY + docker │ │ (PTY + docker │ │ + │ │ exec process) │ │ exec process) │ │ + │ └────────┬─────────┘ └────────┬─────────┘ │ + │ │ │ │ + │ ┌────────▼──────────────────────▼───────────────────────────┐│ + │ │ TerminalSessionModel (DB) ││ + │ │ instance_id | name | status | created_at | closed_at ││ + │ └───────────────────────────────────────────────────────────┘│ + └───────────────────────────────────────────────────────────────┘ +``` + +### Key Principles + +- **One WebSocket per session**: Each `TerminalComponent` opens its own WebSocket to its specific `session_id`. Inactive sessions keep their WebSocket open to preserve scrollback and real-time output. +- **Max 5 sessions per instance**: Enforced in `TerminalManager.create_session()` and validated in the REST endpoint. +- **Default session alias**: `/ws/tool-instances/{instance_id}/terminal` maps to the single legacy session (or the first/only active session) for backward compatibility. +- **Tab-only UI**: No split panes for MVP. Sessions are presented as tabs on desktop and as a scrollable tab strip integrated into the mobile header area. + +--- + +## Backend Design + +### 1. TerminalManager Changes + +**File**: `apps/api/src/services/terminal_manager.py` + +#### Session Key Change + +```python +# BEFORE +self._sessions: dict[str, TerminalSession] = {} # keyed by instance_id + +# AFTER +self._sessions: dict[tuple[str, str], TerminalSession] = {} # keyed by (instance_id, session_id) +``` + +#### New / Modified Methods + +| Method | Signature | Behavior | +|--------|-----------|----------| +| `create_session` | `(instance_id, container_id, startup_command=None, name=None) → TerminalSession` | Creates a new `TerminalSession`, starts it, stores under `(instance_id, session_id)`, and inserts a `TerminalSessionModel` DB row. Enforces max 5 sessions. | +| `get_or_create_session` | *(preserved)* | **Backward-compat only.** Returns existing default session or creates one with `session_id="default"`. Called by the legacy `/terminal` WebSocket endpoint. | +| `get_session` | `(instance_id, session_id) → TerminalSession \| None` | Lookup by composite key. | +| `get_sessions_for_instance` | `(instance_id) → list[TerminalSession]` | Returns all in-memory sessions for an instance. | +| `close_session` | `(instance_id, session_id) → None` | Kills the PTY process, removes from `_sessions`, updates DB row `status=closed`, `closed_at=now()`. | +| `reset_session` | *(modified)* | Now accepts an optional `session_id`. If omitted, resets the default session. | +| `attach_websocket` | *(preserved)* | **Critical fix**: The "close existing WebSockets" logic must only close sockets **within the same `(instance_id, session_id)`**. Previously it closed all sockets for the instance. | + +#### Default Session Behavior + +- The first time a client hits `/ws/.../terminal` (no `session_id`), `TerminalManager` checks if a "default" session exists under key `(instance_id, "default")`. +- If none exists, it creates one (same as `get_or_create_session`). +- The default session counts toward the 5-session limit. + +#### Idle Cleanup + +```python +async def _cleanup_idle_sessions(self) -> None: + idle_keys = [] + for (instance_id, session_id), session in list(self._sessions.items()): + if session.is_idle(): + idle_keys.append((instance_id, session_id)) + for key in idle_keys: + session = self._sessions.pop(key, None) + if session: + await session.close() + # Update DB status + await self._mark_closed_in_db(key[1]) +``` + +### 2. TerminalSession Changes + +**File**: `apps/api/src/services/terminal_session.py` + +#### New Fields + +```python +class TerminalSession: + # ... existing fields ... + + def __init__(self, session_id: str, instance_id: uuid.UUID, container_id: str, + startup_command: str | None = None, name: str | None = None) -> None: + # ... existing init ... + self.name = name or f"Session {self._next_session_number(instance_id)}" + self.status: str = "active" # active, resetting, closed +``` + +The `name` field is runtime-only in `TerminalSession`. Renames update the DB via REST, then the frontend uses the new name on next mount or via a lightweight WS status broadcast (optional optimization). + +#### Status Tracking + +- `active`: Normal operation. +- `resetting`: Transient during `reset()` — cleared after new process starts. +- `closed`: Set after `close()` is called. + +### 3. WebSocket Endpoint Changes + +**File**: `apps/api/src/api/terminal.py` + +#### New Route (Specific Session) + +```python +@router.websocket("/ws/tool-instances/{instance_id}/terminal/{session_id}") +async def terminal_websocket_specific( + websocket: WebSocket, + instance_id: str, + session_id: str, + db_session: AsyncSession = Depends(get_db_session), +) -> None: + ... +``` + +#### Backward-Compatible Route (Default Session) + +```python +@router.websocket("/ws/tool-instances/{instance_id}/terminal") +async def terminal_websocket_default( + websocket: WebSocket, + instance_id: str, + db_session: AsyncSession = Depends(get_db_session), +) -> None: + # Identical auth/validation logic + # Calls terminal_manager.get_or_create_session(...) # uses "default" session_id + # Rest of the loop is identical to specific-session endpoint + ... +``` + +#### Refactoring + +Both endpoints share the same auth/validation and I/O loop logic. Extract a common coroutine: + +```python +async def _handle_terminal_websocket( + websocket: WebSocket, + instance_id: str, + session_id: str | None, # None means default + db_session: AsyncSession, +) -> None: + # Shared: auth, instance lookup, tool_type fetch, session fetch/create, + # attach_websocket, read/write/heartbeat loops, detach_websocket +``` + +#### Control Messages (Unchanged) + +The WebSocket control message protocol is unchanged: + +- `{"type": "resize", "cols": 80, "rows": 24}` +- `{"type": "reset"}` — resets the **current** session only + +### 4. Database Schema + +**File**: `apps/api/src/models/terminal_session.py` (new) + +```python +import uuid +from datetime import datetime + +from sqlalchemy import DateTime, ForeignKey, String +from sqlalchemy import Uuid as UUID +from sqlalchemy.orm import Mapped, mapped_column + +from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin + + +class TerminalSessionModel(UUIDPrimaryKeyMixin, TimestampMixin, Base): + __tablename__ = "terminal_sessions" + + instance_id: Mapped[uuid.UUID] = mapped_column( + UUID(), + ForeignKey("tool_instances.id", ondelete="CASCADE"), + nullable=False, + index=True, + ) + name: Mapped[str | None] = mapped_column(String(255), nullable=True) + status: Mapped[str] = mapped_column( + String(50), + nullable=False, + default="active", + ) + created_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), + nullable=False, + ) + last_activity_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), + nullable=True, + ) + closed_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), + nullable=True, + ) +``` + +#### Rationale + +- `instance_id` is indexed because lookups by instance are frequent (listing sessions, cleanup). +- `name` is nullable; auto-generated names are stored here so they survive page reloads. +- `status` tracks `active` vs `closed`. The `TerminalManager` updates `last_activity_at` whenever a WebSocket attaches/detaches or I/O occurs. +- On API restart, in-memory sessions are lost, but `terminal_sessions` rows remain as metadata history. A future enhancement could resurrect sessions, but that is out of scope. + +### 5. Alembic Migration + +**File**: `apps/api/src/alembic/versions/XXXX_add_terminal_sessions_table.py` + +```python +"""Add terminal_sessions table.""" + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = "" +down_revision = "" + + +def upgrade() -> None: + op.create_table( + "terminal_sessions", + sa.Column("id", sa.UUID(), nullable=False), + sa.Column("instance_id", sa.UUID(), nullable=False), + sa.Column("name", sa.String(length=255), nullable=True), + sa.Column("status", sa.String(length=50), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), + sa.Column("last_activity_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("closed_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), # TimestampMixin + sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), # TimestampMixin + sa.ForeignKeyConstraint(["instance_id"], ["tool_instances.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_terminal_sessions_instance_id"), "terminal_sessions", ["instance_id"], unique=False) + + +def downgrade() -> None: + op.drop_index(op.f("ix_terminal_sessions_instance_id"), table_name="terminal_sessions") + op.drop_table("terminal_sessions") +``` + +### 6. REST API Additions + +**File**: `apps/api/src/api/terminal.py` (same file as WebSocket endpoint) + +All new endpoints follow the existing URL pattern: `/projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/terminal/sessions`. + +#### Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `.../instances/{instance_id}/terminal/sessions` | List sessions for an instance. Returns metadata from DB + live `has_websockets` flag by querying `TerminalManager`. | +| `POST` | `.../instances/{instance_id}/terminal/sessions` | Create a new session. Optional body: `{ "name": "Custom Name" }`. Returns `{ session_id, name, status, created_at }`. Enforces max 5. | +| `DELETE` | `.../instances/{instance_id}/terminal/sessions/{session_id}` | Close a specific session. Kills PTY, updates DB. Returns `{ status: "closed" }`. | +| `POST` | `.../instances/{instance_id}/terminal/sessions/{session_id}/reset` | Reset a specific session (kill + recreate). Returns `{ session_id, name, status }`. | +| `POST` | `.../instances/{instance_id}/terminal/sessions/{session_id}/rename` | Rename a session. Body: `{ "name": "New Name" }`. Updates DB; name reflected on next session list fetch. | + +#### Existing Endpoint Preservation + +| Method | Path | Behavior | +|--------|------|----------| +| `POST` | `.../instances/{instance_id}/terminal/reset` | **Preserved as alias.** Resets the default session (same as `POST .../sessions/default/reset`). | + +#### Response Schema (List Sessions) + +```json +{ + "sessions": [ + { + "id": "uuid", + "name": "Session 1", + "status": "active", + "has_websockets": true, + "created_at": "2026-05-28T10:00:00Z", + "last_activity_at": "2026-05-28T10:05:00Z" + } + ] +} +``` + +--- + +## Frontend Design + +### 1. Session Tabs Component (`TerminalSessionTabs`) + +**File**: `apps/web/src/components/terminal-session-tabs.tsx` + +#### Props + +```typescript +interface TerminalSessionTabsProps { + sessions: TerminalSessionInfo[]; + activeSessionId: string; + onSelect: (sessionId: string) => void; + onClose: (sessionId: string) => void; + onCreate: () => void; + onRename: (sessionId: string, newName: string) => void; + isMobile?: boolean; +} + +interface TerminalSessionInfo { + id: string; + name: string; + status: "connecting" | "connected" | "disconnected" | "error" | "resetting"; +} +``` + +#### Desktop Behavior + +- Horizontal tab strip positioned **above** the terminal container. +- Each tab shows: session name, status dot (colored), close button (×) visible on hover/active. +- Overflow: horizontal scroll with subtle fade indicator. +- **New session button (+)**: Fixed at the right end of the tab strip. Disabled when 5 sessions exist. +- **Double-click to rename**: Inline `` replaces tab text. `Enter` to confirm, `Escape` to cancel. Blur confirms. +- **Close confirmation**: For sessions with an active process and WebSocket, show a lightweight inline confirm tooltip (not a full modal) to avoid friction. + +#### Mobile Behavior + +- Tab strip is integrated into the existing auto-hide chrome. +- `MobileTerminalHeader` gains a `sessionTabs` render prop or child area below the title row. +- Tabs are compact (icon + truncated name + ×). Horizontal swipe scrolls. +- New session (+) is the rightmost item. +- The tab strip shares the auto-hide behavior with the header (tapping the terminal toggles visibility). + +### 2. Modified `TerminalPage` + +**File**: `apps/web/src/pages/terminal.tsx` + +#### State Management + +```typescript +interface TerminalPageState { + sessions: TerminalSessionInfo[]; + activeSessionId: string | null; + isFullscreen: boolean; + isLoading: boolean; +} +``` + +#### Session Lifecycle + +1. **Mount**: `useEffect` calls `GET .../terminal/sessions`. If no sessions exist, auto-creates one via `POST`. +2. **Active session**: Only one tab is visually active. **All `TerminalComponent` instances remain mounted** but inactive ones use CSS `display: none` to preserve xterm.js scrollback and WebSocket connections. +3. **Switch tabs**: Updates `activeSessionId`. The newly active tab's `TerminalComponent` triggers `fitAddon.fit()` via a ref callback after becoming visible (using a `useEffect` on visibility). + +#### Render Structure + +```tsx +
+ {!isFullscreen && ( +
...
+ )} + + + +
+ {sessions.map((s) => ( +
+ handleCloseSession(s.id)} + isMobile={isMobile} + // ... other props + /> +
+ ))} +
+
+``` + +### 3. Modified `TerminalComponent` + +**File**: `apps/web/src/components/terminal.tsx` + +#### New Props + +```typescript +interface TerminalProps { + instanceId: string; + sessionId?: string; // NEW: omitted → uses default session (backward compat) + // ... existing props +} +``` + +#### WebSocket URL + +```typescript +const wsPath = sessionId + ? `/ws/tool-instances/${instanceId}/terminal/${sessionId}` + : `/ws/tool-instances/${instanceId}/terminal`; +``` + +#### Reset Semantics Update + +The component's reset button now sends `{"type": "reset"}` to its own session. The `SessionRef` loop in the backend handles resetting that specific session. After reset, the backend sends `{"type": "status", "status": "connected"}` with the new session object, and the frontend clears the terminal. + +#### Fullscreen Awareness + +When `TerminalPage` enters fullscreen, it passes `isFullscreen` down (via context or prop drilling). `TerminalComponent` adjusts its container height to `100vh` (minus tab strip if visible in fullscreen). + +### 4. Mobile Integration + +**File**: `apps/web/src/components/mobile-terminal-wrapper.tsx` + +#### Changes + +- Accepts `sessions`, `activeSessionId`, and tab callbacks as props from `TerminalPage`. +- Renders `TerminalSessionTabs` between `MobileTerminalHeader` and the terminal content area. +- The tab strip auto-hides along with the header (`useAutoHide`). +- `MobileTerminalHeader` title is updated to show `activeSession.name` instead of generic "Terminal". +- Fullscreen on mobile: hides the header, tab strip, and special-keys strip. A tap in the bottom-right corner (or swipe from edge) reveals the tab strip temporarily. + +### 5. Fullscreen Mode + +**Trigger**: UI button (maximize icon in header) or `Ctrl+Shift+F`. + +#### Desktop Fullscreen + +- `TerminalPage` adds `.fullscreen` class. +- Header and page chrome are hidden (`display: none`). +- Tab strip remains visible as a minimal overlay (semi-transparent, auto-hides after 3s of inactivity, reappears on mouse move). +- Terminal container fills viewport. +- Exit: `Esc` key or click exit-fullscreen button. + +#### Mobile Fullscreen + +- Same as desktop but also hides `SpecialKeysStrip` and `SpecialKeysPanel`. +- A small floating handle at the bottom center reveals the tab strip and special keys on tap. + +### 6. Keyboard Shortcuts + +**Constraint**: Do not override browser defaults. All shortcuts use combinations that are either unassigned or safe in major browsers. + +| Shortcut | Action | Browser Conflict? | +|----------|--------|-------------------| +| `Ctrl+Shift+F` | Toggle fullscreen | None major | +| `Alt+Shift+N` | New session | None major | +| `Alt+Shift+W` | Close current session | None major | +| `Alt+Shift+←` / `Alt+Shift+→` | Previous / next session | None major | +| `Alt+Shift+R` | Reset current session | None major | + +All actions are also accessible via UI buttons. Shortcuts are registered in `TerminalPage` via a `useEffect` on `keydown` with `event.preventDefault()` only for the specific combos above. + +### 7. Session State Management + +**File**: `apps/web/src/hooks/use-terminal-sessions.ts` (new hook) + +```typescript +export function useTerminalSessions(instanceId: string) { + const [sessions, setSessions] = useState([]); + const [activeSessionId, setActiveSessionId] = useState(null); + + const createSession = useCallback(async (name?: string) => { ... }, [instanceId]); + const closeSession = useCallback(async (sessionId: string) => { ... }, [instanceId]); + const renameSession = useCallback(async (sessionId: string, name: string) => { ... }, [instanceId]); + const resetSession = useCallback(async (sessionId: string) => { ... }, [instanceId]); + + // Initial load + useEffect(() => { + loadSessions().then((sess) => { + if (sess.length === 0) { + createSession().then((s) => setActiveSessionId(s.id)); + } else { + setSessions(sess); + setActiveSessionId(sess[0].id); + } + }); + }, [instanceId]); + + return { sessions, activeSessionId, setActiveSessionId, createSession, closeSession, renameSession, resetSession }; +} +``` + +--- + +## Data Flow + +### 1. Create New Session + +``` +User clicks [+] tab + │ + ▼ +Frontend: POST /instances/{id}/terminal/sessions { name?: "Session 3" } + │ + ▼ +Backend: + 1. Auth + validate instance running + 2. Check session count < 5 + 3. TerminalManager.create_session() + - Generates UUID session_id + - Starts docker exec PTY + - Inserts TerminalSessionModel row + 4. Returns { session_id, name, status, created_at } + │ + ▼ +Frontend: + 1. Append session to sessions[] + 2. setActiveSessionId(newId) + 3. React renders new with sessionId prop + 4. Component opens WS to /terminal/{session_id} + 5. Backend attaches WS, replays buffer +``` + +### 2. Switch Between Sessions + +``` +User clicks tab "Session 2" + │ + ▼ +Frontend: setActiveSessionId("session-2-uuid") + │ + ▼ +React re-renders: + - Session 1 container → className="hidden" (display: none) + - Session 2 container → className="active" (display: block) + │ + ▼ +Session 2 useEffect (on visibility change): + - Calls fitAddon.fit() + - Sends resize message over its existing WS + │ + ▼ +(Backend: no operation needed. Both WS connections remain open.) +``` + +### 3. Close Session + +``` +User clicks [×] on "Session 2" + │ + ▼ +Frontend: confirm() or inline tooltip + │ + ▼ +Frontend: DELETE /instances/{id}/terminal/sessions/{session_id} + │ + ▼ +Backend: + 1. Auth + 2. TerminalManager.close_session(instance_id, session_id) + - Kills docker exec process + - Removes from _sessions dict + - Updates DB: status=closed, closed_at=now() + 3. Returns { status: "closed" } + │ + ▼ +Frontend: + 1. Remove session from sessions[] + 2. Unmount (WS closes with code 1000) + 3. If closed session was active, setActiveSessionId to another session (or create one if none left) +``` + +### 4. Reconnect to Existing Session + +``` +User reloads page + │ + ▼ +Frontend: GET /instances/{id}/terminal/sessions + │ + ▼ +Backend: Returns all DB rows with status != "closed" + │ + ▼ +Frontend: Populate sessions[]. For each session, render . + │ + ▼ +Each TerminalComponent opens its WS: + WS URL: /ws/tool-instances/{id}/terminal/{session_id} + │ + ▼ +Backend: + 1. Auth + 2. TerminalManager.get_session(instance_id, session_id) + - If found in-memory: attach_websocket, replay buffer + - If not found in-memory (API restarted): WS closes with code 4004 "Session not found" + (Frontend handles by showing "Session expired" with option to reset/recreate.) +``` + +--- + +## Contracts + +### WebSocket Protocol + +#### Connection URLs + +| URL | Purpose | +|-----|---------| +| `/ws/tool-instances/{instance_id}/terminal` | Default session (backward compatible). Creates/attaches to the single legacy session. | +| `/ws/tool-instances/{instance_id}/terminal/{session_id}` | Specific session. Attaches to an existing session or fails if not found. | + +#### Client → Server Messages + +| Type | Payload | Purpose | +|------|---------|---------| +| `resize` | `{ cols: number, rows: number }` | Resize PTY | +| `reset` | `{}` | Kill and restart the **current** session's shell | +| `pong` | `{}` | Heartbeat response | + +#### Server → Client Messages + +| Type | Payload | Purpose | +|------|---------|---------| +| (binary) | `bytes` | PTY output | +| `status` | `{ status: "connected" \| "resetting" }` | Lifecycle status | +| `ping` | `{}` | Heartbeat | + +### REST API Contract + +#### `GET /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions` + +**Response 200:** +```json +{ + "sessions": [ + { + "id": "uuid", + "name": "Session 1", + "status": "active", + "has_websockets": true, + "created_at": "2026-05-28T10:00:00Z", + "last_activity_at": "2026-05-28T10:05:00Z" + } + ] +} +``` + +#### `POST /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions` + +**Request body:** +```json +{ "name": "Optional Custom Name" } +``` + +**Response 201:** +```json +{ + "id": "uuid", + "name": "Session 2", + "status": "active", + "created_at": "2026-05-28T10:00:00Z" +} +``` + +**Response 409:** (max sessions reached) +```json +{ "detail": "Maximum of 5 terminal sessions reached for this instance" } +``` + +#### `DELETE /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions/{sid}` + +**Response 200:** +```json +{ "status": "closed", "session_id": "uuid" } +``` + +#### `POST /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions/{sid}/reset` + +**Response 200:** +```json +{ + "id": "uuid", + "name": "Session 1", + "status": "active" +} +``` + +#### `POST /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions/{sid}/rename` + +**Request body:** +```json +{ "name": "New Name" } +``` + +**Response 200:** +```json +{ "id": "uuid", "name": "New Name" } +``` + +--- + +## Testing Strategy + +### Unit Tests + +**Backend**: `apps/api/tests/services/test_terminal_manager.py` + +| Test | Scenario | +|------|----------| +| `test_create_session_increases_count` | Creating sessions increments the per-instance count | +| `test_create_session_enforces_max_5` | 6th creation raises `MaxSessionsExceededError` | +| `test_get_sessions_for_instance` | Returns only sessions for the requested instance | +| `test_close_session_removes_from_dict` | `close_session` removes key from `_sessions` | +| `test_attach_websocket_only_closes_same_session` | Attaching to session A does not close websockets on session B | +| `test_default_session_keyed_separately` | Default session uses `"default"` session_id and does not collide with named sessions | +| `test_idle_cleanup_updates_db` | Idle cleanup calls DB update with `status=closed` | + +**Frontend**: `apps/web/src/components/terminal-session-tabs.test.tsx` + +| Test | Scenario | +|------|----------| +| `test_renders_all_tabs` | Renders one tab per session | +| `test_click_tab_selects_session` | Clicking a tab calls `onSelect` with correct ID | +| `test_close_button_calls_onClose` | Clicking × calls `onClose` | +| `test_double_click_enables_rename` | Double-click shows input; Enter commits | +| `test_plus_disabled_at_max_sessions` | `+` button is disabled when 5 sessions exist | + +### Integration Tests + +**Backend**: `apps/api/tests/api/test_terminal_ws.py` + +| Test | Scenario | +|------|----------| +| `test_specific_session_websocket` | Connect to `/terminal/{session_id}`, verify output | +| `test_default_session_alias` | Connect to `/terminal`, verify it creates/uses default session | +| `test_concurrent_sessions_isolated` | Two WS connections to different session_ids receive independent output | +| `test_reset_control_message_scoped` | `{"type":"reset"}` only resets the current session | +| `test_list_sessions_returns_live_and_db` | `GET /sessions` reflects both in-memory state and DB rows | + +**Frontend**: `apps/web/src/pages/terminal.test.tsx` (or E2E) + +| Test | Scenario | +|------|----------| +| `test_create_session_adds_tab` | Clicking + creates a new tab and switches to it | +| `test_switch_tab_preserves_scrollback` | Switching back to a previous tab shows prior output | +| `test_close_last_session_creates_default` | Closing the final session auto-creates a new default session | +| `test_fullscreen_toggle` | `Ctrl+Shift+F` toggles fullscreen class | + +--- + +## Rollout Plan + +### Phase 1: Database (Zero-Downtime) + +1. Run Alembic migration to create `terminal_sessions` table. +2. No code reads from or writes to this table yet. Existing sessions remain purely in-memory. +3. **Rollback**: Alembic downgrade removes table (no data loss risk since table is empty). + +### Phase 2: Backend API (Backward Compatible) + +1. Deploy updated `TerminalManager` with composite key `_sessions`. +2. Deploy updated `TerminalSession` with `name` support. +3. Deploy new WebSocket route `/terminal/{session_id}` and preserve `/terminal` alias. +4. Deploy new REST endpoints (`GET/POST/DELETE .../sessions`). +5. Update DB writes on session lifecycle (create, close, activity update). +6. **Rollback**: Revert code. Old `/terminal` endpoint continues to work. New `/terminal/{session_id}` returns 404, but no clients call it yet. + +### Phase 3: Frontend (Feature Flag Optional) + +1. Deploy new components (`TerminalSessionTabs`, `useTerminalSessions`). +2. Update `TerminalPage` and `MobileTerminalWrapper`. +3. Update `TerminalComponent` to accept optional `sessionId` prop. +4. If a feature flag is used, enable multi-session UI for beta users first. +5. **Rollback**: Revert frontend. Users see the old single-session UI. Backend `/terminal` alias continues to serve them. + +### Phase 4: Deprecation & Cleanup (Follow-Up Task) + +1. Monitor usage of the legacy `/terminal` WebSocket endpoint and `POST .../terminal/reset` REST endpoint. +2. After 2-4 weeks of stable multi-session usage: + - Mark legacy endpoints as deprecated in OpenAPI docs. + - Update frontend to always use `/terminal/{session_id}` (never rely on default alias). +3. In a future release, remove the default alias if desired (not required for correctness). + +### Backward Compatibility Strategy + +| Layer | Compat Mechanism | +|-------|-----------------| +| WebSocket | `/terminal` remains default-session alias forever (or until explicit deprecation). Old clients continue to work. | +| REST API | Existing `POST .../terminal/reset` preserved as alias. No breaking changes to response shape. | +| Frontend | `sessionId` prop on `TerminalComponent` is optional. Omitting it uses the default session path. | +| DB | New table is additive only. No changes to `tool_instances` schema. | + +--- + +## Files to Create / Modify + +### New Files + +| File | Description | +|------|-------------| +| `apps/api/src/models/terminal_session.py` | SQLAlchemy `TerminalSessionModel` | +| `apps/api/src/alembic/versions/XXXX_add_terminal_sessions_table.py` | Alembic migration | +| `apps/web/src/components/terminal-session-tabs.tsx` | Tab bar UI (desktop + mobile) | +| `apps/web/src/hooks/use-terminal-sessions.ts` | Session CRUD + state hook | +| `apps/web/src/components/terminal-session-tabs.test.tsx` | Unit tests | +| `apps/api/tests/services/test_terminal_manager_multi.py` | TerminalManager multi-session tests | +| `apps/api/tests/api/test_terminal_ws_multi.py` | WS integration tests | + +### Modified Files + +| File | Changes | +|------|---------| +| `apps/api/src/services/terminal_manager.py` | Composite key dict, new CRUD methods, max session limit, DB integration | +| `apps/api/src/services/terminal_session.py` | Add `name` field, status tracking | +| `apps/api/src/api/terminal.py` | New WS route, REST endpoints, shared handler coroutine | +| `apps/api/src/main.py` | Import new model (if needed for Alembic autogenerate) | +| `apps/web/src/components/terminal.tsx` | Accept `sessionId` prop, use it in WS URL | +| `apps/web/src/pages/terminal.tsx` | Multi-session orchestration, tabs, fullscreen | +| `apps/web/src/components/mobile-terminal-wrapper.tsx` | Integrate tabs, pass session state | +| `apps/web/src/components/mobile-terminal-header.tsx` | Show active session name | +| `apps/web/src/api/sessions.ts` (or new `terminal.ts`) | REST client functions for session CRUD | + +--- + +## Risks & Mitigations + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| Resource exhaustion from 5× docker exec per instance | Medium | High | Max 5 enforced. Idle timeout (30 min) still applies per session. | +| Mobile UX degraded by tab bar + special keys strip | Medium | Medium | Auto-hide shared between tabs and header. Minimal tab design. | +| Concurrent WS policy closes wrong session's sockets | Medium | High | Unit test explicitly: attach to session A must not affect session B's websockets. | +| DB writes on hot path (activity tracking) | Low | Medium | `last_activity_at` updates are non-blocking fire-and-forget asyncio tasks. No await on commit. | +| Frontend performance with 5 mounted xterm.js instances | Low | Medium | Max 5 sessions. Inactive terminals are `display: none` (not unmounted). GPU acceleration in xterm.js handles this well. | +| Default session alias ambiguity | Low | Low | Document that `/terminal` maps to `"default"` session. Future deprecation can migrate default to explicit ID. | diff --git a/openspec/changes/multi-session-terminal-ux/explore.md b/openspec/changes/multi-session-terminal-ux/explore.md new file mode 100644 index 0000000..cd312d9 --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/explore.md @@ -0,0 +1,256 @@ +# SDD Explore: Multi-Session Terminal UX + +## Executive Summary + +The codebase has a well-built persistent terminal foundation from the `persistent-terminal-sessions` change. `TerminalManager` currently tracks exactly one `TerminalSession` per `instance_id` in an in-memory dict. `TerminalSession` already supports WebSocket attach/detach, circular output buffer replay, idle timeout, and process lifecycle management. + +Implementing multi-session terminal support is a **moderate-complexity, medium-risk** change. The core backend refactor is straightforward: change the session tracking key from `instance_id` to `(instance_id, session_id)` and update the WebSocket endpoint to accept a `session_id`. The frontend work is more involved: designing a tabbed session UI that works on both desktop and mobile, handling session creation/switching/closing, and integrating with the existing `MobileTerminalWrapper`. + +No database schema change is **strictly required** for an MVP—sessions can remain purely in-memory with the same idle-timeout cleanup. However, adding a `terminal_sessions` table would provide cross-API-restart persistence, session auditability, and a foundation for future features like session history or named sessions. + +## Current Architecture (as explored) + +### Backend +- **`TerminalManager`** (`apps/api/src/services/terminal_manager.py`): + - `self._sessions: dict[str, TerminalSession]` keyed by `instance_id` string. + - `get_or_create_session(instance_id, container_id, startup_command)` — returns the single existing session or creates a new one. + - `attach_websocket(session, websocket)` — detaches any *existing* WebSocket connections on that session (closes them with code 4000) before attaching the new one. This enforces single-active-client per session. + - `reset_session(instance_id, container_id, ...)` — kills the existing session and creates a new one. + - Idle check loop every 60s; sessions with no WebSockets attached for 30 minutes are cleaned up. +- **`TerminalSession`** (`apps/api/src/services/terminal_session.py`): + - Already has a `session_id: str` field (UUID) but it is not used as a lookup key. + - Manages one `docker exec` PTY process per session. + - Circular buffer (10KB) for output replay. + - Tracks `self._websockets: set[Any]` for attached connections. +- **`api/terminal.py`** (`apps/api/src/api/terminal.py`): + - WebSocket endpoint: `/ws/tool-instances/{instance_id}/terminal` + - Authenticates user, verifies instance ownership/running state, then calls `terminal_manager.get_or_create_session()`. + - Supports JSON control messages: `resize`, `reset`. + - POST endpoint: `/projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/terminal/reset` — resets the single session. +- **Database**: + - No `terminal_sessions` table exists. Terminal sessions are purely in-memory. + - `ToolInstance` model (`apps/api/src/models/tool_instance.py`) has no terminal-related fields. + +### Frontend +- **`TerminalComponent`** (`apps/web/src/components/terminal.tsx`): + - Single xterm.js terminal per component. + - One WebSocket connection to `/ws/tool-instances/{instance_id}/terminal`. + - Handles reconnect with exponential backoff (max 3 attempts). + - Font size persisted globally in `localStorage` under key `terminal-font-size`. + - Copy/paste buttons on mobile only. + - Status indicator: connecting, connected, disconnected, error, resetting. +- **`TerminalPage`** (`apps/web/src/pages/terminal.tsx`): + - Desktop: renders one `TerminalComponent` inside a page shell. + - Mobile: renders `MobileTerminalWrapper` which composes `MobileTerminalHeader`, `TerminalComponent`, `SpecialKeysStrip`, and `SpecialKeysPanel`. +- **`MobileTerminalWrapper`** (`apps/web/src/components/mobile-terminal-wrapper.tsx`): + - Already handles auto-hide header, virtual keyboard height, special keys, and mobile viewport detection. + - Manages terminal ref callbacks (`sendData`, `connectionStatus`, `focusInput`, `changeFontSize`). + +### Prior Art +- **`persistent-terminal-sessions`** (fully implemented): + - Sessions survive WebSocket disconnections. + - Buffer replay on reconnect. + - Idle timeout cleanup. + - Reset functionality. +- **`mobile-terminal-ux`** (mostly implemented): + - Mobile fullscreen terminal with collapsible chrome. + - Special keys toolbar. + - Dynamic viewport handling for virtual keyboard. + +## Architecture Options for Multi-Session + +### Option A: In-Memory Multi-Session (MVP) +- Change `TerminalManager._sessions` to `dict[tuple[str, str], TerminalSession]` keyed by `(instance_id, session_id)`. +- Add `create_session(instance_id, container_id, ...)` that always creates a new session. +- Keep `get_or_create_session()` for backward compatibility (returns the "default" or only session). +- Add `get_sessions_for_instance(instance_id) -> list[TerminalSession]`. +- Add `close_session(instance_id, session_id)` to kill a specific session. +- **Tradeoffs**: Simplest, no DB migration, survives existing patterns. Loses sessions on API restart. + +### Option B: Database-Backed Session Metadata +- Create `terminal_sessions` table: + ```sql + id UUID PRIMARY KEY, + instance_id UUID FK(tool_instances.id, ondelete=CASCADE), + session_name VARCHAR(255), + status VARCHAR(50), -- active, idle, closed + created_at TIMESTAMPTZ, + last_activity_at TIMESTAMPTZ, + closed_at TIMESTAMPTZ + ``` +- `TerminalManager` still keeps `TerminalSession` objects in memory, but creates/updates DB rows on lifecycle events. +- **Tradeoffs**: Enables cross-restart persistence, session history, named sessions, and auditability. Adds migration and async DB overhead to hot paths. + +### Option C: Hybrid (Recommended) +- In-memory active sessions for performance. +- DB table for metadata, created on session start, updated on activity/close. +- On API restart, sessions are gone (no process resurrection), but metadata remains for history. +- **Tradeoffs**: Best of both worlds. Slightly more complex than Option A but much simpler than full persistence. + +### Decision Matrix + +| Criterion | Option A | Option B | Option C | +|-----------|----------|----------|----------| +| Implementation complexity | Low | Medium | Medium | +| DB migration required | No | Yes | Yes | +| Cross-restart persistence | No | Yes (full) | Metadata only | +| Resource auditability | No | Yes | Yes | +| Performance | Best | Good (cacheable) | Best | +| Recommended for MVP | **Yes** | No | **Preferred** | + +## WebSocket Protocol Options + +### Option 1: URL Path Segment (Recommended) +``` +/ws/tool-instances/{instance_id}/terminal/{session_id} +``` +- Clean, RESTful, easy to route in FastAPI. +- Default session can use a reserved ID like `default` or keep `/terminal` as an alias. +- **Tradeoff**: Breaks existing hardcoded URLs; needs backward-compatibility route. + +### Option 2: Query Parameter +``` +/ws/tool-instances/{instance_id}/terminal?session_id=... +``` +- Easier to add without changing route structure. +- Less idiomatic for WebSocket APIs. +- **Tradeoff**: Query params in WebSocket URLs can be inconsistently supported by proxies. + +### Option 3: First-Message JSON Payload +- Client connects to `/terminal`, then sends `{"type": "attach", "session_id": "..."}`. +- Server must hold the connection in limbo until the attach message arrives. +- **Tradeoff**: More complex state machine; harder to reject invalid sessions early. + +**Recommendation**: Option 1 with a backward-compatible fallback: +- `/ws/tool-instances/{instance_id}/terminal` → attaches to the "default" session (existing behavior). +- `/ws/tool-instances/{instance_id}/terminal/{session_id}` → attaches to the specified session. + +## Frontend UX Design Options + +### Session Presentation: Tabs vs Panes + +| Feature | Tabs | Panes (Split) | +|---------|------|---------------| +| Desktop UX | Good | Excellent (tmux-like) | +| Mobile UX | Good | Poor (too cramped) | +| Implementation | Medium | High | +| Accessibility | Good | Complex | +| Recommendation | **Preferred** | Future enhancement | + +**Decision**: Start with tabs. A split-pane layout can be added later as an advanced feature without breaking the tab model. + +### Tab Bar Design +- Position: Above the terminal container on desktop; integrated into `MobileTerminalHeader` on mobile. +- Contents: + - Session name (auto-named "Session 1", "Session 2", or custom). + - Status dot (connecting, connected, error). + - Close button (×) on hover/active. + - New tab button (+). +- Overflow: Horizontal scroll on mobile; wrap or scroll on desktop. + +### Fullscreen Mode +- **Behavior**: Toggle hides all page chrome (header, sidebar, tab bar can optionally be shown as a minimal overlay). +- **Trigger**: `Ctrl+Shift+F` or UI button. +- **Mobile**: Should integrate with existing mobile fullscreen behavior (already hides AppShell). Fullscreen on mobile could mean hiding the special-keys strip too, with a gesture to reveal. +- **Exit**: `Esc` or UI button. + +### Keyboard Shortcuts + +| Shortcut | Action | Notes | +|----------|--------|-------| +| `Ctrl+Shift+N` | New session | May conflict with browser "New window" on some platforms. Consider `Ctrl+Shift+T` if not used for "Reopen tab". | +| `Ctrl+Shift+W` | Close current session | Conflicts with browser "Close window". May need `Ctrl+Shift+D` or accept override with `preventDefault()`. | +| `Ctrl+Shift+F` | Toggle fullscreen | Safe, no major browser conflict. | +| `Ctrl+Shift+T` | Toggle tab bar visibility | Conflicts with "Reopen closed tab" in browsers. Consider `Ctrl+Shift+B` or `Ctrl+Shift+~`. | + +**Recommendation**: Use `preventDefault()` aggressively and show a shortcuts help modal (e.g., `Ctrl+Shift+/` or `?`). + +### Session Naming +- **Auto-name**: "Session 1", "Session 2", etc. based on creation order. +- **Custom name**: Editable by double-clicking the tab. Persisted in DB if Option B/C, or in-memory only for Option A. +- **Default session**: The first session created for an instance can be unnamed or named "Default". + +### Reset/Kill Semantics +Current behavior: "Reset Terminal" kills the single session and starts fresh. + +With multi-session: +- **Close Session** (× on tab): Kills the `docker exec` process and removes the session. +- **New Session** (+ on tab bar): Creates a new session and switches to it. +- **Reset Session** (in menu): Same as current reset but scoped to the active session. +- **Reset All** (optional, in menu): Kill all sessions for the instance and recreate a default one. + +### Font Size Persistence +- Currently global (`localStorage` key `terminal-font-size`). +- With multi-session, users may want different font sizes per session (e.g., larger for presentations, smaller for logs). +- **Options**: + 1. Keep global (simplest, no change). + 2. Per-session font size (stored in session state or DB). + 3. Per-instance font size. +- **Recommendation**: Keep global for MVP. Per-session font size is a nice-to-have that adds complexity. + +### Status Per Session +- Each tab shows a status dot. +- Possible statuses: `connecting` (pulsing), `connected` (green), `disconnected` (yellow), `error` (red), `closed` (gray). +- The terminal component already tracks these statuses; they just need to be surfaced at the tab level. + +## Database Schema Recommendation (Option C) + +```python +class TerminalSessionModel(UUIDPrimaryKeyMixin, TimestampMixin, Base): + __tablename__ = "terminal_sessions" + + instance_id: Mapped[uuid.UUID] = mapped_column( + UUID(), ForeignKey("tool_instances.id", ondelete="CASCADE"), nullable=False + ) + name: Mapped[str | None] = mapped_column(String(255), nullable=True) + status: Mapped[str] = mapped_column( + String(50), nullable=False, default="active" + ) + # Not storing process PID here — that's runtime-only in TerminalManager + created_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), nullable=False, default=datetime.utcnow + ) + last_activity_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True + ) + closed_at: Mapped[datetime | None] = mapped_column( + DateTime(timezone=True), nullable=True + ) +``` + +**Migration**: New alembic revision adding `terminal_sessions` table. + +## Open Questions Needing User/Product Decisions + +1. **Max sessions per instance?** Suggest 5 for MVP to prevent resource exhaustion. +2. **Should we persist sessions across API restarts?** Option A = no; Option C = metadata only. Product call. +3. **Tab vs Pane UI?** Strongly recommend tabs for MVP. Panes as future work. +4. **Keyboard shortcuts — override browser defaults?** `Ctrl+Shift+W` closes browser window. We can `preventDefault()` but should warn users. +5. **Should the existing `/terminal` endpoint remain as a default-session alias?** Yes for backward compatibility, but confirm. +6. **Session idle timeout per session or global per instance?** Currently per session. Keep per session. +7. **Should font size be global, per-instance, or per-session?** Recommend global for MVP. +8. **Copy/paste on desktop — any gaps?** Current desktop relies on native xterm.js copy/paste (`Ctrl+C`/`Ctrl+V` with selection). This is standard and sufficient. Mobile already has buttons. + +## Risks and Feasibility Assessment + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| Resource exhaustion from too many docker exec processes | Medium | High | Enforce max sessions per instance (5). Idle timeout already exists. | +| Mobile UX degradation from tab bar clutter | Medium | Medium | Integrate tabs into existing `MobileTerminalHeader` auto-hide. Limit visible tabs, overflow scroll. | +| Backward compat breakage from URL change | Low | Medium | Keep `/terminal` as default-session alias. | +| Concurrent WebSocket policy bugs | Medium | High | Ensure "close existing" only applies within same `(instance_id, session_id)`, not across sessions. | +| Scope creep (panes, detachable windows) | High | Medium | Explicitly exclude split panes and detachable windows from MVP. | + +## Feasibility: Green/Yellow/Red + +**Yellow-Green**. The backend changes are well-scoped and build on solid existing infrastructure. The frontend tab UI is the largest unknown, especially mobile integration, but the existing `MobileTerminalWrapper` provides a good foundation. No external dependencies needed. + +## Recommended Next Step + +**Proceed to `design` phase** after resolving these scoping decisions: +1. Choose Option A or C for session storage (recommend Option C). +2. Confirm max sessions limit (recommend 5). +3. Confirm tab-only UI for MVP (no panes). +4. Confirm backward-compatible WebSocket URL strategy. + +Then write `design.md` with concrete decisions and `tasks.md` with implementation steps. diff --git a/openspec/changes/multi-session-terminal-ux/proposal.md b/openspec/changes/multi-session-terminal-ux/proposal.md new file mode 100644 index 0000000..53e69f9 --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/proposal.md @@ -0,0 +1,33 @@ +## Why + +Currently, each tool instance (e.g., pi-agent, code-server) supports exactly one terminal session. Users who want to run multiple concurrent tasks (e.g., a long-running build in one pane, an editor in another, and a shell for quick commands) must open multiple tool instances or use tmux/screen inside a single session. This is inefficient and confusing. + +Additionally, the web terminal lacks basic usability features found in modern terminal emulators: fullscreen mode, detachable panes, session tabs, and keyboard shortcuts for common actions. + +## What Changes + +- **Backend**: Allow multiple `TerminalSession` objects per `ToolInstance`, each with a unique `session_id` +- **Backend**: Update `TerminalManager` to track and route multiple sessions per instance +- **Backend**: Update terminal WebSocket protocol to include `session_id` in connection URL or message +- **Frontend**: Add session tabs/management UI (create new session, switch between sessions, close sessions) +- **Frontend**: Add fullscreen mode for the terminal +- **Frontend**: Add keyboard shortcuts for session management (Ctrl+Shift+N new session, etc.) +- **Frontend**: Session list panel showing active sessions per instance + +## Capabilities + +### New Capabilities +- `multi-session-terminal`: Multiple independent terminal sessions per tool instance +- `terminal-fullscreen`: Fullscreen terminal mode +- `terminal-session-management`: Create, switch, rename, and close terminal sessions + +### Modified Capabilities +- `tool-terminal`: Extend WebSocket protocol and UI to support multiple sessions per instance +- `terminal-session-lifecycle`: Session creation, naming, and cleanup for multi-session model + +## Impact + +- Backend: `TerminalManager`, `TerminalSession`, `api/terminal.py`, database schema (session tracking) +- Frontend: `TerminalComponent`, `terminal.tsx`, new `TerminalSessionTabs`, `TerminalSessionManager` +- Protocol: WebSocket message format changes (add session_id field) +- Database: New or extended table to track terminal sessions per instance diff --git a/openspec/changes/multi-session-terminal-ux/tasks.md b/openspec/changes/multi-session-terminal-ux/tasks.md new file mode 100644 index 0000000..e3aad3c --- /dev/null +++ b/openspec/changes/multi-session-terminal-ux/tasks.md @@ -0,0 +1,404 @@ +# SDD Tasks: Multi-Session Terminal UX + +## Review Workload Forecast + +| Field | Value | +|-------|-------| +| Estimated changed lines | ~1,400–1,600 (new ~900, modified ~600–700) | +| 400-line budget risk | High | +| Chained PRs recommended | Yes | +| Suggested split | PR 1: DB + Backend Core → PR 2: Backend API + Tests → PR 3: Frontend + Tests | +| Delivery strategy | auto-chain | +| Chain strategy | stacked-to-main | + +```text +Decision needed before apply: Yes +Chained PRs recommended: Yes +Chain strategy: stacked-to-main +400-line budget risk: High +``` + +--- + +## Task Overview + +| # | Task | PR | Est. Lines | Dependencies | +|---|------|-----|------------|--------------| +| 1 | Database schema and Alembic migration | 1 | ~80 | None | +| 2 | TerminalManager multi-session core | 1 | ~250 | Task 1 | +| 3 | TerminalSession name and status fields | 1 | ~40 | Task 2 | +| 4 | WebSocket routing and backward-compat alias | 2 | ~200 | Task 2 | +| 5 | REST endpoints for session CRUD | 2 | ~180 | Task 2, 4 | +| 6 | Frontend API client and `useTerminalSessions` hook | 3 | ~180 | Task 5 | +| 7 | `TerminalComponent` `sessionId` support | 3 | ~100 | Task 4, 6 | +| 8 | `TerminalSessionTabs` UI component | 3 | ~220 | Task 6 | +| 9 | `TerminalPage` multi-session orchestration and fullscreen | 3 | ~200 | Task 7, 8 | +| 10 | Mobile terminal integration | 3 | ~100 | Task 8, 9 | +| 11 | Backend integration tests | 2 | ~250 | Task 4, 5 | +| 12 | Frontend component tests | 3 | ~150 | Task 8, 9, 10 | + +--- + +## PR 1: Database + Backend Core + +### Task 1: Database Schema and Alembic Migration + +**Scope**: Create the `terminal_sessions` metadata table and corresponding Alembic migration. + +**Files to create**: +- `apps/api/src/models/terminal_session.py` +- `apps/api/alembic/versions/XXXX_add_terminal_sessions_table.py` + +**Files to modify**: +- `apps/api/src/main.py` — import new model so Alembic autogenerate discovers it + +**Acceptance Criteria**: +- `TerminalSessionModel` extends `Base`, `UUIDPrimaryKeyMixin`, `TimestampMixin` +- Columns: `instance_id` (UUID, FK `tool_instances.id` ON DELETE CASCADE, indexed), `name` (String 255, nullable), `status` (String 50, default `"active"`), `created_at` (DateTime TZ, non-nullable), `last_activity_at` (DateTime TZ, nullable), `closed_at` (DateTime TZ, nullable) +- Migration is reversible (`downgrade` drops table + index) +- `make migrate` applies successfully in local dev + +**Testing (TDD)**: +- RED: Write a migration metadata test asserting the new table exists in `Base.metadata` and has expected columns +- GREEN: Create model and migration +- Run `pytest tests/integration/test_models.py` or equivalent to verify table registration + +--- + +### Task 2: TerminalManager Multi-Session Core + +**Scope**: Refactor `TerminalManager` to support up to 5 concurrent sessions per instance using composite keys. + +**Files to modify**: +- `apps/api/src/services/terminal_manager.py` + +**Acceptance Criteria**: +- `self._sessions` keyed by `(instance_id: str, session_id: str)` +- `create_session(instance_id, container_id, startup_command=None, name=None)`: + - Generates UUID `session_id` + - Enforces max 5 active sessions per instance (raise `MaxSessionsExceededError` / HTTP 409) + - Inserts `TerminalSessionModel` DB row (fire-and-forget async task acceptable) + - Returns `TerminalSession` +- `get_or_create_session(instance_id, container_id, ...)` preserved for backward compatibility; uses `"default"` session_id +- `get_session(instance_id, session_id)` returns session or `None` +- `get_sessions_for_instance(instance_id)` returns list of in-memory sessions +- `close_session(instance_id, session_id)`: kills PTY, removes from `_sessions`, updates DB `status=closed`, `closed_at=now()` +- `reset_session(instance_id, container_id, session_id=None)`: if `session_id` omitted, resets `"default"` session +- `attach_websocket` only closes existing WebSockets **within the same `(instance_id, session_id)`** +- `_cleanup_idle_sessions` uses composite keys and updates DB status on cleanup +- Idle timeout (30 min) and buffer replay behavior preserved + +**Testing (TDD)**: +- RED: Create `apps/api/tests/services/test_terminal_manager_multi.py` with tests: + - `test_create_session_increases_count` + - `test_create_session_enforces_max_5` + - `test_get_sessions_for_instance_filters_by_instance` + - `test_close_session_removes_from_dict_and_updates_db` + - `test_attach_websocket_only_closes_same_session` + - `test_default_session_keyed_separately` + - `test_idle_cleanup_updates_db_status` +- GREEN: Implement `TerminalManager` changes +- Run `make test-unit` + +--- + +### Task 3: TerminalSession Name and Status Fields + +**Scope**: Add runtime `name` and `status` tracking to `TerminalSession`. + +**Files to modify**: +- `apps/api/src/services/terminal_session.py` + +**Acceptance Criteria**: +- `__init__` accepts optional `name`; auto-generates `"Session N"` if omitted (N = per-instance counter) +- `self.name` stored as runtime attribute +- `self.status` enum-like string: `"active"`, `"resetting"`, `"closed"` +- `reset()` sets `status="resetting"` during transition, `"active"` after restart +- `close()` sets `status="closed"` +- No breaking changes to existing `TerminalSession` behavior + +**Testing (TDD)**: +- RED: Extend `test_terminal_manager_multi.py` or add `test_terminal_session_name_and_status.py` covering auto-naming, status transitions, and reset/close side effects +- GREEN: Implement fields and transitions +- Run `make test-unit` + +--- + +## PR 2: Backend API + Tests + +### Task 4: WebSocket Routing and Backward-Compat Alias + +**Scope**: Add session-scoped WebSocket route, extract shared handler, preserve legacy alias. + +**Files to modify**: +- `apps/api/src/api/terminal.py` + +**Files to create**: +- `apps/api/tests/api/test_terminal_ws_multi.py` + +**Acceptance Criteria**: +- New route: `@router.websocket("/ws/tool-instances/{instance_id}/terminal/{session_id}")` +- Existing route `@router.websocket("/ws/tool-instances/{instance_id}/terminal")` preserved; calls `get_or_create_session(...)` for `"default"` session +- Extract `async def _handle_terminal_websocket(websocket, instance_id, session_id, db_session)` containing shared auth/validation/I/O loop logic +- Both routes call `_handle_terminal_websocket` +- Auth/validation logic unchanged (cookie-based, ownership check, running status) +- `reset` control message scoped to the current session only (via `SessionRef` update) +- On unknown `session_id`, close WS with code `4004` "Session not found" + +**Testing (TDD)**: +- RED: Write `test_terminal_ws_multi.py`: + - `test_specific_session_websocket_connects` + - `test_default_session_alias_creates_default` + - `test_concurrent_sessions_isolated_output` + - `test_reset_control_message_scoped_to_session` + - `test_unknown_session_id_returns_4004` +- GREEN: Implement routes and shared handler +- Run `pytest tests/api/test_terminal_ws_multi.py` + +--- + +### Task 5: REST Endpoints for Session CRUD + +**Scope**: Add REST endpoints for listing, creating, closing, resetting, and renaming sessions. + +**Files to modify**: +- `apps/api/src/api/terminal.py` + +**Acceptance Criteria**: +- `GET /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/sessions` + - Returns `{ sessions: [...] }` with `id`, `name`, `status`, `has_websockets`, `created_at`, `last_activity_at` + - `has_websockets` queried live from `TerminalManager` +- `POST .../terminal/sessions` — body `{ name?: string }` + - Returns `201` with `{ id, name, status, created_at }` + - Returns `409` if max 5 reached +- `DELETE .../terminal/sessions/{sid}` — returns `{ status: "closed", session_id }` +- `POST .../terminal/sessions/{sid}/reset` — returns `{ id, name, status }` +- `POST .../terminal/sessions/{sid}/rename` — body `{ name: string }`, returns `{ id, name }` +- Existing `POST .../terminal/reset` preserved as alias for default session reset +- All endpoints validate auth, ownership, and running instance status + +**Testing (TDD)**: +- RED: Add integration tests in `test_terminal_ws_multi.py` or new `test_terminal_rest.py`: + - `test_list_sessions_returns_db_and_live_state` + - `test_create_session_201` + - `test_create_session_409_at_max` + - `test_close_session_200` + - `test_reset_session_200` + - `test_rename_session_200` + - `test_legacy_reset_alias_still_works` +- GREEN: Implement endpoints +- Run `make test-integration` + +--- + +### Task 6: Frontend API Client and `useTerminalSessions` Hook + +**Scope**: Add frontend REST client functions and the central session state hook. + +**Files to create**: +- `apps/web/src/api/terminal.ts` (new file for terminal-specific API calls) +- `apps/web/src/hooks/use-terminal-sessions.ts` + +**Files to modify**: +- `apps/web/src/api/sessions.ts` — optional, or keep terminal API separate + +**Acceptance Criteria**: +- API functions: `listTerminalSessions`, `createTerminalSession`, `closeTerminalSession`, `resetTerminalSession`, `renameTerminalSession` +- `useTerminalSessions(instanceId: string)` hook: + - Loads sessions on mount; auto-creates one if list is empty + - Exposes `sessions`, `activeSessionId`, `setActiveSessionId` + - Exposes `createSession`, `closeSession`, `renameSession`, `resetSession` with optimistic UI updates + - Handles 409 errors (max sessions) gracefully + - Refetches after reset/rename to stay in sync + +**Testing (TDD)**: +- RED: Write hook unit tests mocking API client: + - `test_loads_sessions_on_mount` + - `test_auto_creates_session_if_empty` + - `test_close_session_removes_from_state` + - `test_create_session_enforces_max_5_error` +- GREEN: Implement hook and API client +- Run `cd apps/web && npm test` + +--- + +## PR 3: Frontend + Tests + +### Task 7: `TerminalComponent` `sessionId` Support + +**Scope**: Update `TerminalComponent` to accept an optional `sessionId` and route WS accordingly. + +**Files to modify**: +- `apps/web/src/components/terminal.tsx` + +**Acceptance Criteria**: +- New optional prop `sessionId?: string` +- WS URL constructed as: + - `/ws/tool-instances/{instanceId}/terminal/{sessionId}` if `sessionId` provided + - `/ws/tool-instances/{instanceId}/terminal` if omitted (backward compat) +- Reset button sends `{"type": "reset"}` to the correct session's WS +- Component still supports all existing props and mobile behavior +- `onTerminalReady` callback still works; parent can differentiate sessions by key + +**Testing (TDD)**: +- RED: Add/update `terminal.test.tsx` (or similar) to assert WS URL includes `sessionId` when provided +- GREEN: Implement prop and URL logic +- Run `cd apps/web && npm test` + +--- + +### Task 8: `TerminalSessionTabs` UI Component + +**Scope**: Build the tab bar for desktop and mobile. + +**Files to create**: +- `apps/web/src/components/terminal-session-tabs.tsx` +- `apps/web/src/components/terminal-session-tabs.test.tsx` + +**Acceptance Criteria**: +- Props interface: `sessions`, `activeSessionId`, `onSelect`, `onClose`, `onCreate`, `onRename`, `isMobile?` +- Desktop: horizontal tab strip above terminal, overflow scroll with fade indicator +- Mobile: compact tabs integrated into auto-hide chrome, horizontal swipe scroll +- Each tab shows: name, status dot (connecting/connected/disconnected/error), close button (×) on hover/active +- Double-click to rename: inline ``, `Enter` to confirm, `Escape` to cancel, blur confirms +- New session button (+) at right end; disabled when 5 sessions exist +- Close confirmation: lightweight inline confirm tooltip (not modal) +- Accessible: `role="tablist"`, `role="tab"`, keyboard navigation + +**Testing (TDD)**: +- RED: Write `terminal-session-tabs.test.tsx`: + - `test_renders_all_tabs` + - `test_click_tab_calls_onSelect` + - `test_close_button_calls_onClose` + - `test_double_click_enables_rename` + - `test_plus_disabled_at_max_sessions` + - `test_status_dot_reflects_connection_state` +- GREEN: Implement component +- Run `cd apps/web && npm test` + +--- + +### Task 9: `TerminalPage` Multi-Session Orchestration, Fullscreen, and Shortcuts + +**Scope**: Rewrite `TerminalPage` to manage multiple mounted terminals, fullscreen mode, and keyboard shortcuts. + +**Files to modify**: +- `apps/web/src/pages/terminal.tsx` + +**Acceptance Criteria**: +- Uses `useTerminalSessions` hook +- Renders `` above terminal area +- Renders one `` per session; inactive sessions hidden via `display: none` (preserves scrollback and WS) +- On tab switch, active terminal calls `fitAddon.fit()` via ref + `useEffect` on visibility +- Fullscreen toggle: + - `Ctrl+Shift+F` toggles `.fullscreen` class + - Desktop: hides page header; tab strip becomes minimal overlay (auto-hides after 3s, reappears on mouse move) + - Mobile: hides header, tab strip, special keys; floating handle reveals chrome + - Exit via `Esc` or UI button +- Keyboard shortcuts (registered in `useEffect` on `keydown`): + - `Alt+Shift+N` — new session + - `Alt+Shift+W` — close current session + - `Alt+Shift+←` / `Alt+Shift+→` — prev/next session + - `Alt+Shift+R` — reset current session + - All use `preventDefault()` only for the exact combo; no browser overrides +- Closing last session auto-creates a new default session + +**Testing (TDD)**: +- RED: Add `terminal-page.test.tsx`: + - `test_creates_default_session_on_empty_load` + - `test_switching_tabs_hides_inactive_terminals` + - `test_fullscreen_toggle_adds_class` + - `test_keyboard_shortcut_creates_session` + - `test_close_last_session_auto_creates_default` +- GREEN: Implement page orchestration +- Run `cd apps/web && npm test` + +--- + +### Task 10: Mobile Terminal Integration + +**Scope**: Integrate session tabs into mobile terminal wrapper and update header. + +**Files to modify**: +- `apps/web/src/components/mobile-terminal-wrapper.tsx` +- `apps/web/src/components/mobile-terminal-header.tsx` + +**Acceptance Criteria**: +- `MobileTerminalWrapper` accepts session-related props from `TerminalPage` and passes them to `TerminalSessionTabs` +- `MobileTerminalHeader` displays `activeSession.name` instead of generic `"Terminal"` +- Tab strip shares `useAutoHide` behavior with header (tapping terminal toggles visibility) +- Special keys strip remains functional; no z-index conflicts with tabs +- Fullscreen on mobile correctly hides/shows all chrome layers + +**Testing (TDD)**: +- RED: Add/update mobile wrapper tests: + - `test_renders_session_tabs` + - `test_header_shows_session_name` + - `test_auto_hide_applies_to_tabs` +- GREEN: Implement mobile integration +- Run `cd apps/web && npm test` + +--- + +### Task 11: Backend Integration Tests + +**Scope**: Complete backend test coverage for multi-session WebSocket and REST behavior. + +**Files to create / modify**: +- `apps/api/tests/services/test_terminal_manager_multi.py` (finalize) +- `apps/api/tests/api/test_terminal_ws_multi.py` (finalize) + +**Acceptance Criteria**: +- All tests from Tasks 2, 4, 5 pass +- Additional integration tests: + - `test_list_sessions_after_api_restart_shows_db_metadata` (simulates restart by clearing in-memory dict) + - `test_two_websockets_on_same_session_receive_same_output` + - `test_idle_cleanup_per_session_not_global` +- `make test` passes (unit + integration) + +**Testing (TDD)**: +- These are the GREEN/TRIANGULATE phases for earlier backend tasks; ensure coverage is comprehensive + +--- + +### Task 12: Frontend Component Tests + +**Scope**: Finalize frontend test coverage for tabs, page, and hook. + +**Files to create / modify**: +- `apps/web/src/components/terminal-session-tabs.test.tsx` (finalize) +- `apps/web/src/hooks/use-terminal-sessions.test.ts` (new, if not created earlier) +- `apps/web/src/pages/terminal.test.tsx` (new) + +**Acceptance Criteria**: +- Tab component tests cover rendering, selection, close, rename, and max-session disable +- Hook tests cover load, create, close, error handling +- Page tests cover session lifecycle, fullscreen, and keyboard shortcuts +- `cd apps/web && npm test` passes + +**Testing (TDD)**: +- Finalize RED→GREEN→TRIANGULATE for all frontend tasks + +--- + +## Risks and Mitigations + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| Resource exhaustion (5× docker exec per instance) | Medium | High | Max 5 enforced in `create_session`. Idle timeout (30 min) applies per session. | +| Mobile UX degraded by tab bar + special keys strip | Medium | Medium | Auto-hide shared between tabs and header. Compact tab design. Overflow scroll. | +| Concurrent WS policy closes wrong session's sockets | Medium | High | Explicit unit test: `attach_websocket` must only affect same `(instance_id, session_id)`. | +| DB writes on hot path (activity tracking) | Low | Medium | `last_activity_at` updates are fire-and-forget async tasks; do not block I/O loop. | +| Frontend performance with 5 mounted xterm.js instances | Low | Medium | Max 5 sessions. Inactive terminals use `display: none` (not unmounted). xterm.js GPU acceleration handles this. | +| Default session alias ambiguity | Low | Low | Document that `/terminal` maps to `"default"`. Future deprecation can migrate to explicit IDs. | +| Browser shortcut conflicts | Low | Medium | Use `Alt+Shift+*` instead of `Ctrl+Shift+W/N`. Only `preventDefault()` on exact matching combos. | + +--- + +## Rollback Plan + +- **PR 1 rollback**: Alembic downgrade removes `terminal_sessions` table. Old `TerminalManager` code is fully replaced, so reverting PR 1 requires reverting all subsequent PRs. +- **PR 2 rollback**: Revert API changes. Legacy `/terminal` WS route and `POST .../terminal/reset` continue to work; new `/terminal/{session_id}` returns 404 but no clients call it until PR 3 is deployed. +- **PR 3 rollback**: Revert frontend. Users see old single-session UI. Backend `/terminal` alias continues to serve them. + +Because PRs are stacked, rolling back PR 2 or PR 1 requires rolling back all dependent PRs above it. diff --git a/scripts/fix_ghost_migration.sh b/scripts/fix_ghost_migration.sh new file mode 100644 index 0000000..51b6361 --- /dev/null +++ b/scripts/fix_ghost_migration.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Fix ghost migration on production server +# Run this INSIDE the api container or on the server + +echo "=== Checking for ghost migration file ===" +find /app/alembic/versions -name "*tool_definition*" 2>/dev/null + +echo "" +echo "=== Current alembic_version in DB ===" +psql "$DATABASE_URL" -c "SELECT * FROM alembic_version;" + +echo "" +echo "=== Checking if tool_types has definition_manifests column ===" +psql "$DATABASE_URL" -c "\d tool_types" | grep -i manifest + +echo "" +echo "=== Our known migration heads ===" +grep -r "revision.*=" /app/alembic/versions/*.py | grep "2026_05_28" diff --git a/scripts/update_db_password.py b/scripts/update_db_password.py new file mode 100644 index 0000000..f0fef34 --- /dev/null +++ b/scripts/update_db_password.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Securely update the PostgreSQL password for the headquarter database user. + +Usage: + python scripts/update_db_password.py + +The script will prompt for the new password (no echo) and update it via the +running hq-postgres Docker container. + +After running, remember to update your .env file: + POSTGRES_PASSWORD= +""" + +import getpass +import subprocess +import sys + + +def main() -> None: + # Prompt for new password securely (no echo to terminal) + new_password = getpass.getpass("Enter new password for 'headquarter' user: ") + if not new_password: + print("Error: password cannot be empty.", file=sys.stderr) + sys.exit(1) + + confirm = getpass.getpass("Confirm new password: ") + if new_password != confirm: + print("Error: passwords do not match.", file=sys.stderr) + sys.exit(1) + + # Use psql inside the running postgres container to avoid exposing + # the password in host shell history. + sql = f"ALTER ROLE headquarter WITH PASSWORD '{new_password}';" + + try: + result = subprocess.run( + [ + "docker", + "exec", + "-i", + "hq-postgres", + "psql", + "-U", + "headquarter", + "-d", + "headquarter", + "-c", + sql, + ], + capture_output=True, + text=True, + check=True, + ) + print(result.stdout.strip()) + print("\n✅ Password updated successfully.") + print("\n⚠️ IMPORTANT: Update your .env file:") + print(f" POSTGRES_PASSWORD={new_password}") + print("\n⚠️ Then restart the application containers:") + print(" docker compose up -d") + except subprocess.CalledProcessError as exc: + print(f"Error: {exc.stderr or exc.stdout}", file=sys.stderr) + sys.exit(1) + except FileNotFoundError: + print( + "Error: 'docker' command not found. Is Docker installed and running?", + file=sys.stderr, + ) + sys.exit(1) + + +if __name__ == "__main__": + main()