Skip to content

Commit 9255103

Browse files
committed
docs(agents): document custom profiles, setting changes and the gomobile Core
1 parent caf9f8e commit 9255103

16 files changed

Lines changed: 812 additions & 238 deletions

File tree

‎.agents/architecture.md‎

Lines changed: 416 additions & 127 deletions
Large diffs are not rendered by default.

‎.agents/commands.md‎

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ dart setup.dart windows
1717
dart setup.dart android
1818
```
1919

20-
The Go core and the Rust helper build automatically: Flutter runs
20+
The desktop Go core and the Rust helper build automatically: Flutter runs
2121
`plugins/setup/hook/build.dart` on every `flutter build` and `flutter test`,
2222
and the hook drives `CoreBuilder` from the `setup_hooks` package in
23-
`plugins/setup/setup_hooks/`. Android builds take the NDK from the C compiler
24-
Flutter hands the hook; no `ANDROID_NDK` variable is needed.
25-
Artifacts land in `libclash/`. The hook reruns only when Go, Rust, or
23+
`plugins/setup/setup_hooks/`. Artifacts land in `libclash/`. Android's Core is
24+
the AAR the `:core` Gradle module builds with `gomobile bind` before anything
25+
compiles against it; that needs `go` on `PATH` and nothing else, since the
26+
gomobile tools come from `core/go.mod` and the NDK from AGP. The hook reruns only when Go, Rust, or
2627
`setup_hooks` inputs change; the fingerprint cache lives in
2728
`.dart_tool/setup_build_cache/`. To force a rebuild, delete that directory:
2829

@@ -49,15 +50,16 @@ hooks:
4950
build_assets: true # false does the same for the Rust library
5051
```
5152
52-
CI flips `setup` to `false` with `yq` before `dart run tool/changelog.dart` and
53-
`flutter test`, and restores the file afterwards; no test loads the Go core. `rust_api`
54-
stays on there because the editor tests in `test/plugins/code_forge/` load the Rust
55-
library the hook builds; the release-notes job, which runs no tests, flips both.
53+
CI flips `setup` to `false` with `yq` in its throwaway checkout before
54+
`dart run tool/changelog.dart` and `flutter test`; no test loads the Go core. `rust_api`
55+
stays on there because the editor tests in `test/plugins/code_forge/` and the socket
56+
test in `test/core/desktop/ipc_native_test.dart` load the Rust library the hook
57+
builds; the release-notes job, which runs no tests, flips both.
5658
Never commit `false`: a build with it set stages whatever `libclash/` already
5759
holds and bundles no Rust library, which is why `setup.dart` refuses to package
5860
while it is set. Locally, `false` is worth setting for a Dart-only test loop,
5961
but the hook cache keys on the user-define, so the first build afterwards runs
60-
the hooks again. The editor tests still need the Rust library: keep `rust_api`
62+
the hooks again. The editor and IPC socket tests still need the Rust library: keep `rust_api`
6163
on, or point `FRB_DART_LOAD_EXTERNAL_LIBRARY_NATIVE_LIB_DIR` at a directory that
6264
holds a `rust_api` library built from the same sources.
6365

@@ -175,7 +177,8 @@ flutter test test/widgets/core_status_button_test.dart
175177
What those suites own:
176178

177179
- `test/core/desktop/`: replaceable IPC transport, RPC request correlation/failure, direct/Helper process leases, and
178-
latest-intent desktop lifecycle convergence.
180+
latest-intent desktop lifecycle convergence. `ipc_native_test.dart` runs the transport over a real socket through
181+
the Rust `IpcServer`; the server's own behavior is covered by `cargo test` in `plugins/rust_api/rust`.
179182
- `test/core/service_test.dart`: `CoreService` composition and terminal close behavior.
180183
- `test/core/protocol_contract_test.dart`: shared Dart/Go method and event-envelope compatibility, including event batches.
181184
- `test/providers/action_test.dart`: Core start/restart orchestration and overlapping restart requests.
@@ -185,12 +188,13 @@ What those suites own:
185188

186189
## Native Component Verification
187190

188-
The CI Go-wrapper checks can be reproduced without CGO:
191+
The CI Go-wrapper checks can be reproduced without CGO, the Android files included:
189192

190193
```bash
191194
cd core
192195
CGO_ENABLED=0 go test .
193-
CGO_ENABLED=0 go vet .
196+
CGO_ENABLED=0 go vet . ./cmd/...
197+
GOOS=android GOARCH=arm64 CGO_ENABLED=0 go vet -tags=with_gvisor . ./mobile ./tun ./platform
194198
```
195199

196200
The Windows Helper's loopback/session protocol tests are host-independent by default. Windows CI additionally enables its
@@ -209,6 +213,7 @@ registered with `java_home`, so export it by prefix:
209213
```bash
210214
cd android
211215
export JAVA_HOME="$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home" # elsewhere: any JDK 17
216+
./gradlew :core:compileDebugKotlin -Ptarget-platform=android-arm64 # builds the gomobile AAR for one ABI
212217
./gradlew :service:compileDebugKotlin
213218
./gradlew :app:compileDebugKotlin
214219
```
@@ -284,7 +289,8 @@ works as is for local previews. `tool/build_site.sh [dir]` assembles it with the
284289
`gh`. Without `gh` access the page falls back to the newest version in `CHANGELOG.md` and lists the files without sizes.
285290
It then runs `tool/render_site.mjs` (Node), which writes the English page and a `zh/` copy for search engines: page
286291
text, the first changelog releases, canonical and `hreflang` links, JSON-LD and `sitemap.xml`, all from the strings,
287-
changelog parser and release markup in `site/assets/shared.js`. `SITE_URL` overrides the published URL these point at.
292+
changelog parser and release markup in `site/assets/shared.js`, plus the GitHub star count from `release.json` so the
293+
nav does not grow when the page loads. `SITE_URL` overrides the published URL these point at.
288294
On the built site each URL keeps its language: the language button links to the other page and carries the section in
289295
view, the chosen platform and the changelog search. Only the English root sends readers who chose or prefer Chinese on
290296
to `zh/`, unless its URL carries `?lang=en`: the button on `zh/` links there with it, so getting back to English never
@@ -311,8 +317,7 @@ In the public repository every branch push runs the `dart` job; in the private
311317
The `dart` job performs these root-package checks in order:
312318

313319
```bash
314-
bash tool/check_commit_msg_test.sh
315-
bash tool/check_comment_density_test.sh
320+
bash tool/hooks/test.sh
316321
flutter pub get
317322
dart format --output=none --set-exit-if-changed lib test tool plugins setup.dart
318323
flutter analyze --no-fatal-infos
@@ -321,15 +326,18 @@ flutter test --reporter expanded --coverage
321326
dart run tool/check_coverage.dart coverage/lcov.info 75
322327
```
323328

329+
`tool/hooks/` holds the scripts the git hooks run, and `tool/hooks/test.sh` runs every `*_test.sh` beside them, so a
330+
new hook script needs only its test file next to it, not a workflow step.
331+
324332
Run `flutter analyze` before committing; CI fails on anything it reports.
325333

326334
Release builds run only for `v*` tag pushes; pull requests trigger nothing.
327335
Root analysis excludes `plugins/**`, and root tests do not discover nested
328336
plugin packages, so parallel jobs validate the rest from their own package
329337
directories: `plugins` (local Flutter packages and the setup build tool), `go`
330-
(the Core wrapper, plus an NDK-backed vet of the Android files), `android`
331-
(JVM unit tests for `:common`, `:service` and `:app`, with the Flutter compile
332-
tasks excluded so no native build hook runs), `rust` (both crates), and a
338+
(the Core wrapper, plus a vet of the Android files), `android` (JVM unit tests
339+
for `:common`, `:service` and `:app`, with the Flutter compile tasks excluded
340+
and the gomobile AAR built for one ABI), `rust` (both crates), and a
333341
Windows runner for the helper's `windows-service` feature. A `desktop` job also
334342
compiles a debug build per desktop platform. Release builds run only in the
335343
public repository and start once every job except `desktop` passes.

‎.agents/flutter-upgrade.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ listed in the SDK's `CHANGELOG.md`.
1717
became the default desktop renderer, Intel (x86_64) Macs flicker across the whole window while scrolling or
1818
animating, and text can render garbled. Apple Silicon is not affected.
1919
- **Fix upstream:** landed on `main` before 2026-08-25 and verified on `3.48.0-1.0.pre-404`; it is not in any
20-
3.47.x hotfix (checked through 3.47.5).
20+
3.47.x hotfix (checked through 3.47.6).
2121
- **Workaround:** the release job for `macos-15-intel` (`arch: amd64`) runs
2222
`plutil -replace FLTEnableImpeller -bool NO macos/Runner/Info.plist` before `dart setup.dart`, so only the Intel
2323
DMG falls back to Skia. The checked-in `Info.plist` does not set the key, so local builds and the arm64 DMG keep

‎.agents/project.md‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Project Context
22

3-
FlClash is a multi-platform proxy client based on ClashMeta (mihomo), built with Flutter. It supports Android, Windows, macOS, and Linux, using a Material You design with Surfboard-like UI.
3+
FlClash is a multi-platform proxy client based on ClashMeta (mihomo), built with Flutter. It supports Android, Windows, macOS, and Linux, using Material You from `material_ui` as the base with Apple's Human Interface interaction conventions layered on top.
44

55
## Version Notes
66

7-
- Flutter stays on the 3.47.x line. Release CI pins 3.47.4 and is the source
7+
- Flutter stays on the 3.47.x line. Release CI pins 3.47.6 and is the source
88
of truth for release builds; `.fvmrc` and local SDKs may sit on another 3.47
99
patch. The editor in `plugins/code_forge` came from `code_forge` 10.14.0, which
1010
needs Dart 3.13.2, so the CI pin cannot go below Flutter 3.47.2.
@@ -16,11 +16,11 @@ FlClash is a multi-platform proxy client based on ClashMeta (mihomo), built with
1616

1717
## Forked Dependencies
1818

19-
Two `pubspec.yaml` dependencies are pinned to a fork by commit SHA. Both forks
20-
live under `chen08209`, the same account that owns this repository, so they are
19+
One `pubspec.yaml` dependency is pinned to a fork by commit SHA. The fork lives
20+
under `chen08209`, the same account that owns this repository, so it is
2121
maintained in-house rather than tracked from a third party: advancing a pin is a
2222
local decision, and there is no external maintainer to wait on for the patch
23-
itself. What each fork still waits on is the *upstream* fix that would let the pin
23+
itself. What the fork still waits on is the *upstream* fix that would let the pin
2424
be dropped entirely, recorded below.
2525

2626
Each entry records what the fork changes and what has to be true before it can go
@@ -47,13 +47,11 @@ now, see the window plugin section of `architecture.md`.
4747
directly, and upstream's `^2.0.0` constraint cannot co-resolve with it.
4848
- Drop the fork when upstream publishes a release that accepts `win32_registry` 3.x.
4949

50-
`yaml_writer` — `chen08209/yaml_writer`, version 2.1.0.
51-
52-
- Adds `StringNode.quoteKey()` and applies it to map keys in `lib/src/node.dart`.
53-
Upstream quotes values but emits keys verbatim, so a profile key needing quotes
54-
is written as invalid YAML.
55-
- Drop the fork once upstream quotes map keys by the same
56-
`isValidUnquotedString` rule it already applies to values.
50+
The `yaml_writer` fork (`chen08209/yaml_writer`) was replaced by
51+
`lib/common/yaml_writer.dart`. Its key quoting let keys such as `!a`, `'a` or
52+
`0x1F` reach the Core's yaml.v3 as a parse error or a non-string; a merge key
53+
`<<` stays plain on purpose, because `package:yaml` keeps it as an ordinary key
54+
and the Core applies the merge.
5755

5856
The `code_forge` fork (`chen08209/code_forge`) is frozen: its Dart code now lives
5957
in the in-repo `plugins/code_forge` package and its Rust code in the `editor/`
@@ -69,9 +67,15 @@ resolved-until-the-ceiling-moves rather than as debt:
6967
- `intl` is intentionally unbounded (`any`) and `material_color_utilities` is
7068
resolved by the Flutter SDK; neither is a bound this repository sets.
7169

72-
`freezed`, the `riverpod` set, `build_runner`, `drift_dev`, `intl_utils` and
73-
`test` all resolve against the analyzer the pinned SDK ships; none of them is
74-
held back. When an upgrade fails version solving, record the blocker here with
70+
The `riverpod` set, `build_runner`, `drift_dev` and `intl_utils` resolve to their
71+
latest releases. Two are held back:
72+
73+
- `freezed` 4.0.2 needs `analyzer` 14, while `intl_utils` 2.8.16 still requires
74+
`analyzer` ^13. It moves once `intl_utils` accepts analyzer 14.
75+
- `test` 1.32.0 needs `test_api` 0.7.14, and `flutter_test` on Flutter 3.47 pins
76+
0.7.12. It moves with the SDK.
77+
78+
When an upgrade fails version solving, record the blocker here with
7579
what has to change upstream before the pin can move, so the next
7680
`flutter pub outdated` run does not rediscover it.
7781

0 commit comments

Comments
 (0)