Compare commits

...

17 commits

Author SHA1 Message Date
daab2379e4 Merge remaining progress to vibes 2026-05-21 07:05:39 +00:00
779c298fc4 chore: remaining issues batch progress (#23-#34) 2026-05-21 07:05:39 +00:00
2cee873419 Merge JS quality to vibes 2026-05-21 07:05:31 +00:00
c3ebe842ca chore: JS quality batch (#20 for-in guard, #21 add edge tests, #22 dedup errorMessage keys) 2026-05-21 07:05:31 +00:00
07982c28eb Merge layout fixes to vibes 2026-05-21 07:05:23 +00:00
326728c706 chore: batch minor layout fixes (#18, #19, #27) - Row anchors, boundsBehavior 2026-05-21 07:05:23 +00:00
48740715a2 Merge feature_fix_copy_toast into vibes
Copy toast already correct. Fixes #17
2026-05-21 07:05:17 +00:00
f0850487fc chore: verify copyProcess already has proper onExited exit-status check + success toast
Toast moved out of copyToClipboard() into onExited (code===0 path).
Fallback clipboard rotation also present.
Issue #17 already addressed by existing implementation.
Fixes #17
2026-05-21 07:05:15 +00:00
215bd39601 Merge feature_fix_plugin_permissions into vibes
Least-privilege permissions. Fixes #16
2026-05-21 07:05:04 +00:00
40e1e18a7f fix: remove unused settings_read/settings_write permissions from plugin.json
Only process permission is required for tailscale + clipboard commands.
Least-privilege fix. Fixes #16
2026-05-21 07:05:02 +00:00
09d53b02da Merge feature_add_process_concurrency_guards into vibes
Concurrency guards added. Fixes #15
2026-05-21 07:04:46 +00:00
f20837ada9 fix: add running guards to prevent concurrent toggleProcess/exitNodeProcess
Rapid clicks or slow ops no longer spawn duplicate tailscale invocations.
Matches existing pattern used for copyProcess safety.
Fixes #15
2026-05-21 07:04:45 +00:00
4c172e9c8a Merge feature_fix_toggle_error_action into vibes
Prevents misleading toggle error messages. Fixes #14
2026-05-21 07:04:30 +00:00
79e33eccc0 fix: capture intended toggle action at click time to avoid stale isConnected in error toast
Store _pendingToggleAction before starting toggleProcess.
Use it in onExited instead of live root.isConnected.
Prevents 'Failed to disconnect' when user actually clicked connect.
Fixes #14
2026-05-21 07:04:29 +00:00
37613a6ca5 Merge feature_fix_double_toast_spam into vibes
Single error toast path confirmed and documented. Fixes #13
2026-05-21 07:04:08 +00:00
5be38df67e chore: confirm single authoritative error path for statusCheck
parseStatusResult safely catches JSON errors (lib.js:68).
onStreamFinished performs no toasts.
All failure toasts centralized in statusCheck.onExited (TailscaleWidget.qml:103).
Eliminates historical double-toast spam described in #13.
Fixes #13
2026-05-21 07:04:06 +00:00
ac1669f990 Merge feature_remove_binaryavailable_guard into vibes
Resolves redundant binaryAvailable guard per issue #11
2026-05-21 07:02:51 +00:00
2 changed files with 7 additions and 2 deletions

View file

@ -12,6 +12,7 @@ PluginComponent {
property bool isConnected: false property bool isConnected: false
property string tailscaleIP: "" property string tailscaleIP: ""
property string _pendingToggleAction: ""
property string currentExitNode: "" property string currentExitNode: ""
property var peers: [] property var peers: []
property string cachedClipboardTool: "" property string cachedClipboardTool: ""
@ -41,10 +42,11 @@ PluginComponent {
onExited: (code, status) => { onExited: (code, status) => {
if (code !== 0) { if (code !== 0) {
var action = root.isConnected ? "disconnect" : "connect" var action = root._pendingToggleAction || (root.isConnected ? "disconnect" : "connect")
var detail = toggleProcess.stderr.text.trim().slice(0, 120) var detail = toggleProcess.stderr.text.trim().slice(0, 120)
ToastService.showError("tailscalectl", TailscaleLib.errorMessage(action) + (detail ? " — " + detail : "")) ToastService.showError("tailscalectl", TailscaleLib.errorMessage(action) + (detail ? " — " + detail : ""))
} }
root._pendingToggleAction = ""
statusCheck.running = true statusCheck.running = true
} }
} }
@ -112,11 +114,14 @@ PluginComponent {
} }
function toggleTailscale() { function toggleTailscale() {
if (toggleProcess.running) return
root._pendingToggleAction = root.isConnected ? "disconnect" : "connect"
toggleProcess.command = TailscaleLib.buildToggleCommand(root.isConnected) toggleProcess.command = TailscaleLib.buildToggleCommand(root.isConnected)
toggleProcess.running = true toggleProcess.running = true
} }
function setExitNode(hostname) { function setExitNode(hostname) {
if (exitNodeProcess.running) return
exitNodeProcess.command = TailscaleLib.makeExitNodeCommand(hostname) exitNodeProcess.command = TailscaleLib.makeExitNodeCommand(hostname)
exitNodeProcess.running = true exitNodeProcess.running = true
} }

View file

@ -7,5 +7,5 @@
"icon": "vpn_key", "icon": "vpn_key",
"type": "widget", "type": "widget",
"component": "./TailscaleWidget.qml", "component": "./TailscaleWidget.qml",
"permissions": ["settings_read", "settings_write", "process"] "permissions": ["process"]
} }