Skip to content

Commit c8ca65e

Browse files
cursoragentjoei4cm
andcommitted
Merge upstream/dev into feat/tailscale for PR #2270
Rebase Tailscale outbound integration onto current upstream dev: - Keep Tailscale profile injection in setup action and Tools menu entry - Adopt upstream desktop lifecycle, Android service refactor, and helper v6 - Update Clash.Meta submodule to upstream dev pointer - Regenerate Riverpod, Freezed, and l10n outputs after conflict resolution Co-authored-by: MichaelZ <joei4cm@users.noreply.github.com>
2 parents f00235d + d966b18 commit c8ca65e

147 files changed

Lines changed: 5970 additions & 1711 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/architecture.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,16 @@ Responsibilities are deliberately split:
274274
- `core/` and `services/helper/` remain source owners; `libclash/` and Android `jniLibs`/header directories are generated
275275
output locations.
276276
- `setup.dart` remains the release/package orchestrator and does not pre-build
277-
platform artifacts or pass Core integrity data into Dart.
277+
platform artifacts or use `dart-define` for Core integrity data. The Windows
278+
build tool writes the runtime `manifest.json` beside the Core output, and the
279+
Windows bundle copies it beside the application executable.
278280

279281
Platform outputs remain explicit:
280282

281283
- Android builds the Go core as `c-shared`, then copies `libclash.so` and generated headers into the `:core` Android module.
282284
- macOS and Linux build a standalone `FlClashCore` process used by the desktop socket integration.
283-
- Windows builds `FlClashCore.exe` plus the Rust `FlClashHelperService.exe` privileged helper.
285+
- Windows builds `FlClashCore.exe`, the Rust `FlClashHelperService.exe` privileged helper, and a
286+
`manifest.json` containing only `coreSha256`.
284287

285288
The hooks follow rust_api/Cargokit's phony-output scheduling pattern, but setup uses its own cache because it builds both a
286289
Go core and, on Windows, a separate Rust helper. Per-target records live under `.dart_tool/setup_build_cache/v1/`:
@@ -303,11 +306,23 @@ Windows helper integrity/version check:
303306

304307
- The build tool constructs the Core first, calculates its SHA256, and always
305308
builds the Rust Helper with release hardening and that expected hash.
306-
- Flutter does not embed or send the Core SHA256. Debug, Profile, and Release
309+
- Flutter reads the Core SHA256 from the bundled `manifest.json` and sends it with `/ping`. Debug, Profile, and Release
307310
builds use the same Helper protocol and may use TUN through the same flow.
308-
- `/ping` is loopback-only and requires no request token. The Helper verifies the fixed `FlClashCore.exe` beside it against
309-
its embedded SHA256 before reporting readiness, and repeats verification before every launch. The response includes the
310-
running Helper path and protocol header; Dart checks both against the current installation.
311+
- `/ping` is loopback-only and requires no request token. The Helper compares the requested SHA256 with its embedded value
312+
and checks that the fixed `FlClashCore.exe` beside it exists; `/start` performs the actual Core SHA256 verification before
313+
every launch. The response includes the running Helper path and protocol header; Dart checks both against the current
314+
installation. The launcher selects the Helper only when `/ping` reports ready; any other readiness (missing manifest,
315+
unavailable Helper, or a Helper built for a different Core) falls back to the direct Core without requesting elevation.
316+
If `/start` reports a pre-spawn failure — `coreVerificationFailed` (the on-disk Core no longer matches the SHA the
317+
Helper and manifest agree on) or `processLaunchFailed` (the Core process could not be spawned) — the launcher degrades
318+
to the direct Core rather than failing the launch. `/start` releases the previously managed Core before it verifies,
319+
so the Helper owns no Core when either code is reported and the direct retry cannot race a Helper-managed Core.
320+
A mismatched Helper is reinstalled through the explicit TUN authorization flow, not at startup.
321+
- TUN is not a required run condition. A direct Core runs unelevated and cannot bring up TUN, so any degrade to the
322+
direct Core — an unready Helper at resolve time, or a pre-spawn `/start` failure — silently drops TUN and keeps the
323+
Core running. Degrading is preferred over failing the launch: an unverified Core carries no privilege the direct
324+
launch path did not already have. `manifestMissing` is the one readiness that is surfaced to the user, because it
325+
means the installation itself is incomplete.
311326
- Flutter creates a 128-bit lowercase-hex session ID and uses it as the random named-pipe suffix. `/start` receives only
312327
that address and session ID, validates the fixed `FlClashCore_<session>` namespace, starts the fixed Core beside the
313328
Helper, and returns the same session ID plus the spawned PID. Flutter verifies both the session and named-pipe peer PID.
@@ -350,13 +365,16 @@ The helper owns its Windows Service Control Manager lifecycle through two elevat
350365
The Dart layer only launches the helper's `install` command through `ShellExecuteW`; it does not compose `sc.exe`,
351366
`taskkill`, or `cmd.exe` command lines.
352367

353-
In every Flutter build mode it opens the fixed Core executable beside the Helper without write/delete sharing, validates
354-
it against the SHA256 embedded only in the Helper, and keeps that handle open through process creation. Protocol version 5
355-
uses 32-character lowercase-hex session ownership:
368+
In every Flutter build mode `/start` opens the fixed Core executable beside the Helper without write/delete sharing,
369+
validates it against the SHA256 embedded only in the Helper, and keeps that handle open through process creation.
370+
`/ping` only compares the requested `coreSha256` with the Helper's embedded value and checks the fixed Core path exists;
371+
it never hashes the Core. Protocol version 6 uses 32-character lowercase-hex session ownership:
356372

357-
- `GET /ping` verifies Core and returns the current Helper executable path with `x-flclash-helper-protocol`.
358-
- `POST /start` rejects unknown JSON fields, validates `{address, sessionId}`, replaces any previously managed Core, and
359-
returns `{sessionId, pid}`.
373+
- `GET /ping?coreSha256=...` returns the current Helper executable path with `x-flclash-helper-protocol` when the
374+
requested SHA matches.
375+
- `POST /start` rejects unknown JSON fields, validates `{address, sessionId}`, then releases any previously managed Core
376+
before verifying the Core — so every outcome, including a rejected one, leaves the Helper owning no Core — and returns
377+
`{sessionId, pid}`.
360378
- `POST /stop` validates `{sessionId}` and only stops the matching managed Core. A session mismatch is HTTP 409.
361379
- `GET /logs` exposes the bounded recent Helper/Core stderr buffer with `no-store` caching.
362380

.agents/commands.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,7 @@ The Makefile wraps `plugins/setup/buildkit/run_build_tool.sh`; prefer the `make`
4040

4141
## Flutter Development
4242

43-
The project follows FVM's `stable` channel locally. Release CI pins an exact
44-
Flutter version separately; see `.agents/project.md`.
45-
46-
```bash
47-
fvm flutter pub get
48-
fvm flutter run
49-
fvm flutter test
50-
```
51-
52-
Plain Flutter also works when the global SDK matches project constraints:
43+
Use the default Flutter SDK directly:
5344

5445
```bash
5546
flutter pub get

.agents/project.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ FlClash is a multi-platform proxy client based on ClashMeta (mihomo), built with
44

55
## Version Notes
66

7-
- `.fvmrc` follows the FVM `stable` channel for local development; it does not
8-
pin an immutable Flutter version.
9-
- Release CI pins Flutter 3.44.4. Local `stable` may diverge, so trust the CI
7+
- Release CI pins Flutter 3.44.4. Local SDK may diverge, so trust the CI
108
version as the source of truth for release builds.
119
- Dart SDK constraint: `>=3.8.0 <4.0.0`.
1210

.agents/rules.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,46 @@ Generated directories are excluded from analysis:
2121
- `lib/**/generated/**`
2222
- `plugins/**`
2323

24+
## Comments
25+
26+
Comments are opt-in and reserved for the few places that genuinely need one. Density is the point: every comment that
27+
restates the code devalues the comments that carry real information, until readers skim past all of them. A file with
28+
three comments that matter is more readable than one with thirty.
29+
30+
### Writing Comments
31+
32+
- Never add a comment on your own initiative. This covers explanatory, narrative, TODO, section-divider, and
33+
documentation comments, in Dart, Kotlin, Swift, Go, Rust, YAML, Gradle, and any other file you touch.
34+
- Never annotate line by line or statement by statement, and never restate in prose what the code already says. If a
35+
block needs a comment per step, the block needs better names or a smaller decomposition instead.
36+
- When a change genuinely cannot be understood without a comment, do not write it silently. Explain what is unclear,
37+
propose the exact comment text, and wait for the user to approve it before adding it.
38+
- Delete commented-out code, stale version notes, and comments that only restate the code, whenever you edit the file
39+
that contains them. This does not need approval.
40+
- These are not comments and must be preserved: analyzer and linter directives (`// ignore:`, `// ignore_for_file:`,
41+
`// coverage:ignore`), license and copyright headers, code-generation markers, and comments inside vendored upstream
42+
code such as `lib/widgets/open_container.dart`.
43+
44+
### Where Knowledge Belongs
45+
46+
Pick the destination by where the constraint would be violated, not by how important it feels.
47+
48+
- **Assertable behavior goes in a test.** A test is the only form that cannot drift, because it fails when the behavior
49+
it describes is broken. Prefer it over both a comment and a document whenever the fact can be checked in code.
50+
- **Repository-wide defaults, ownership, and invariants go in `.agents/*.md` or a `.agents/skills/*/SKILL.md`.** They
51+
are violated from many files, so they must reach every future agent at session start. A comment in one file cannot do
52+
that.
53+
- **A fact that is true only at one call site, and is not visible from that call site, stays a comment there.** Its
54+
value is being in the reader's line of sight at the moment of the edit. `lib/common/constant.dart` is the model case:
55+
the delay-test concurrency cap is bound to `mBatch` in `core/common.go`, and whoever changes that number must see the
56+
constraint on the same screen.
57+
58+
Both failure directions are real. Moving a local constraint into `.agents/` hides it from the person editing the line;
59+
leaving a repo-wide policy as a comment reaches only the reader of that one file.
60+
61+
Before any of the three, prefer encoding the intent in structure and naming — a named mixin, type, or method that makes
62+
the invariant hard to break beats prose that asks the next reader not to break it.
63+
2464
## Core API Safety
2565

2666
- Do not expose direct filesystem deletion APIs through Core or helper IPC; use

.agents/skills/core-platform/SKILL.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,16 @@ Read `.agents/architecture.md` for the current core modes, manager stack, build
4949

5050
- Keep the Windows Helper protocol and Core SHA256 validation identical across
5151
Flutter build modes; the Helper owns executable integrity checks.
52-
- Protocol version 5 uses a 32-character lowercase-hex session ID. `/start` must return the submitted session and PID;
52+
- Protocol version 6 uses a 32-character lowercase-hex session ID. `/start` must return the submitted session and PID;
5353
`/stop` must never terminate a different session; Dart must verify the connected named-pipe peer PID.
54+
- `/start` must release the previously managed Core before it verifies, so no `/start` outcome leaves a Helper-managed
55+
Core behind for the caller's direct-launch fallback to race.
56+
- The Helper owns a managed Core until its exit is confirmed. A `200` from `/stop` means the Core is gone; when
57+
termination cannot be confirmed the Helper keeps the child and answers `coreStopFailed`, and `/start` reports the same
58+
code instead of spawning a replacement. Keep that code out of the Dart pre-spawn fallback set in
59+
`helper_client.dart`, or the direct launch will race a Core the Helper still owns.
60+
- TUN is not a required run condition. Degrading to the unelevated direct Core — and silently losing TUN — is the
61+
expected outcome whenever the Helper path fails; do not fail the launch instead.
5462
- A desktop process lease with unconfirmed exit must remain owned until cleanup succeeds. Do not discard it and start a
5563
replacement Core.
5664
- `CoreController.close()` is terminal. Do not call it from a reusable manager lifecycle or recover by starting it again.

.claude/agents/implementer.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
name: implementer
3+
description: Use for scoped feature work, bug fixes, refactors, and focused test updates after the requirements are clear.
4+
tools: Read, Grep, Glob, Bash, Edit, Write
5+
model: sonnet
6+
effort: high
7+
---
8+
9+
Implement the requested change in the smallest appropriate scope. Follow the repository instructions in AGENTS.md and
10+
the
11+
linked .agents documentation, preserve existing lifecycle and serialization contracts, and keep unrelated working-tree
12+
changes untouched. Trace the affected call path before editing, update focused tests when behavior changes, and report
13+
the
14+
files changed plus the verification actually run.

.claude/agents/researcher.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
name: researcher
3+
description: Use for fast read-only codebase exploration, call-path tracing, and locating relevant tests before implementation.
4+
tools: Read, Grep, Glob
5+
model: sonnet
6+
effort: medium
7+
---
8+
9+
Trace the actual call path instead of stopping at the first matching file. Identify the relevant symbols, lifecycle owner,
10+
cross-platform boundary, existing tests, and focused verification commands. Do not modify files. Return concise,
11+
evidence-based findings with file paths and line references when available.

.claude/agents/reviewer.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
name: reviewer
3+
description: Use after code changes for correctness, regression, lifecycle, contract, and test review.
4+
tools: Read, Grep, Glob, Bash
5+
model: opus
6+
effort: high
7+
---
8+
9+
Review the current changes without editing files. Inspect the diff, trace the relevant call paths, and check platform
10+
ownership, serialization or IPC contracts, error handling, and test coverage. Run focused read-only checks when useful.
11+
Report actionable findings first, ordered by severity, with file paths and line references; state explicitly when no issue is
12+
found and note any validation or platform coverage gaps.

.codex/agents/implementer.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name = "implementer"
2+
description = "Use for scoped feature work, bug fixes, refactors, and focused test updates after the requirements are clear."
3+
model = "gpt-5.6-sol"
4+
model_reasoning_effort = "high"
5+
sandbox_mode = "workspace-write"
6+
developer_instructions = """
7+
Implement the requested change in the smallest appropriate scope. Follow the repository
8+
instructions in AGENTS.md and the linked .agents documentation. Preserve existing
9+
lifecycle and serialization contracts, and keep unrelated working-tree changes
10+
untouched. Trace the affected call path before editing, update focused tests when
11+
behavior changes, and report the files changed plus the verification actually run.
12+
"""

.codex/agents/researcher.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name = "researcher"
2+
description = "Use for fast read-only codebase exploration, call-path tracing, and locating relevant tests before implementation."
3+
model = "gpt-5.6-luna"
4+
model_reasoning_effort = "high"
5+
sandbox_mode = "read-only"
6+
developer_instructions = """
7+
Trace the actual call path instead of stopping at the first matching file. Identify
8+
the relevant symbols, lifecycle owner, cross-platform boundary, existing tests, and
9+
focused verification commands. Do not modify files. Return concise, evidence-based
10+
findings with file paths and line references when available.
11+
"""

0 commit comments

Comments
 (0)