fix: clipboard copy in dialog + CLI --help handling#209
Conversation
The legacy execCommand fallback failed inside Radix Dialog because: 1. textarea.focus() was missing before textarea.select() 2. off-screen positioning (left:-9999px) prevented focus in some browsers Also skip Clipboard API entirely on non-secure contexts (HTTP) via window.isSecureContext check instead of catching the DOMException.
Previously running `engram --help` or `engram -h` fell through to startupGate() which exits with FATAL if ENGRAM_TOKEN is unset. Now prints version, purpose, and env var reference.
ОбзорДобавлена ранняя проверка аргументов командной строки в точку входа приложения для вывода справки и версии перед инициализацией. Модифицирован механизм копирования в буфер обмена для требования безопасного контекста и улучшены операции со скрытым текстовым полем. Изменения
Оценка сложности проверки кода🎯 1 (Тривиальное) | ⏱️ ~5 минут Стихотворение
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.11.4)Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces basic command-line flag handling for the engram daemon and improves the clipboard utility's reliability and security. The clipboard utility now checks for a secure context before using the modern API and includes a more robust legacy fallback. Feedback was provided regarding the CLI flags, suggesting that the --version flag should output only the version string to support programmatic usage and that a switch statement would improve the code's maintainability.
| if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h" || os.Args[1] == "--version" || os.Args[1] == "-v") { | ||
| fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion) | ||
| fmt.Println() | ||
| fmt.Println("This binary is invoked automatically by the engram plugin.") | ||
| fmt.Println("It is not intended to be run directly.") | ||
| fmt.Println() | ||
| fmt.Println("Environment:") | ||
| fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL) | ||
| fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken) | ||
| os.Exit(0) | ||
| } |
There was a problem hiding this comment.
The implementation currently returns the full help text for both --help and --version flags. It is standard practice for --version to only output the version string, which facilitates programmatic usage (e.g., version checks in scripts). Using a switch statement also improves readability and makes it easier to add more flags in the future.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ui/src/utils/clipboard.ts (1)
11-22:⚠️ Potential issue | 🟡 MinorСделайте очистку
textareaгарантированной черезfinally.Если исключение произойдёт после
appendChild, текущийremoveChildне выполнится и скрытый элемент останется в DOM.Предлагаемое исправление
export async function copyToClipboard(text: string): Promise<boolean> { if (window.isSecureContext && navigator.clipboard?.writeText) { @@ - try { - const textarea = document.createElement('textarea') + const textarea = document.createElement('textarea') + try { textarea.value = text textarea.setAttribute('readonly', '') textarea.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;padding:0;border:none;outline:none;opacity:0;' document.body.appendChild(textarea) textarea.focus() textarea.select() - const success = document.execCommand('copy') - document.body.removeChild(textarea) - return success + return document.execCommand('copy') } catch { return false + } finally { + textarea.remove() } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ui/src/utils/clipboard.ts` around lines 11 - 22, The hidden textarea created in the copy routine can remain in the DOM if an exception occurs after document.body.appendChild(textarea); update the copy logic (the block that creates textarea, sets value/attributes, calls textarea.select() and document.execCommand('copy')) to ensure document.body.removeChild(textarea) is executed in a finally block and that a default return value (e.g., false) is used if an exception occurs; reference the textarea variable and the document.execCommand('copy') call so you move removeChild into finally and preserve/return the copy success state safely.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/engram/main.go`:
- Around line 67-77: Split the combined help/version branch so that when
os.Args[1] is "--version" or "-v" the program prints just the version
(daemonVersion) and exits, and only when os.Args[1] is "--help" or "-h" it
prints the full help text; update the conditional around os.Args handling in
main (the block that currently checks os.Args[1] for "--help" || "-h" ||
"--version" || "-v") to check version flags first and call fmt.Printf("%s\n",
daemonVersion) (or similar) then os.Exit(0), otherwise fall through to the
existing help-printing code that references config.EnvServerURL and
config.EnvWorkstationToken.
---
Outside diff comments:
In `@ui/src/utils/clipboard.ts`:
- Around line 11-22: The hidden textarea created in the copy routine can remain
in the DOM if an exception occurs after document.body.appendChild(textarea);
update the copy logic (the block that creates textarea, sets value/attributes,
calls textarea.select() and document.execCommand('copy')) to ensure
document.body.removeChild(textarea) is executed in a finally block and that a
default return value (e.g., false) is used if an exception occurs; reference the
textarea variable and the document.execCommand('copy') call so you move
removeChild into finally and preserve/return the copy success state safely.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 64c25cab-086b-4812-8c6f-619085e3a95b
📒 Files selected for processing (2)
cmd/engram/main.goui/src/utils/clipboard.ts
| if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h" || os.Args[1] == "--version" || os.Args[1] == "-v") { | ||
| fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion) | ||
| fmt.Println() | ||
| fmt.Println("This binary is invoked automatically by the engram plugin.") | ||
| fmt.Println("It is not intended to be run directly.") | ||
| fmt.Println() | ||
| fmt.Println("Environment:") | ||
| fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL) | ||
| fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken) | ||
| os.Exit(0) | ||
| } |
There was a problem hiding this comment.
--version сейчас выводит help-текст вместо только версии.
На Line 67-77 --help и --version объединены в одну ветку, поэтому engram --version печатает длинный справочный вывод. Это ломает ожидаемый формат для скриптов и расходится с целевым поведением PR.
Предлагаемое исправление
- if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h" || os.Args[1] == "--version" || os.Args[1] == "-v") {
- fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion)
- fmt.Println()
- fmt.Println("This binary is invoked automatically by the engram plugin.")
- fmt.Println("It is not intended to be run directly.")
- fmt.Println()
- fmt.Println("Environment:")
- fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL)
- fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken)
- os.Exit(0)
- }
+ if len(os.Args) > 1 {
+ switch os.Args[1] {
+ case "--version", "-v":
+ fmt.Printf("engram %s\n", daemonVersion)
+ os.Exit(0)
+ case "--help", "-h":
+ fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion)
+ fmt.Println()
+ fmt.Println("This binary is invoked automatically by the engram plugin.")
+ fmt.Println("It is not intended to be run directly.")
+ fmt.Println()
+ fmt.Println("Environment:")
+ fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL)
+ fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken)
+ os.Exit(0)
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h" || os.Args[1] == "--version" || os.Args[1] == "-v") { | |
| fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion) | |
| fmt.Println() | |
| fmt.Println("This binary is invoked automatically by the engram plugin.") | |
| fmt.Println("It is not intended to be run directly.") | |
| fmt.Println() | |
| fmt.Println("Environment:") | |
| fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL) | |
| fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken) | |
| os.Exit(0) | |
| } | |
| if len(os.Args) > 1 { | |
| switch os.Args[1] { | |
| case "--version", "-v": | |
| fmt.Printf("engram %s\n", daemonVersion) | |
| os.Exit(0) | |
| case "--help", "-h": | |
| fmt.Printf("engram %s — stdio MCP daemon for Claude Code\n", daemonVersion) | |
| fmt.Println() | |
| fmt.Println("This binary is invoked automatically by the engram plugin.") | |
| fmt.Println("It is not intended to be run directly.") | |
| fmt.Println() | |
| fmt.Println("Environment:") | |
| fmt.Printf(" %-28s Server URL (e.g. http://host:37777)\n", config.EnvServerURL) | |
| fmt.Printf(" %-28s Workstation keycard (issued via dashboard /tokens)\n", config.EnvWorkstationToken) | |
| os.Exit(0) | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@cmd/engram/main.go` around lines 67 - 77, Split the combined help/version
branch so that when os.Args[1] is "--version" or "-v" the program prints just
the version (daemonVersion) and exits, and only when os.Args[1] is "--help" or
"-h" it prints the full help text; update the conditional around os.Args
handling in main (the block that currently checks os.Args[1] for "--help" ||
"-h" || "--version" || "-v") to check version flags first and call
fmt.Printf("%s\n", daemonVersion) (or similar) then os.Exit(0), otherwise fall
through to the existing help-printing code that references config.EnvServerURL
and config.EnvWorkstationToken.
Summary
Two v6 follow-up fixes in one PR:
1. Fix clipboard copy in TokenCreated dialog (closes #167 via engram issue tracker)
The "Copy" button in the token creation modal silently failed on HTTP sites
(e.g.
http://host:37777). Root cause:navigator.clipboard.writeText()requires a secure context (HTTPS/localhost)execCommand('copy')fallback was missingtextarea.focus()beforetextarea.select()— Radix Dialog's focus trap prevented the textarea fromreceiving focus
left:-9999px) caused some browsers to skip the elementFix: Skip Clipboard API on non-secure contexts via
window.isSecureContext,add
textarea.focus(), use in-viewport transparent positioning.2. Handle
--help/--versionCLI flagsPreviously
engram --helpfell through tostartupGate()which exits withFATAL: ENGRAM_TOKEN is emptyif the token isn't configured. Now printsversion, purpose, and env var reference.
Testing
engram --helpprints usage,engram --versionprints versiongo build ./cmd/engram/— cleanSummary by CodeRabbit
Новые функции
--helpи--versionдля быстрого получения информации о приложении и выхода перед инициализацией.Исправления ошибок