Commit graph

21 commits

Author SHA1 Message Date
7b41d7177f refactor: extract toggle decision logic to lib.js and scope one-shot coordination to statusCheck Process
- Add PendingAction constant and commandForPendingAction pure function (fully tested)
- Remove root _pendingToggle property
- Use dynamic _pendingAction on the statusCheck Process for the fresh-status hand-off
- Introduce refreshStatus() helper and deduplicate the two post-action refresh sites
- All JS statements now terminate with semicolons; all blocks use braces
- Behavior unchanged; coordination token no longer leaks to widget root
- Enables future post-status actions without adding more root properties

Written by AI agent working for @jtmorris. Model: grok-build-0.1.
2026-05-25 03:00:33 +00:00
12ef07040c Code formatting cleanup. 2026-05-25 03:00:33 +00:00
6e4e5d51ec refactor(clipboard): replace object map + 4 helpers with simple array + getClipboardCommands; QML becomes dumb index driver
- lib.js: single clipboardTools array + getClipboardCommands(text) returning argv lists
- Delete validateClipboardTool, buildCopyCommand, nextClipboardTool, allClipboardTools, safeClipboardTools, old clipboardTools object
- Remove noClipboardTool / invalidClipboardCommand from getStrings (dead)
- TailscaleWidget.qml: remove _copyCurrentTool + _executeCopy; add _copyIndex + _runNextCopy
- copyProcess.onExited and copyToClipboard now purely index-driven, no tool names
- Update tests: remove 4 old clipboard test blocks + dead string assertions; add focused getClipboardCommands tests
- All 34 tests pass

This is the minimal honest design given Process is a QML type.
2026-05-25 03:00:33 +00:00
e695db6650 security: validate hostname in makeExitNodeCommand (balanced paranoia, direct-argv defense-in-depth, TDD) 2026-05-25 03:00:33 +00:00
4a7803dc42 refactor: simplify copy path — drop caching and multi-tool retry state machine, keep simple dms→wl-copy fallback (first-principles plan) 2026-05-25 03:00:33 +00:00
9dd73b6d55 refactor: add getStatusCommand pure helper + test (TDD step 2 — prepares low-duty-cycle status calls) 2026-05-25 03:00:33 +00:00
6b71197770 refactor: introduce formatError centralizer + remove first batch of historical comments (TDD step 1 of first-principles plan) 2026-05-25 03:00:33 +00:00
440e954099 refactor: extract shouldShowClearExitNode and isActiveExitNode to lib.js (TDD) — light progress on #43
- Two small pure UI predicates moved out of QML delegate
- QML now calls TailscaleLib.* (thinner glue)
- New tests + all existing tests pass
- No new state, no architecture change

Written by AI agent working for @jtmorris. Model: Grok build-0.1.
2026-05-25 03:00:33 +00:00
925233dfb9 feat: extract UI strings to lib.js; harden clipboard to direct argv, drop clipmanctl (#34, #49)
- safeClipboardTools now only dms + wl-copy (clipmanctl removed as niche optional history manager)
- buildCopyCommand now returns pure argv arrays (no sh -c, no escaping, eliminates future injection risk)
- Added getStrings() for centralised user-facing strings (prep for real i18n)
- Updated all tests (TDD) and README
- All 29 tests pass

Written by AI agent working for @jtmorris. Model: Grok build-0.1.
2026-05-25 03:00:33 +00:00
da4d566f0c fix: lib.js security and correctness fixes (#40, #41)
- parsePeers: add hasOwnProperty guard and filter null entries
- findActiveExitNode: add hasOwnProperty guard to for..in loop
- makeExitNodeCommand: handle empty hostname correctly
2026-05-25 03:00:33 +00:00
701daa9a39 refactor: replace detectClipboard with try-fallback-cached clipboard strategy
- Remove detectClipboard Process and clipboardCmd property
- Add try-fallback-cached copy logic: attempt cached tool first,
  then cycle through hardcoded safe tools (dms, wl-copy, clipmanctl)
- Add stderr StdioCollector to all Process components for error details
- Update lib.js: replace parseClipboardDetection with validateClipboardTool,
  buildCopyCommand, nextClipboardTool, allClipboardTools
- Update tests to match new lib.js API

Benefits:
- No startup delay from clipboard detection process
- Robust fallback if clipboard tool becomes unavailable
- Better error messages with stderr details from failed commands
2026-05-21 06:37:14 +00:00
6ef933211c fix: expand clipboard detection to xclip and xsel
Add xclip and xsel to the whitelist and detection script so users
on systems without wl-copy or clipmanctl can still copy peer info.
2026-05-21 02:29:13 +00:00
b521af3364 feat: add parseStatusResult for safe JSON parsing of tailscale status
Wraps JSON.parse in try/catch, returns safe defaults on failure,
and delegates to existing findActiveExitNode and parsePeers.
2026-05-20 19:29:02 +00:00
ce8707c618 feat: add buildToggleCommand for safe toggle command construction
Replaces inline ternary in QML with a pure function that returns
the correct tailscale up/down command based on connection state.
2026-05-20 19:21:17 +00:00
dddd9218f6 feat: add parseClipboardDetection for safe clipboard tool parsing
Trims output and validates against whitelist, falling back to 'none'
for empty, multi-line, or unexpected values.
2026-05-20 10:16:02 +00:00
3c31209ff1 feat: add buildCopyCommand for safe clipboard command construction
Uses validateClipboardCmd to reject untrusted input and properly escapes
single quotes in text to prevent shell injection.
2026-05-20 10:11:57 +00:00
a86d5e279d feat: add validateClipboardCmd with whitelist-based input validation
Prevents shell injection by only allowing known-safe clipboard commands
(dms cl copy, wl-copy, clipmanctl copy, none).
2026-05-20 10:08:59 +00:00
bd9df03b5b fix: find active exit node from Peer map instead of CurrentExitNode 2026-05-18 22:10:37 +00:00
6129b09943 feat: add error handling and toast notifications (#8)
- Add errorMessage() utility for user-friendly toast messages
- Show toast on tailscale up/down/set/status failures
- Detect missing tailscale binary (exit code 127)
- Guard toggleTailscale and setExitNode when binary unavailable
- Show 'Tailscale not available' in popout when binary missing
2026-05-18 20:53:32 +00:00
c9d1baf7c4 fix: remove ESM export from lib.js for QML compatibility
QML's JS engine does not support ES module export/import syntax.
Replace bare export with a CommonJS guard that only runs under Node.js,
so the plugin loads in QML while tests still work.
2026-05-18 18:39:39 +00:00
0c2376b3bb feat: add exit node selection to Tailscale widget
- Extract peer parsing and exit-node command logic into lib.js
- Add ↗ button on peers that are ExitNodeOption candidates
- Highlight active exit node in primary color
- Add clear (×) button next to current exit node label
- Add unit tests for parsePeers and makeExitNodeCommand
2026-05-18 18:27:41 +00:00