Skip to content

v1.0.3 -- "宇宙是蚂蚁的梦。"

Choose a tag to compare

@github-actions github-actions released this 02 Sep 17:56
· 10 commits to main since this release
  • chore(release): bump version to 1.0.3

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • feat(profiles): give each tab its own action button

  • The Profiles scaffold showed one Add Profile button for all three tabs,

  • while the node and chain actions sat inline above their lists. The

  • button that matters depends on the tab you are looking at.

  • Drive the floating action button from the tab index: Add Profile on

  • Profiles, Create node and Import node on Nodes, Create chain on Chains.

  • The inline buttons in the node toolbar and above the chain list are gone

  • now that the actions live in the scaffold; the empty states keep theirs

  • as a call to action.

  • The two node buttons sit at opposite edges, which the end-aligned slot

  • cannot express, so CommonScaffold gained a floatingActionButtonLocation

  • and that tab uses centerFloat with the edge inset added back.

  • To reach the actions from the scaffold, the node import/create handlers

  • and the chain create handler become top-level functions in their own

  • files; the views delegate to them.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • feat(nodes): import nodes without a preview step

  • Removing only the overwrite-or-copy radios left the preview dialog in

  • place, so importing still interrupted the user to confirm a list they

  • did not ask to review. Importing a link means "add this": parse it, add

  • what is valid, and report what is not.

  • Drop the preview entirely from both import paths. NodeLibraryService

  • already skips drafts that fail to parse and returns their issues, so the

  • Nodes tab now surfaces those issues instead of showing them in a list

  • nobody needed to approve. Binding follows the caller as before: imports

  • bind to the current profile when there is one.

  • Delete NodeImportPreview, NodeImportSelection and their test, along with

  • the importPreview and bindCurrentProfile messages that only that dialog

  • used. _previewAndCommitNodes becomes _commitNodes, since it no longer

  • previews anything.

  • Verified on an Android emulator: a node deep link and the Nodes tab

  • import both create the node with no dialog, and importing the same link

  • twice yields two copies.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • feat(nodes): always add on import instead of asking about duplicates

  • The import preview asked the user to choose between updating the

  • existing node and creating a copy. The choice is not worth a prompt:

  • importing a link means "add this", and re-importing the same link should

  • simply yield another copy.

  • Drop the radio group and commit imports with createCopy, so the preview

  • only asks what it still needs, which drafts to keep and whether to bind

  • them to the current profile.

  • Clean up what the choice left behind:

    • NodeImportSelection.createCopy, now that nothing reads it.
    • The createCopy parameter on importNodeText and _previewAndCommitNodes,
  • which no caller ever passed.

    • The updateExisting message, whose only reference was the removed radio.
  • NodeLibraryService.commit keeps its createCopy parameter: the node menu

  • still duplicates a node with it, and manual creation still dedupes by

  • fingerprint without it.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • fix(android): keep warm-start deep links out of Flutter routing

  • Deep links are handled by app_links, but the Flutter engine's own deep

  • link handling is on by default and pushes the incoming URI into the

  • navigation system. This app uses a plain MaterialApp with no route

  • generator, so a link delivered to an already running instance raised

  • "Could not find a generator for route" and never reached LinkManager.

  • Cold start worked only because getInitialLink reads the intent

  • directly. Warm start is the common case here, since the app is meant to

  • stay running in the background while a subscription link is opened from

  • a browser or chat app.

  • Set flutter_deeplinking_enabled to false so the intent reaches

  • app_links in both cases.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • fix(nodes): treat every http(s) URI as a subscription

  • isHttpProxyUri classified any http(s) URI with an explicit port as an

  • HTTP proxy node, so a subscription link served on a non-default port

  • was imported as a node instead of creating a profile. Self-hosted

  • panels commonly use ports such as 8443 or 2096, and the

  • avalon://install-config deep link routes through the same path, so its

  • explicit intent was overridden by the heuristic.

  • http and https are no longer node schemes, matching what the deep link

  • dispatcher and the Android intent filters already assumed. Drop

  • HttpCodec, its https alias and the port heuristic, and let importText

  • treat any http(s) URI as a subscription URL.

  • Raw Mihomo configs carrying type: http proxies keep working; only the

  • URI codec is gone.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • perf(telemetry): gate UI telemetry on a unified activity state

  • Traffic sampling ran on a fixed 1s global timer that only stopped when

  • the proxy stopped, so a hidden window still paid for Dart scheduling,

  • two IPC round trips and provider updates every second.

  • Introduce a process-wide AppActivityState fed by the Flutter lifecycle,

  • window visibility and window focus, and drive telemetry from it:

    • SetupAction picks 1s, 5s or no sampling from the current activity,
  • the dashboard traffic widgets and the tray title need, resamples

  • immediately on resume, and skips a tick while a request is in flight.

    • The tray speed title is macOS-only, so its need is platform-gated;
  • otherwise showTrayTitle (default true) kept background sampling alive

  • for a consumer that does not exist off macOS.

    • Pages and the app root wrap their subtree in TickerMode so animations
  • stop when the page or the window is inactive.

    • NetworkSpeed and TrafficUsage drop their provider subscription while
  • inactive; Logs and Requests buffer through ActiveSnapshotMixin and

  • commit one snapshot once page and window are both active again.

    • Tray titles dedupe on the formatted string, and getTraffic /
  • getTotalTraffic bypass the debug RPC timing logs.

  • Frame pausing now distinguishes an on-screen window from a hidden one:

  • blur only gates telemetry and tickers, while hide and minimize pause

  • frames after 300ms instead of 5s. Losing focus must not stop frames, as

  • an unfocused window is still scrollable and would appear frozen.

  • Verified on an Android emulator: 1 tick/s in the foreground, zero ticks

  • across 25s backgrounded, and an immediate resample on resume.

  • Co-Authored-By: Claude Opus 5 noreply@anthropic.com

  • Claude-Session: https://claude.ai/code/session_01THm54YvuV1sjPqEMGFrgxq

  • fix(ui): show chain names and align node actions

Release Downloads

Download based on your OS:

OS Download
Android

Windows
macOS
Linux