diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0bd1bbe1..301f2cb1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -59,6 +59,7 @@ jobs:
# Seconds of Python, so it runs on everything: the site is generated from Swift sources and project.yml as well
# as from site/, and "docs/ is out of date" should be caught whichever of those moved.
site:
+ needs: changes
# Pinned rather than `ubuntu-latest`: that label moves to Ubuntu 26 in October 2026, and every run has
# been carrying an annotation saying so. A named image means the move happens when we make it, with a
# green run to prove it, rather than on a date somebody else chose. macOS is already pinned the same way.
@@ -141,17 +142,27 @@ jobs:
done <<< "$(sed -n '/^Shipped:/,/^Planned/p' README.md | grep -o '([0-9]\+\.[0-9]\+\.[0-9]\+)' | tr -d '()')"
[ "$bad" -eq 0 ] || exit 1
- test:
+ project-drift:
+ name: project drift
+ needs: changes
+ if: needs.changes.outputs.app == 'true'
+ runs-on: macos-15
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - name: Install XcodeGen
+ run: brew install xcodegen
+
+ - name: Generate the project and reject drift
+ run: scripts/check_xcode_project.sh
+
+ unit-oldest:
+ name: unit (oldest Xcode)
needs: changes
if: needs.changes.outputs.app == 'true'
runs-on: macos-15
- strategy:
- fail-fast: false
- matrix:
- # README says Xcode 16 or later, so both ends of that are built. The oldest one earns its place: it is
- # stricter about expressions the type checker has to explore, and it caught two the newest compiler accepts.
- xcode: [oldest, newest]
- name: test (${{ matrix.xcode }} Xcode)
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
@@ -160,29 +171,61 @@ jobs:
- name: Select Xcode
run: |
set -euo pipefail
- if [[ "${{ matrix.xcode }}" == "newest" ]]; then
- sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | tail -1)"
- else
- sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | head -1)"
- fi
+ sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | head -1)"
xcodebuild -version
- - name: Install XcodeGen
- run: brew install xcodegen
+ # Ad-hoc signing: the entitlements that need a Developer ID profile are only exercised by the release build.
+ - name: Test
+ timeout-minutes: 40
+ run: scripts/run-ci-tests.sh
- - name: Generate the project and reject drift
- run: scripts/check_xcode_project.sh
+ unit-newest:
+ name: unit (newest Xcode)
+ needs: changes
+ if: needs.changes.outputs.app == 'true'
+ runs-on: macos-15
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - name: Select Xcode
+ run: |
+ set -euo pipefail
+ sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | tail -1)"
+ xcodebuild -version
- name: Check release helpers, catalog policy, and warning gate
- if: matrix.xcode == 'newest'
run: |
scripts/test-notarize.sh
scripts/test-rule-pack-policy.sh
scripts/test-swift-warnings.sh
+ scripts/test-codeql-gate.sh
python3 -I scripts/test_classify_changes.py
python3 -I scripts/test_check_site.py
python3 scripts/test_release_checks.py
+ # Ad-hoc signing: the entitlements that need a Developer ID profile are only exercised by the release build.
+ - name: Test
+ timeout-minutes: 40
+ run: scripts/run-ci-tests.sh
+
+ store:
+ name: store
+ needs: changes
+ if: needs.changes.outputs.app == 'true'
+ runs-on: macos-15
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - name: Select newest Xcode
+ run: |
+ set -euo pipefail
+ sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | tail -1)"
+ xcodebuild -version
+
# This compiles a different product graph and activation path from the Developer ID build. The build clears
# protected entitlements because CI has no Store profiles; the next step re-signs the isolated product with the
# repository plists so the product gate still inspects the actual executable entitlements it is meant to police.
@@ -210,66 +253,6 @@ jobs:
codesign --force --sign - --entitlements Flowlight/Flowlight-AppStore.entitlements "$APP"
scripts/check_app_store_product.sh "$APP"
- # Ad-hoc signing: the entitlements that need a Developer ID profile are only exercised by the release build.
- - name: Test
- timeout-minutes: 40
- run: |
- # GitHub runs this step under `bash -e`, so the first failing command ends it. That killed the whole
- # point of the reporting below: a failing test exited 65 with no output at all, and the log saying
- # which test failed was thrown away with the runner. `set +e` has to be explicit — the `set` line
- # below can't clear a flag the shell was started with.
- set +e
- set -uo pipefail
- # xcodebuild occasionally never returns here — the same suite passes locally and on most runs, and the
- # per-test allowance below doesn't always catch it, so the whole invocation gets a watchdog. One retry:
- # a hang that clears on a second attempt is a flake, and one that repeats is a real failure worth seeing.
- run_tests() {
- local log="$1" limit=900
- xcodebuild test -project Flowlight.xcodeproj -scheme Flowlight -destination 'platform=macOS' \
- -test-timeouts-enabled YES \
- -default-test-execution-time-allowance 120 \
- -maximum-test-execution-time-allowance 300 \
- CODE_SIGN_IDENTITY=- CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM= CODE_SIGN_ENTITLEMENTS= > "$log" 2>&1 &
- local pid=$!
- local waited=0
- while kill -0 "$pid" 2>/dev/null; do
- if [ "$waited" -ge "$limit" ]; then
- echo "::warning::xcodebuild still running after ${limit}s — killing it."
- kill -9 "$pid" 2>/dev/null
- pkill -9 -f "xcodebuild|XCTestCore|testmanagerd" 2>/dev/null
- wait "$pid" 2>/dev/null
- return 124
- fi
- sleep 5
- waited=$((waited + 5))
- done
- wait "$pid"
- }
-
- LOG="$RUNNER_TEMP/test.log"
- run_tests "$LOG"
- status=$?
- grep -E "Test Case .* (passed|failed)|Executed .* tests|\*\* TEST" "$LOG" | tail -25
-
- if [ "$status" -eq 124 ]; then
- echo "::group::Where it stopped (last 60 lines before the kill)"; tail -60 "$LOG"; echo "::endgroup::"
- echo "Retrying once."
- LOG="$RUNNER_TEMP/test-retry.log"
- run_tests "$LOG"
- status=$?
- grep -E "Executed .* tests|\*\* TEST" "$LOG" | tail -10
- fi
-
- if [ "$status" -ne 0 ]; then
- echo "::group::Last 300 lines"; tail -300 "$LOG"; echo "::endgroup::"
- echo "Why it failed (status $status):"
- # Outside the group, so it is the first thing visible on a failed run.
- grep -E "error:|Testing failed:|XCTAssert.*failed|exceeded execution time allowance" "$LOG" | head -40
- exit 1
- fi
- set -e
- scripts/check-swift-warnings.sh "$LOG"
-
# Exact-head evidence proves what was reviewed; this separate PR-only build proves that same head still compiles
# when combined with the current base. The trees are intentionally different, so this is not duplicate work.
merge-compatibility:
@@ -293,14 +276,17 @@ jobs:
gate:
name: Review / gate
if: always()
- needs: [changes, site, test, merge-compatibility]
+ needs: [changes, site, project-drift, unit-oldest, unit-newest, store, merge-compatibility]
runs-on: ubuntu-24.04
steps:
- name: Require every applicable review job
env:
CHANGES_RESULT: ${{ needs.changes.result }}
SITE_RESULT: ${{ needs.site.result }}
- TEST_RESULT: ${{ needs.test.result }}
+ PROJECT_DRIFT_RESULT: ${{ needs.project-drift.result }}
+ UNIT_OLDEST_RESULT: ${{ needs.unit-oldest.result }}
+ UNIT_NEWEST_RESULT: ${{ needs.unit-newest.result }}
+ STORE_RESULT: ${{ needs.store.result }}
MERGE_RESULT: ${{ needs.merge-compatibility.result }}
EVENT_NAME: ${{ github.event_name }}
APP_ROUTE: ${{ needs.changes.outputs.app }}
@@ -318,13 +304,21 @@ jobs:
echo "::error::Site verification did not succeed: $SITE_RESULT"
exit 1
}
- case "$APP_ROUTE:$TEST_RESULT" in
- true:success|false:skipped) ;;
- *)
- echo "::error::Application route $APP_ROUTE produced test result $TEST_RESULT."
- exit 1
- ;;
- esac
+ for result in \
+ "project drift:$PROJECT_DRIFT_RESULT" \
+ "oldest unit:$UNIT_OLDEST_RESULT" \
+ "newest unit:$UNIT_NEWEST_RESULT" \
+ "store:$STORE_RESULT"; do
+ name=${result%%:*}
+ conclusion=${result#*:}
+ case "$APP_ROUTE:$conclusion" in
+ true:success|false:skipped) ;;
+ *)
+ echo "::error::Application route $APP_ROUTE produced $name result $conclusion."
+ exit 1
+ ;;
+ esac
+ done
if [[ "$EVENT_NAME" == pull_request && "$APP_ROUTE" == true ]]; then
[[ "$MERGE_RESULT" == success ]] || {
echo "::error::Prospective-merge compatibility did not succeed: $MERGE_RESULT"
@@ -336,7 +330,11 @@ jobs:
exit 1
}
fi
- [[ -n "$HEAD_SHA" && -n "$TREE" && -n "$FINGERPRINT" && -n "$SCHEMA" ]] || {
+ [[ "$SCHEMA" == flowlight-review-v2 ]] || {
+ echo "::error::Unexpected review receipt schema: $SCHEMA"
+ exit 1
+ }
+ [[ -n "$HEAD_SHA" && -n "$TREE" && -n "$FINGERPRINT" ]] || {
echo "::error::The review receipt identity is incomplete."
exit 1
}
@@ -351,14 +349,18 @@ jobs:
--arg app_route "$APP_ROUTE" \
--arg changes "$CHANGES_RESULT" \
--arg site "$SITE_RESULT" \
- --arg tests "$TEST_RESULT" \
+ --arg project_drift "$PROJECT_DRIFT_RESULT" \
+ --arg unit_oldest "$UNIT_OLDEST_RESULT" \
+ --arg unit_newest "$UNIT_NEWEST_RESULT" \
+ --arg store "$STORE_RESULT" \
--arg merge_compatibility "$MERGE_RESULT" \
--arg run_id "${{ github.run_id }}" \
--arg run_attempt "${{ github.run_attempt }}" \
'{schema: $schema, repository: $repository, workflow: $workflow, event: $event,
source_sha: $source_sha, source_tree: $source_tree, app_fingerprint: $app_fingerprint,
app_route: $app_route,
- conclusions: {changes: $changes, site: $site, tests: $tests,
+ conclusions: {changes: $changes, site: $site, project_drift: $project_drift,
+ unit_oldest: $unit_oldest, unit_newest: $unit_newest, store: $store,
merge_compatibility: $merge_compatibility},
run_id: $run_id, run_attempt: $run_attempt}' \
> "$RUNNER_TEMP/review-receipt.json"
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 0ae7052a..79be96d3 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -1,10 +1,7 @@
# CodeQL code scanning.
#
-# This exists as a workflow rather than as GitHub's default setup for one reason: the Xcode project is not
-# committed. XcodeGen writes it from project.yml, so `autobuild` looked for a project or workspace, found
-# neither, and gave up with `no-project-found`. The reaction to that failure was to drop Swift from the
-# languages being scanned, which left the one language worth scanning in a tool that reads other people's
-# network traffic unscanned. Swift is built here explicitly instead.
+# This exists as a workflow rather than as GitHub's default setup for one reason: Swift must be built explicitly.
+# XcodeGen's committed project is prepared before CodeQL tracing begins so Homebrew never runs under Rosetta.
#
# Requires GitHub's default setup to be turned OFF for this repository (Settings › Code security › Code
# scanning), because the two configurations cannot both be active.
@@ -27,65 +24,101 @@ concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
- analyze:
- name: analyze (${{ matrix.language }})
- runs-on: ${{ matrix.runner }}
+ classify:
+ name: classify
+ runs-on: ubuntu-24.04
+ outputs:
+ app: ${{ steps.route.outputs.app || 'true' }}
+ python: ${{ steps.route.outputs.python || 'true' }}
+ actions: ${{ steps.route.outputs.actions || 'true' }}
+ steps:
+ - id: checkout
+ if: github.event_name == 'push' || github.event_name == 'pull_request'
+ continue-on-error: true
+ uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ # Code scanning reports against the PR head, so classify that exact commit rather than the merge ref.
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+ fetch-depth: 0
+
+ - id: what
+ name: Classify the exact change
+ if: steps.checkout.outcome == 'success'
+ continue-on-error: true
+ env:
+ BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
+ HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+ run: |
+ set -euo pipefail
+ python3 -I scripts/classify_changes.py \
+ --repo . --base "$BASE_SHA" --head "$HEAD_SHA" --github-output "$GITHUB_OUTPUT" \
+ > "$RUNNER_TEMP/codeql-classification.json"
+ cat "$RUNNER_TEMP/codeql-classification.json"
+
+ - id: route
+ name: Route language analysis fail closed
+ if: always()
+ env:
+ EVENT_NAME: ${{ github.event_name }}
+ CHECKOUT_OUTCOME: ${{ steps.checkout.outcome }}
+ CLASSIFIER_OUTCOME: ${{ steps.what.outcome }}
+ APP_ROUTE: ${{ steps.what.outputs.app }}
+ PYTHON_ROUTE: ${{ steps.what.outputs.python }}
+ ACTIONS_ROUTE: ${{ steps.what.outputs.actions }}
+ run: |
+ set -euo pipefail
+ if [[ "$EVENT_NAME" == schedule || "$EVENT_NAME" == workflow_dispatch ]]; then
+ app=true
+ python=true
+ actions=true
+ elif [[ "$CHECKOUT_OUTCOME" == success && "$CLASSIFIER_OUTCOME" == success &&
+ "$APP_ROUTE" =~ ^(true|false)$ && "$PYTHON_ROUTE" =~ ^(true|false)$ &&
+ "$ACTIONS_ROUTE" =~ ^(true|false)$ ]]; then
+ app=$APP_ROUTE
+ python=$PYTHON_ROUTE
+ actions=$ACTIONS_ROUTE
+ else
+ echo "::warning::CodeQL classification failed; routing every language."
+ app=true
+ python=true
+ actions=true
+ fi
+ echo "app=$app" >> "$GITHUB_OUTPUT"
+ echo "python=$python" >> "$GITHUB_OUTPUT"
+ echo "actions=$actions" >> "$GITHUB_OUTPUT"
+
+ analyze-swift:
+ name: analyze (swift)
+ needs: classify
+ if: always() && needs.classify.outputs.app == 'true'
+ runs-on: macos-15
timeout-minutes: 60
permissions:
- security-events: write # the only reason this workflow needs more than read
+ security-events: write
contents: read
- strategy:
- fail-fast: false
- matrix:
- include:
- # Swift has to be built, and only a macOS runner can. See the header.
- - language: swift
- runner: macos-15
- build-mode: manual
- # The site generator, the packaging scripts and the workflows themselves. Nothing to build.
- - language: python
- runner: ubuntu-24.04
- build-mode: none
- - language: actions
- runner: ubuntu-24.04
- build-mode: none
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
- # Code scanning reports against the PR head, so compile that exact commit rather than the merge ref.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- # Everything that is not the compilation happens before init, and deliberately so. Once init has run,
- # CodeQL traces the job by preloading an x86_64 libtrace.dylib through DYLD_INSERT_LIBRARIES, which puts
- # every child process under Rosetta 2 — and Homebrew refuses to install an x86_64 build into the ARM
- # prefix: "Cannot install under Rosetta 2 in ARM default prefix". Generating the project needs no tracing
- # anyway; only the compiler does.
+ # Everything that is not compilation happens before init. Once init runs, CodeQL tracing preloads an x86_64
+ # library through DYLD_INSERT_LIBRARIES, putting child processes under Rosetta where ARM Homebrew refuses work.
- name: Prepare the project
- if: matrix.build-mode == 'manual'
run: |
set -euo pipefail
- # Newest Xcode only. CI's test job covers the oldest-supported compiler; this build exists to give
- # CodeQL something to trace, and tracing it twice would double the cost for the same findings.
sudo xcode-select -s "$(ls -d /Applications/Xcode*.app | sort -V | tail -1)"
xcodebuild -version
- # Analyze the exact committed graph that CI reviewed and Xcode Cloud discovers.
xcodebuild -project Flowlight.xcodeproj -list >/dev/null
- uses: github/codeql-action/init@7999b86c43a865dc79d8923397f35af22de63401 # v4
with:
- languages: ${{ matrix.language }}
- build-mode: ${{ matrix.build-mode }}
- # security-extended over the default suite: this app holds decrypted request bodies and a CA key, so
- # the extra precision-medium queries are worth the false positives they bring.
+ languages: swift
+ build-mode: manual
queries: security-extended
- name: Build for analysis
- if: matrix.build-mode == 'manual'
run: |
set -euo pipefail
- # Signing off, as in the test job: analysis needs the compilation, not a runnable app. `clean build`
- # rather than `build`, because CodeQL only sees the files the compiler actually recompiles and an
- # incremental build would hand it a fraction of the sources.
xcodebuild clean build \
-project Flowlight.xcodeproj \
-scheme Flowlight \
@@ -94,4 +127,73 @@ jobs:
- uses: github/codeql-action/analyze@7999b86c43a865dc79d8923397f35af22de63401 # v4
with:
- category: /language:${{ matrix.language }}
+ category: /language:swift
+
+ analyze-python:
+ name: analyze (python)
+ needs: classify
+ if: always() && needs.classify.outputs.python == 'true'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 60
+ permissions:
+ security-events: write
+ contents: read
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - uses: github/codeql-action/init@7999b86c43a865dc79d8923397f35af22de63401 # v4
+ with:
+ languages: python
+ build-mode: none
+ queries: security-extended
+
+ - uses: github/codeql-action/analyze@7999b86c43a865dc79d8923397f35af22de63401 # v4
+ with:
+ category: /language:python
+
+ analyze-actions:
+ name: analyze (actions)
+ needs: classify
+ if: always() && needs.classify.outputs.actions == 'true'
+ runs-on: ubuntu-24.04
+ timeout-minutes: 60
+ permissions:
+ security-events: write
+ contents: read
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - uses: github/codeql-action/init@7999b86c43a865dc79d8923397f35af22de63401 # v4
+ with:
+ languages: actions
+ build-mode: none
+ queries: security-extended
+
+ - uses: github/codeql-action/analyze@7999b86c43a865dc79d8923397f35af22de63401 # v4
+ with:
+ category: /language:actions
+
+ gate:
+ name: CodeQL / gate
+ if: always()
+ needs: [classify, analyze-swift, analyze-python, analyze-actions]
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
+ with:
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
+
+ - name: Require successful classification and every routed language
+ env:
+ CLASSIFY_RESULT: ${{ needs.classify.result }}
+ SWIFT_ROUTE: ${{ needs.classify.outputs.app }}
+ PYTHON_ROUTE: ${{ needs.classify.outputs.python }}
+ ACTIONS_ROUTE: ${{ needs.classify.outputs.actions }}
+ SWIFT_RESULT: ${{ needs.analyze-swift.result }}
+ PYTHON_RESULT: ${{ needs.analyze-python.result }}
+ ACTIONS_RESULT: ${{ needs.analyze-actions.result }}
+ run: scripts/check-codeql-gate.sh
diff --git a/Flowlight.xcodeproj/project.pbxproj b/Flowlight.xcodeproj/project.pbxproj
index 16006e3e..085efa62 100644
--- a/Flowlight.xcodeproj/project.pbxproj
+++ b/Flowlight.xcodeproj/project.pbxproj
@@ -2252,7 +2252,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 76;
+ CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@@ -2267,7 +2267,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 15.0;
- MARKETING_VERSION = 0.17.2;
+ MARKETING_VERSION = 0.17.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2313,7 +2313,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 76;
+ CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 38RJUJHKZS;
ENABLE_HARDENED_RUNTIME = YES;
@@ -2328,7 +2328,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 15.0;
- MARKETING_VERSION = 0.17.2;
+ MARKETING_VERSION = 0.17.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2393,7 +2393,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 76;
+ CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
@@ -2414,7 +2414,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 15.0;
- MARKETING_VERSION = 0.17.2;
+ MARKETING_VERSION = 0.17.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
diff --git a/Flowlight/App/AppNavigation.swift b/Flowlight/App/AppNavigation.swift
index 8f4f38d2..fc5e1617 100644
--- a/Flowlight/App/AppNavigation.swift
+++ b/Flowlight/App/AppNavigation.swift
@@ -1,7 +1,7 @@
import SwiftUI
enum SidebarItem: String, CaseIterable, Identifiable {
- case live, agents, reports, alerts, rules, ask, inspect, devices, coverage, capture, visualize
+ case live, agents, reports, alerts, rules, ask, inspect, sources, visualize
var id: String { rawValue }
static var availableCases: [SidebarItem] {
@@ -27,9 +27,7 @@ enum SidebarItem: String, CaseIterable, Identifiable {
case .rules: return "rules"
case .ask: return "ask"
case .inspect: return "inspection"
- case .devices: return "devices"
- case .coverage: return "coverage"
- case .capture: return "capture"
+ case .sources: return "sources"
}
}
@@ -45,9 +43,7 @@ enum SidebarItem: String, CaseIterable, Identifiable {
case .rules: return "Rules"
case .ask: return "Ask"
case .inspect: return "Inspect"
- case .devices: return "Devices"
- case .coverage: return "Coverage"
- case .capture: return "Capture"
+ case .sources: return "Sources"
}
}
@@ -60,10 +56,8 @@ enum SidebarItem: String, CaseIterable, Identifiable {
case .alerts: return L("Alerts")
case .rules: return L("Rules")
case .ask: return L("Ask")
- case .devices: return L("Devices")
- case .coverage: return L("Coverage")
case .inspect: return L("Inspect")
- case .capture: return L("Capture")
+ case .sources: return L("Sources")
}
}
var icon: String {
@@ -75,10 +69,8 @@ enum SidebarItem: String, CaseIterable, Identifiable {
case .alerts: return "exclamationmark.triangle"
case .rules: return "hand.raised"
case .ask: return "text.bubble"
- case .devices: return "dot.radiowaves.left.and.right"
- case .coverage: return "circle.dashed.inset.filled"
case .inspect: return "lock.open.display"
- case .capture: return "antenna.radiowaves.left.and.right"
+ case .sources: return "antenna.radiowaves.left.and.right"
}
}
/// The exact visual order of the sidebar. Enum declaration order is an implementation detail and used to
@@ -101,7 +93,7 @@ enum SidebarItem: String, CaseIterable, Identifiable {
case .live, .agents, .reports, .visualize, .alerts: return .traffic
case .ask, .inspect: return .investigate
case .rules: return .control
- case .devices, .coverage, .capture: return .sources
+ case .sources: return .sources
}
}
@@ -114,7 +106,7 @@ enum SidebarItem: String, CaseIterable, Identifiable {
return true
case .alerts:
return scope.hosts.isEmpty
- case .ask, .rules, .devices, .coverage, .capture:
+ case .ask, .rules, .sources:
return false
}
}
@@ -145,12 +137,37 @@ enum SidebarSection: String, CaseIterable, Identifiable {
case .traffic: order = [.live, .agents, .reports, .visualize, .alerts]
case .investigate: order = [.ask, .inspect]
case .control: order = [.rules]
- case .sources: order = [.devices, .coverage, .capture]
+ case .sources: order = [.sources]
}
return order.filter { SidebarItem.availableCases.contains($0) }
}
}
+/// The three operational views behind the single Sources destination. Keeping this in shared navigation lets a
+/// status notice open the exact recovery surface without putting three configuration screens back in the sidebar.
+enum SourcesTab: String, CaseIterable, Identifiable, Sendable {
+ case collector, devices, coverage
+
+ var id: String { rawValue }
+
+ @MainActor var title: String {
+ switch self {
+ case .collector: return L("Collector")
+ case .devices: return L("Devices")
+ case .coverage: return L("Coverage")
+ }
+ }
+}
+
+/// Alert review and its detection tuning share a destination, but app-wide alert links must still be able to select
+/// the review list explicitly instead of inheriting whichever tab happened to be visible.
+enum AlertsTab: String, CaseIterable, Identifiable {
+ case alerts, detection
+
+ var id: String { rawValue }
+ @MainActor var title: String { self == .alerts ? L("Alerts") : L("Detection") }
+}
+
/// The three views inside Rules. This lives with the shared navigation state so an app-wide notice can take someone
/// straight to a changed pack, while ordinary rule links always land back on the rule list.
enum RulesTab: String, CaseIterable, Identifiable {
@@ -189,9 +206,25 @@ struct ReportRequest: Equatable {
@MainActor
final class AppNavigation: ObservableObject {
@Published private(set) var selection: SidebarItem = {
- let restored = SidebarItem(rawValue: UserDefaults.standard.string(forKey: "FLScreen") ?? "") ?? .live
+ let raw = UserDefaults.standard.string(forKey: "FLScreen") ?? ""
+ // Preserve restored windows and screenshot arguments from before Devices, Coverage and Capture became tabs.
+ let restored = ["devices", "coverage", "capture"].contains(raw)
+ ? SidebarItem.sources
+ : SidebarItem(rawValue: raw) ?? .live
return SidebarItem.availableCases.contains(restored) ? restored : .live
}()
+ @Published var sourcesTab: SourcesTab = {
+ let defaults = UserDefaults.standard
+ if let explicit = SourcesTab(rawValue: defaults.string(forKey: "FLSourcesTab") ?? "") {
+ return explicit
+ }
+ switch defaults.string(forKey: "FLScreen") {
+ case "devices": return .devices
+ case "coverage": return .coverage
+ default: return .collector
+ }
+ }()
+ @Published var alertsTab: AlertsTab = .alerts
@Published var rulesTab: RulesTab = {
RulesTab(rawValue: UserDefaults.standard.string(forKey: "FLRulesTab") ?? "") ?? .rules
}()
@@ -213,6 +246,7 @@ final class AppNavigation: ObservableObject {
func show(_ item: SidebarItem) {
guard SidebarItem.availableCases.contains(item) else { return }
trail.removeAll()
+ if item == .alerts { alertsTab = .alerts }
if item == .rules { rulesTab = .rules }
selection = item
}
@@ -245,10 +279,19 @@ final class AppNavigation: ObservableObject {
showRules()
}
+ func showAlerts() {
+ show(.alerts)
+ }
+
func showRules() {
show(.rules)
}
+ func showSources(_ tab: SourcesTab = .collector) {
+ sourcesTab = tab
+ show(.sources)
+ }
+
func showPackReviews() {
show(.rules)
rulesTab = .packs
diff --git a/Flowlight/App/FlowlightApp.swift b/Flowlight/App/FlowlightApp.swift
index 98d66b4b..dee23d8a 100644
--- a/Flowlight/App/FlowlightApp.swift
+++ b/Flowlight/App/FlowlightApp.swift
@@ -15,6 +15,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
runStartupIfReady()
}
+ func applicationWillFinishLaunching(_ notification: Notification) {
+ // Screenshot runs need a deterministic appearance even when the reviewing Mac itself uses Dark Mode.
+ // Keep the override demo-only so no launch argument can change the appearance of a real user's app.
+ guard DemoData.isEnabled,
+ UserDefaults.standard.bool(forKey: "FLForceLightAppearance") else { return }
+ NSApp.appearance = NSAppearance(named: .aqua)
+ }
+
func applicationDidFinishLaunching(_ notification: Notification) {
Self.didFinishLaunching = true
Self.runStartupIfReady()
diff --git a/Flowlight/App/TrafficMonitor.swift b/Flowlight/App/TrafficMonitor.swift
index e8c5c4e0..2bd069b3 100644
--- a/Flowlight/App/TrafficMonitor.swift
+++ b/Flowlight/App/TrafficMonitor.swift
@@ -41,8 +41,8 @@ final class TrafficMonitor: ObservableObject {
@Published private(set) var unacknowledgedAlerts = 0
@Published private(set) var captureState: PacketSniffer.State = .stopped
@Published private(set) var hostnamesLearned = 0
- /// Share of traffic in the last hour with a hostname / with at least a network owner.
- @Published private(set) var coverage: (named: Double, owned: Double) = (0, 0)
+ /// Share of traffic in the last hour with a hostname / with at least a network owner, plus whether the window has evidence.
+ @Published private(set) var coverage: (named: Double, owned: Double, hasTraffic: Bool) = (0, 0, false)
let sniffer = PacketSniffer()
/// First-launch offer to enable packet capture.
@Published var showCaptureOnboarding = false
diff --git a/Flowlight/Ask/AskController.swift b/Flowlight/Ask/AskController.swift
index 4fc7f0f5..60864ee8 100644
--- a/Flowlight/Ask/AskController.swift
+++ b/Flowlight/Ask/AskController.swift
@@ -150,7 +150,8 @@ final class AskController: ObservableObject {
do {
let result = try await Self.run(call, db: db, environment: snapshot)
await recorder.finish(call, summary: result.summary, filter: result.filter, from: result.from,
- to: result.to, chart: result.chart, screen: result.screen)
+ to: result.to, chart: result.chart, screen: result.screen,
+ sourcesTab: result.sourcesTab)
return result.json
} catch {
let message = (error as? AskQueryRunner.Failure)?.description ?? error.localizedDescription
@@ -216,7 +217,8 @@ private actor CallRecorder {
}
func finish(_ call: AskCall, summary: String, failed: Bool = false, filter: TrafficFilter? = nil,
- from: Date? = nil, to: Date? = nil, chart: AskChart? = nil, screen: SidebarItem? = nil) {
+ from: Date? = nil, to: Date? = nil, chart: AskChart? = nil, screen: SidebarItem? = nil,
+ sourcesTab: SourcesTab? = nil) {
guard let index = calls.lastIndex(where: { $0.call.id == call.id }) else { return }
calls[index].summary = summary
calls[index].failed = failed
@@ -225,6 +227,7 @@ private actor CallRecorder {
calls[index].to = to
calls[index].chart = chart.flatMap { $0.isEmpty ? nil : $0 }
calls[index].screen = screen
+ calls[index].sourcesTab = sourcesTab
}
func sent(_ body: String) { bodies.append(body) }
diff --git a/Flowlight/Ask/AskProvider.swift b/Flowlight/Ask/AskProvider.swift
index 0cae1b45..bb1c97d5 100644
--- a/Flowlight/Ask/AskProvider.swift
+++ b/Flowlight/Ask/AskProvider.swift
@@ -103,6 +103,8 @@ struct AskRecordedCall: Identifiable, Equatable, Sendable {
var chart: AskChart?
/// Which app screen clicking should open when Reports cannot represent this result.
var screen: SidebarItem?
+ /// The exact operational tab when that destination is Sources.
+ var sourcesTab: SourcesTab? = nil
}
/// What a provider needs to answer. The conversation is only ever the question and the results of queries
diff --git a/Flowlight/Ask/AskQueryRunner.swift b/Flowlight/Ask/AskQueryRunner.swift
index 97215fb2..d7b0a804 100644
--- a/Flowlight/Ask/AskQueryRunner.swift
+++ b/Flowlight/Ask/AskQueryRunner.swift
@@ -22,6 +22,8 @@ enum AskQueryRunner {
var chart: AskChart?
/// Where the answer points for a question about the app rather than about traffic.
var screen: SidebarItem?
+ /// The exact operational tab when that screen is Sources.
+ var sourcesTab: SourcesTab? = nil
}
enum Failure: Error, CustomStringConvertible {
@@ -114,7 +116,7 @@ enum AskQueryRunner {
summary: environment.inspecting
? L("%@, inspection on, %lld rules", environment.captureSource, environment.rules.count)
: L("%@, inspection off, %lld rules", environment.captureSource, environment.rules.count),
- screen: .capture)
+ screen: .sources, sourcesTab: .collector)
}
private static func howTo(_ topic: String) -> Result {
@@ -125,7 +127,8 @@ enum AskQueryRunner {
}
return Result(json: encode(matches.map(\.asDictionary)),
summary: matches.map(\.title).joined(separator: ", "),
- screen: matches.first?.screen)
+ screen: matches.first?.screen,
+ sourcesTab: matches.first?.sourcesTab)
}
/// `what` names the JSON field the model reads, so it stays English; the summary is what the panel shows and
@@ -308,7 +311,7 @@ enum AskQueryRunner {
return Result(json: encode(payload),
summary: rows.isEmpty ? L("no device changes")
: rows.prefix(3).map { L("%@ · %lld changes", $0.name, $0.total) }.joined(separator: ", "),
- from: window.from, to: window.to, screen: .devices)
+ from: window.from, to: window.to, screen: .sources, sourcesTab: .devices)
}
private static func overTime(db: TrafficDatabase, window: (from: Date, to: Date), app: String?,
diff --git a/Flowlight/Ask/FeatureGuide.swift b/Flowlight/Ask/FeatureGuide.swift
index 07fd12da..c0d7a7ac 100644
--- a/Flowlight/Ask/FeatureGuide.swift
+++ b/Flowlight/Ask/FeatureGuide.swift
@@ -19,6 +19,8 @@ struct FeatureGuide: Equatable, Sendable, Identifiable {
var steps: [String]
/// Where it lives, so an answer can offer to go there.
var screen: SidebarItem?
+ /// The operational tab behind Sources, when the destination needs more precision than one sidebar item.
+ var sourcesTab: SourcesTab? = nil
/// What it can't do. Left out of an answer, these are the things people discover the hard way.
var caveats: [String] = []
/// Extra words someone might use for it.
@@ -45,9 +47,10 @@ extension FeatureGuide {
FeatureGuide(
id: "capture", title: "Capture source",
summary: "Where traffic comes from. The Network Extension is a content filter that sits in the data path and attributes every flow to its app; the nettop sampler needs no entitlement but samples once a second and misses flows shorter than that.",
- steps: ["Open Capture.", "Under Capture source, pick Network Extension or nettop sampler.",
+ steps: ["Open Sources and choose Collector.", "Pick Network Extension or nettop sampler.",
"For the extension, press Install & enable filter and approve it in System Settings."],
- screen: .capture,
+ screen: .sources,
+ sourcesTab: .collector,
caveats: ["macOS runs one content filter at a time. If a VPN or a security agent holds that slot, Flowlight's filter installs and connects but is never handed a flow.",
"Only the extension can refuse a connection. The sampler counts traffic after the fact."],
keywords: ["nettop", "network extension", "content filter", "source", "no traffic", "nothing showing"]),
@@ -55,8 +58,9 @@ extension FeatureGuide {
FeatureGuide(
id: "hostnames", title: "Hostnames",
summary: "Turning IP addresses into names. The extension reads TLS SNI and DNS answers itself. On the sampler, a one-time packet-capture setup is what lets Flowlight see those names.",
- steps: ["Open Capture.", "Turn on Read hostnames from the network.", "Give the helper permission when macOS asks."],
- screen: .capture,
+ steps: ["Open Sources and choose Collector.", "Turn on Read hostnames from the network.", "Give the helper permission when macOS asks."],
+ screen: .sources,
+ sourcesTab: .collector,
caveats: ["Without it the sampler falls back to reverse DNS, which is often missing or wrong."],
keywords: ["dns", "sni", "domain", "ip only", "no domain names", "bpf", "packet capture"]),
@@ -136,7 +140,7 @@ extension FeatureGuide {
FeatureGuide(
id: "alerts", title: "Alerts",
summary: "Explainable, per-app alerts: traffic spikes, unusual numbers of destinations, first contact with a domain, sensitive channels, possible exfiltration, agents active while you are away, and refused connections.",
- steps: ["Open Alerts to review them.", "Adjust the thresholds in Settings ⌘, under Detection."],
+ steps: ["Open Alerts to review them.", "Choose Detection there to adjust the thresholds."],
screen: .alerts,
caveats: ["Every app gets a learning period before first-contact and spike rules fire."],
keywords: ["alert", "anomaly", "warning", "threshold", "notification", "exfiltration"]),
@@ -172,8 +176,9 @@ extension FeatureGuide {
FeatureGuide(
id: "devices", title: "Devices: camera, Bluetooth and USB",
summary: "Whether each camera is active, which Bluetooth and USB devices are paired or attached, and when that changed. Every channel is off until you turn it on.",
- steps: ["Open Devices.", "Turn on Watch camera activity, Watch Bluetooth, or Watch USB and external storage."],
- screen: .devices,
+ steps: ["Open Sources and choose Devices.", "Turn on Watch camera activity, Watch Bluetooth, or Watch USB and external storage."],
+ screen: .sources,
+ sourcesTab: .devices,
caveats: ["Camera activity names the camera, not the app using it; Flowlight never reads frames or requests camera access.",
"No Bluetooth or USB byte counts: macOS keeps no per-app accounting for those channels.",
"The Bluetooth app list is who asked for access, not who was granted it."],
@@ -200,9 +205,9 @@ extension FeatureGuide {
FeatureGuide(
id: "data", title: "Your data and retention",
summary: "Everything is a SQLite database in Application Support. Seconds are kept briefly, minutes and hours longer, daily totals indefinitely, alerts for 90 days.",
- steps: ["Open Capture and use Clear all data to delete everything.",
+ steps: ["Open Settings with ⌘, and choose Data & Privacy.", "Use Clear All Data to delete everything.",
"Or remove ~/Library/Application Support/Flowlight."],
- screen: .capture,
+ screen: nil,
keywords: ["delete", "database", "retention", "privacy", "clear", "storage", "disk"]),
FeatureGuide(
@@ -218,7 +223,7 @@ extension FeatureGuide {
guard guide.id == "capture" else { return guide }
var storeGuide = guide
storeGuide.summary = "Where traffic comes from. The Mac App Store build uses Flowlight's content-filter extension to attribute every flow to its app."
- storeGuide.steps = ["Open Capture.", "Under Content filter, press Enable Filter and approve it in System Settings."]
+ storeGuide.steps = ["Open Sources and choose Collector.", "Under Content filter, press Enable Filter and approve it in System Settings."]
storeGuide.caveats = ["macOS runs one content filter at a time. If a VPN or a security agent holds that slot, Flowlight cannot receive traffic."]
storeGuide.keywords = ["network extension", "content filter", "source", "no traffic", "nothing showing"]
return storeGuide
diff --git a/Flowlight/Localization/de.lproj/Localizable.strings b/Flowlight/Localization/de.lproj/Localizable.strings
index 3d41e10d..b5a39be4 100644
--- a/Flowlight/Localization/de.lproj/Localizable.strings
+++ b/Flowlight/Localization/de.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "Geräte";
"Coverage" = "Abdeckung";
"Inspect" = "Inspizieren";
-"Capture" = "Erfassung";
"Traffic" = "Datenverkehr";
"Investigate" = "Untersuchen";
"Control" = "Steuerung";
@@ -87,6 +86,7 @@
"Questions & Answers" = "Fragen & Antworten";
"What Flowlight Reads on This Mac" = "Was Flowlight auf diesem Mac liest";
"Privacy" = "Datenschutz";
+"Data & Privacy" = "Daten & Datenschutz";
"Report an Issue" = "Problem melden";
"Turn Focus Off" = "Fokus aus";
"Turn Focus On" = "Fokus ein";
@@ -634,8 +634,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "Allen aufgezeichneten Datenverkehr, alle Basislinien und Warnungen löschen?";
"Delete everything" = "Alles löschen";
-"nettop sampler · the extension didn't answer" = "nettop-Sampler · die Erweiterung hat nicht geantwortet";
-"Network Extension · unavailable" = "Netzwerkerweiterung · nicht verfügbar";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "Die Filtererweiterung ist nicht erreichbar. Aktiviere sie unter Inhaltsfilter und klicke dann auf Aktualisieren.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — aktiviere Flowlight unter Inhaltsfilter und klicke dann auf Aktualisieren.";
"%@ — the content filter is unavailable" = "%@ — der Inhaltsfilter ist nicht verfügbar";
@@ -644,8 +642,6 @@
"Reconnect to the content filter" = "Erneut mit dem Inhaltsfilter verbinden";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "Wenn ein VPN oder Sicherheitsagent diesen Platz bereits belegt – Palo Alto Networks GlobalProtect, CrowdStrike Falcon und ähnliche verwenden ihn –, kann der Flowlight-Filter keinen Datenverkehr empfangen, bis dieser Filter deaktiviert wird.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "Der Filter antwortet nicht, daher empfängt Flowlight keinen Datenverkehr. Aktiviere ihn unter Inhaltsfilter und klicke dann auf Aktualisieren.";
-"%@ · receiving" = "%@ · empfängt";
-"%@ · nothing arriving yet" = "%@ · noch kommt nichts an";
"Source" = "Quelle";
"Content filter" = "Inhaltsfilter";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Beobachtet geeignete TCP- und UDP-Flows beim Öffnen. Erfordert die Berechtigung für die Netzwerkerweiterung und Ihre Freigabe.";
@@ -702,7 +698,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Ohne dies zeigt der meiste Datenverkehr nur eine IP-Adresse oder einen Netzbetreiber.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight liest DNS-Antworten und TLS-Servernamen auf Ihrer primären Netzwerkschnittstelle, um Verbindungen zu benennen.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "Paketinhalte werden nie gespeichert oder irgendwohin gesendet. Nur Hostnamen werden behalten.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS erlaubt nur Administratoren das Lesen von Paketen, daher wird einmal nach Ihrem Passwort gefragt. Sie können dies jederzeit unter „Erfassung“ entfernen.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS erlaubt nur Administratoren das Lesen von Paketen, daher wird einmal nach Ihrem Passwort gefragt. Sie können dies jederzeit unter „Quellen › Collector“ entfernen.";
"Identify network owners when no hostname is available" = "Netzbetreiber ermitteln, wenn kein Hostname verfügbar ist";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "Standardmäßig aktiv. Sendet öffentliche Ziel-IPs an den DNS-Dienst von Team Cymru. Ausschalten, damit diese Abfragen auf dem Mac bleiben.";
"Not Now" = "Jetzt nicht";
@@ -733,8 +729,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Noch nichts aufgezeichnet";
+"Nothing recorded in the last hour" = "In der letzten Stunde wurde nichts aufgezeichnet";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "Die Abdeckung wird aus dem Datenverkehr berechnet, den Flowlight schon aufgezeichnet hat. Lassen Sie es einen Moment laufen.";
-"%@ of traffic fully accounted for" = "%@ des Datenverkehrs vollständig erfasst";
"How much of this Mac is covered" = "Wie viel von diesem Mac abgedeckt ist";
"HTTPS inspection is on" = "Die HTTPS-Inspektion ist ein";
"HTTPS inspection is off" = "Die HTTPS-Inspektion ist aus";
@@ -782,8 +778,6 @@
"Camera" = "Kamera";
"Started" = "Gestartet";
"Unknown camera" = "Unbekannte Kamera";
-"%@ · nothing active" = "%@ · nichts aktiv";
-"%@ · %lld active" = "%@ · %lld aktiv";
"Watch camera activity" = "Kameraaktivität überwachen";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Bluetooth, USB und Kameraaktivität sind ausgeschaltet, bis Sie sie einschalten. Dafür ist keine neue Berechtigung nötig – sie sind ausgeschaltet, weil ihre Überwachung erweitert, worauf Flowlight schaut, und das sollte Ihre Entscheidung sein, nicht die eines Updates.\n\nBluetooth und USB zeigen, was verbunden ist. Die Kameraaktivität zeigt, ob eine Kamera aktiv ist, nicht welche App sie verwendet. Flowlight öffnet die Kamera nie und liest keine Bilder.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "Keine Nutzdaten und keine erfundene Zuordnung. Bluetooth und USB zeigen Verbindungen, während die Kameraüberwachung nur den Aktivstatus jedes Geräts liest. macOS stellt hier keine öffentliche Identität der App bereit, die die Kamera verwendet. Deshalb nennt Flowlight die Kamera, rät nie bei der App und liest keine Bilder.";
@@ -1035,7 +1029,6 @@
"The network is quiet" = "Das Netzwerk ist ruhig";
"No app has sent or received data in the last few seconds." = "In den letzten Sekunden hat keine App Daten gesendet oder empfangen.";
"Waiting for traffic data" = "Warten auf Verkehrsdaten";
-"Open Capture Settings" = "Erfassungseinstellungen öffnen";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Einen gewählten Endpunkt selbst beantworten, statt die Anfrage zum Server zu lassen – ein 500, ein Rate-Limit, ein fehlerhafter Body oder eine lange Wartezeit – und beobachten, wie der Agent damit umgeht.";
@@ -1257,8 +1250,8 @@
"Until I resume" = "Bis ich fortsetze";
"Pause Blocking" = "Blockieren pausieren";
"Stand every rule down for a while, without deleting anything" = "Alle Regeln vorübergehend außer Kraft setzen, ohne etwas zu löschen";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "Eine Regel wird beobachtet, aber nicht durchgesetzt. Nur die Netzwerkerweiterung sitzt im Datenpfad und kann eine Verbindung verweigern; der nettop-Sampler zählt Datenverkehr im Nachhinein. Wählen Sie unter „Erfassung“ die Netzwerkerweiterung, um diese Regeln durchzusetzen.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld Regeln werden beobachtet, aber nicht durchgesetzt. Nur die Netzwerkerweiterung sitzt im Datenpfad und kann eine Verbindung verweigern; der nettop-Sampler zählt Datenverkehr im Nachhinein. Wählen Sie unter „Erfassung“ die Netzwerkerweiterung, um diese Regeln durchzusetzen.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "Eine Regel wird beobachtet, aber nicht durchgesetzt. Nur die Netzwerkerweiterung sitzt im Datenpfad und kann eine Verbindung verweigern; der nettop-Sampler zählt Datenverkehr im Nachhinein. Wählen Sie unter „Quellen › Collector“ die Netzwerkerweiterung, um diese Regeln durchzusetzen.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld Regeln werden beobachtet, aber nicht durchgesetzt. Nur die Netzwerkerweiterung sitzt im Datenpfad und kann eine Verbindung verweigern; der nettop-Sampler zählt Datenverkehr im Nachhinein. Wählen Sie unter „Quellen › Collector“ die Netzwerkerweiterung, um diese Regeln durchzusetzen.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "Eine Regel wird beobachtet, aber nicht durchgesetzt – eine Regel, die einen Pfad benennt, lässt sich nur mit HTTPS-Inspektion abgleichen, und die ist aus.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld Regeln werden beobachtet, aber nicht durchgesetzt – eine Regel, die einen Pfad benennt, lässt sich nur mit HTTPS-Inspektion abgleichen, und die ist aus.";
"In force" = "In Kraft";
@@ -1308,7 +1301,7 @@
"Apply a Template" = "Vorlage anwenden";
"%@ · in force at once" = "%@ · sofort in Kraft";
"%@ · shown first" = "%@ · wird erst angezeigt";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Jede schreibt gewöhnliche Regeln in die Liste, wo sie wie alles andere gelesen, ausgeschaltet oder gelöscht werden können. Verbindungen zu verweigern ist Aufgabe der Netzwerkerweiterung; ist in der Erfassung der nettop-Sampler gewählt, werden diese Regeln nur beobachtet statt durchgesetzt.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Jede schreibt gewöhnliche Regeln in die Liste, wo sie wie alles andere gelesen, ausgeschaltet oder gelöscht werden können. Verbindungen zu verweigern ist Aufgabe der Netzwerkerweiterung; ist unter Quellen › Collector der nettop-Sampler gewählt, werden diese Regeln nur beobachtet statt durchgesetzt.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Optional. Leer gelassen gilt dies für alles auf dem Mac; eine genannte App schränkt es auf diese App und die von ihr gestarteten Tools ein.";
"A domain, an IP address, or a range" = "Eine Domain, eine IP-Adresse oder ein Bereich";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "Diese benennen eine HTTP-Methode, daher kann nur die HTTPS-Inspektion sie durchsetzen. Ist sie aus, stehen sie beobachtend in der Liste.";
diff --git a/Flowlight/Localization/en.lproj/Localizable.strings b/Flowlight/Localization/en.lproj/Localizable.strings
index 84397c40..89b0a0f2 100644
--- a/Flowlight/Localization/en.lproj/Localizable.strings
+++ b/Flowlight/Localization/en.lproj/Localizable.strings
@@ -73,7 +73,6 @@
"Devices" = "Devices";
"Coverage" = "Coverage";
"Inspect" = "Inspect";
-"Capture" = "Capture";
"Traffic" = "Traffic";
"Investigate" = "Investigate";
"Control" = "Control";
@@ -89,6 +88,7 @@
"Questions & Answers" = "Questions & Answers";
"What Flowlight Reads on This Mac" = "What Flowlight Reads on This Mac";
"Privacy" = "Privacy";
+"Data & Privacy" = "Data & Privacy";
"Report an Issue" = "Report an Issue";
"Turn Focus Off" = "Turn Focus Off";
"Turn Focus On" = "Turn Focus On";
@@ -606,8 +606,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "Delete all recorded traffic, baselines and alerts?";
"Delete everything" = "Delete everything";
-"nettop sampler · the extension didn't answer" = "nettop sampler · the extension didn't answer";
-"Network Extension · unavailable" = "Network Extension · unavailable";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "Couldn't reach the filter extension. Enable it under Content filter, then press Refresh.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — enable Flowlight under Content filter, then press Refresh.";
"%@ — the content filter is unavailable" = "%@ — the content filter is unavailable";
@@ -616,8 +614,6 @@
"Reconnect to the content filter" = "Reconnect to the content filter";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh.";
-"%@ · receiving" = "%@ · receiving";
-"%@ · nothing arriving yet" = "%@ · nothing arriving yet";
"Source" = "Source";
"Content filter" = "Content filter";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval.";
@@ -674,7 +670,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Without this, most traffic shows only an IP address or network owner.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight reads DNS answers and TLS server names on your primary network interface to name connections.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "Packet contents are never stored or sent anywhere. Only hostnames are kept.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector.";
"Identify network owners when no hostname is available" = "Identify network owners when no hostname is available";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac.";
"Not Now" = "Not Now";
@@ -705,8 +701,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Nothing recorded yet";
+"Nothing recorded in the last hour" = "Nothing recorded in the last hour";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment.";
-"%@ of traffic fully accounted for" = "%@ of traffic fully accounted for";
"How much of this Mac is covered" = "How much of this Mac is covered";
"HTTPS inspection is on" = "HTTPS inspection is on";
"HTTPS inspection is off" = "HTTPS inspection is off";
@@ -754,8 +750,6 @@
"Camera" = "Camera";
"Started" = "Started";
"Unknown camera" = "Unknown camera";
-"%@ · nothing active" = "%@ · nothing active";
-"%@ · %lld active" = "%@ · %lld active";
"Watch camera activity" = "Watch camera activity";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames.";
@@ -984,7 +978,6 @@
"The network is quiet" = "The network is quiet";
"No app has sent or received data in the last few seconds." = "No app has sent or received data in the last few seconds.";
"Waiting for traffic data" = "Waiting for traffic data";
-"Open Capture Settings" = "Open Capture Settings";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it.";
@@ -1189,8 +1182,8 @@
"Until I resume" = "Until I resume";
"Pause Blocking" = "Pause Blocking";
"Stand every rule down for a while, without deleting anything" = "Stand every rule down for a while, without deleting anything";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off.";
"In force" = "In force";
@@ -1240,7 +1233,7 @@
"Apply a Template" = "Apply a Template";
"%@ · in force at once" = "%@ · in force at once";
"%@ · shown first" = "%@ · shown first";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started.";
"A domain, an IP address, or a range" = "A domain, an IP address, or a range";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching.";
diff --git a/Flowlight/Localization/es.lproj/Localizable.strings b/Flowlight/Localization/es.lproj/Localizable.strings
index 97a8f55a..3cda2c08 100644
--- a/Flowlight/Localization/es.lproj/Localizable.strings
+++ b/Flowlight/Localization/es.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "Dispositivos";
"Coverage" = "Cobertura";
"Inspect" = "Inspeccionar";
-"Capture" = "Captura";
"Traffic" = "Tráfico";
"Investigate" = "Investigar";
"Control" = "Control";
@@ -87,6 +86,7 @@
"Questions & Answers" = "Preguntas y respuestas";
"What Flowlight Reads on This Mac" = "Qué lee Flowlight en este Mac";
"Privacy" = "Privacidad";
+"Data & Privacy" = "Datos y privacidad";
"Report an Issue" = "Informar de un problema";
"Turn Focus Off" = "Desactivar el foco";
"Turn Focus On" = "Activar el foco";
@@ -634,8 +634,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "¿Eliminar todo el tráfico registrado, las líneas base y las alertas?";
"Delete everything" = "Eliminar todo";
-"nettop sampler · the extension didn't answer" = "Muestreador nettop · la extensión no ha respondido";
-"Network Extension · unavailable" = "Extensión de red · no disponible";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "No se pudo acceder a la extensión de filtro. Actívala en Filtro de contenido y pulsa Actualizar.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — activa Flowlight en Filtro de contenido y pulsa Actualizar.";
"%@ — the content filter is unavailable" = "%@ — el filtro de contenido no está disponible";
@@ -644,8 +642,6 @@
"Reconnect to the content filter" = "Volver a conectar con el filtro de contenido";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "Si una VPN o un agente de seguridad ya ocupa ese espacio —Palo Alto Networks GlobalProtect, CrowdStrike Falcon y otros similares lo utilizan—, el filtro de Flowlight no podrá recibir tráfico hasta que se desactive dicho filtro.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "El filtro no responde, por lo que Flowlight no recibe tráfico. Actívalo en Filtro de contenido y pulsa Actualizar.";
-"%@ · receiving" = "%@ · recibiendo";
-"%@ · nothing arriving yet" = "%@ · todavía no llega nada";
"Source" = "Fuente";
"Content filter" = "Filtro de contenido";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Observa los flujos TCP y UDP admitidos en el momento en que se abren. Requiere el permiso de la extensión de red y tu autorización.";
@@ -702,7 +698,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Sin esto, la mayor parte del tráfico solo muestra una dirección IP o el propietario de la red.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight lee las respuestas DNS y los nombres de servidor TLS de tu interfaz de red principal para dar nombre a las conexiones.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "El contenido de los paquetes nunca se guarda ni se envía a ningún sitio. Solo se conservan los nombres de host.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS solo permite leer los paquetes a los administradores, así que esto pide tu contraseña una vez. Puedes quitarlo en cualquier momento en Captura.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS solo permite leer los paquetes a los administradores, así que esto pide tu contraseña una vez. Puedes quitarlo en cualquier momento en Fuentes › Colector.";
"Identify network owners when no hostname is available" = "Identificar el propietario de la red cuando no hay nombre de host";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "Activado por omisión. Envía las IP públicas de destino al servicio DNS de Team Cymru. Si se desactiva, estas consultas no salen de tu Mac.";
"Not Now" = "Ahora no";
@@ -733,8 +729,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Aún no se ha registrado nada";
+"Nothing recorded in the last hour" = "No se ha registrado nada en la última hora";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "La cobertura se calcula a partir del tráfico que Flowlight ya ha registrado. Déjalo funcionando un momento.";
-"%@ of traffic fully accounted for" = "%@ del tráfico contabilizado por completo";
"How much of this Mac is covered" = "Cuánto de este Mac está cubierto";
"HTTPS inspection is on" = "La inspección HTTPS está activada";
"HTTPS inspection is off" = "La inspección HTTPS está desactivada";
@@ -782,8 +778,6 @@
"Camera" = "Cámara";
"Started" = "Iniciada";
"Unknown camera" = "Cámara desconocida";
-"%@ · nothing active" = "%@ · nada activo";
-"%@ · %lld active" = "%@ · %lld activos";
"Watch camera activity" = "Vigilar la actividad de la cámara";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "El Bluetooth, el USB y la actividad de la cámara están desactivados hasta que los actives. No necesitan ningún permiso nuevo: están desactivados porque vigilarlos amplía lo que Flowlight observa, y esa decisión debe ser tuya, no de una actualización.\n\nEl Bluetooth y el USB muestran qué está conectado. La actividad de la cámara indica si cada cámara está activa, no qué app la está usando. Flowlight nunca abre la cámara ni lee fotogramas.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "Sin cargas útiles ni atribuciones inventadas. El Bluetooth y el USB muestran las conexiones, mientras que la vigilancia de la cámara solo lee el estado activo de cada dispositivo. macOS no revela aquí públicamente qué app utiliza la cámara, por lo que Flowlight identifica la cámara, nunca adivina la app y nunca lee fotogramas.";
@@ -1035,7 +1029,6 @@
"The network is quiet" = "La red está tranquila";
"No app has sent or received data in the last few seconds." = "Ninguna app ha enviado ni recibido datos en los últimos segundos.";
"Waiting for traffic data" = "Esperando datos de tráfico";
-"Open Capture Settings" = "Abrir los ajustes de captura";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Responder a un endpoint elegido desde Flowlight en lugar de dejar que la petición llegue al servidor —un 500, un límite de peticiones, un cuerpo mal formado o una espera larga— y ver qué hace el agente al respecto.";
@@ -1257,8 +1250,8 @@
"Until I resume" = "Hasta que lo reanude";
"Pause Blocking" = "Pausar el bloqueo";
"Stand every rule down for a while, without deleting anything" = "Suspender todas las reglas un rato, sin eliminar nada";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "Una regla se está vigilando, pero no se aplica. Solo la extensión de red está en el camino de los datos y puede rechazar una conexión; el muestreador nettop cuenta el tráfico a posteriori. Selecciona la extensión de red en Captura para aplicar estas reglas.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld reglas se están vigilando, pero no se aplican. Solo la extensión de red está en el camino de los datos y puede rechazar una conexión; el muestreador nettop cuenta el tráfico a posteriori. Selecciona la extensión de red en Captura para aplicar estas reglas.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "Una regla se está vigilando, pero no se aplica. Solo la extensión de red está en el camino de los datos y puede rechazar una conexión; el muestreador nettop cuenta el tráfico a posteriori. Selecciona la extensión de red en Fuentes › Colector para aplicar estas reglas.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld reglas se están vigilando, pero no se aplican. Solo la extensión de red está en el camino de los datos y puede rechazar una conexión; el muestreador nettop cuenta el tráfico a posteriori. Selecciona la extensión de red en Fuentes › Colector para aplicar estas reglas.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "Una regla se está vigilando, pero no se aplica: una regla que nombra una ruta solo puede compararse con la inspección HTTPS, y está desactivada.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld reglas se están vigilando, pero no se aplican: una regla que nombra una ruta solo puede compararse con la inspección HTTPS, y está desactivada.";
"In force" = "En vigor";
@@ -1308,7 +1301,7 @@
"Apply a Template" = "Aplicar una plantilla";
"%@ · in force at once" = "%@ · en vigor de inmediato";
"%@ · shown first" = "%@ · se muestran primero";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Cada una escribe reglas normales en la lista, donde pueden leerse, desactivarse o eliminarse como cualquier otra. Rechazar una conexión es tarea de la extensión de red, así que con el muestreador nettop seleccionado en Captura estas reglas se vigilan en lugar de aplicarse.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Cada una escribe reglas normales en la lista, donde pueden leerse, desactivarse o eliminarse como cualquier otra. Rechazar una conexión es tarea de la extensión de red, así que con el muestreador nettop seleccionado en Fuentes › Colector estas reglas se vigilan en lugar de aplicarse.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Opcional. Si se deja vacío, se aplica a todo el Mac; nombrar una app lo limita a esa app y a las herramientas que haya iniciado.";
"A domain, an IP address, or a range" = "Un dominio, una dirección IP o un rango";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "Estas nombran un método HTTP, así que solo la inspección HTTPS puede aplicarlas. Con ella desactivada, se quedan en la lista vigilando.";
diff --git a/Flowlight/Localization/fr.lproj/Localizable.strings b/Flowlight/Localization/fr.lproj/Localizable.strings
index 8c1b399a..77d49d96 100644
--- a/Flowlight/Localization/fr.lproj/Localizable.strings
+++ b/Flowlight/Localization/fr.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "Appareils";
"Coverage" = "Couverture";
"Inspect" = "Inspecter";
-"Capture" = "Capture";
"Traffic" = "Trafic";
"Investigate" = "Analyser";
"Control" = "Contrôle";
@@ -87,6 +86,7 @@
"Questions & Answers" = "Questions et réponses";
"What Flowlight Reads on This Mac" = "Ce que Flowlight lit sur ce Mac";
"Privacy" = "Confidentialité";
+"Data & Privacy" = "Données et confidentialité";
"Report an Issue" = "Signaler un problème";
"Turn Focus Off" = "Désactiver Focus";
"Turn Focus On" = "Activer Focus";
@@ -634,8 +634,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "Supprimer tout le trafic enregistré, les références et les alertes ?";
"Delete everything" = "Tout supprimer";
-"nettop sampler · the extension didn't answer" = "Échantillonneur nettop · l'extension n'a pas répondu";
-"Network Extension · unavailable" = "Extension réseau · indisponible";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "Impossible de joindre l’extension de filtrage. Activez-la dans Filtre de contenu, puis cliquez sur Actualiser.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — activez Flowlight dans Filtre de contenu, puis cliquez sur Actualiser.";
"%@ — the content filter is unavailable" = "%@ — le filtre de contenu est indisponible";
@@ -644,8 +642,6 @@
"Reconnect to the content filter" = "Se reconnecter au filtre de contenu";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "Si un VPN ou un agent de sécurité occupe déjà cet emplacement — Palo Alto Networks GlobalProtect, CrowdStrike Falcon et autres l’utilisent — le filtre Flowlight ne peut recevoir aucun trafic tant que cet autre filtre n’est pas désactivé.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "Le filtre ne répond pas, Flowlight ne reçoit donc aucun trafic. Activez-le dans Filtre de contenu, puis cliquez sur Actualiser.";
-"%@ · receiving" = "%@ · réception en cours";
-"%@ · nothing arriving yet" = "%@ · rien ne parvient encore";
"Source" = "Source";
"Content filter" = "Filtre de contenu";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Observe les flux TCP et UDP éligibles à leur ouverture. Nécessite le droit d'accès Extension réseau et votre autorisation.";
@@ -702,7 +698,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Sans cela, la plupart du trafic n'affiche qu'une adresse IP ou un propriétaire de réseau.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight lit les réponses DNS et les noms de serveur TLS sur votre interface réseau principale pour nommer les connexions.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "Le contenu des paquets n'est jamais conservé ni envoyé où que ce soit. Seuls les noms d'hôte sont conservés.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS ne permet qu'aux administrateurs de lire les paquets : votre mot de passe est donc demandé une fois. Vous pouvez le retirer à tout moment dans Capture.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS ne permet qu'aux administrateurs de lire les paquets : votre mot de passe est donc demandé une fois. Vous pouvez le retirer à tout moment dans Sources › Collecteur.";
"Identify network owners when no hostname is available" = "Identifier les propriétaires de réseau quand aucun nom d'hôte n'est disponible";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "Activé par défaut. Envoie les IP de destination publiques au service DNS de Team Cymru. À désactiver pour que ces recherches restent sur ce Mac.";
"Not Now" = "Pas maintenant";
@@ -733,8 +729,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Rien d'enregistré pour l'instant";
+"Nothing recorded in the last hour" = "Rien n'a été enregistré durant la dernière heure";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "La couverture est calculée à partir du trafic que Flowlight a déjà enregistré. Le laisser tourner un moment.";
-"%@ of traffic fully accounted for" = "%@ du trafic entièrement pris en compte";
"How much of this Mac is covered" = "Quelle part de ce Mac est couverte";
"HTTPS inspection is on" = "L'inspection HTTPS est activée";
"HTTPS inspection is off" = "L'inspection HTTPS est désactivée";
@@ -782,8 +778,6 @@
"Camera" = "Caméra";
"Started" = "Démarrée";
"Unknown camera" = "Caméra inconnue";
-"%@ · nothing active" = "%@ · rien d'actif";
-"%@ · %lld active" = "%@ · %lld actifs";
"Watch camera activity" = "Surveiller l'activité de la caméra";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Le Bluetooth, l'USB et l'activité de la caméra restent désactivés tant que vous ne les activez pas. Ils ne demandent aucune nouvelle autorisation : ils sont désactivés parce que leur surveillance élargit ce que Flowlight observe, et cette décision doit vous appartenir, plutôt qu'à une mise à jour.\n\nLe Bluetooth et l'USB indiquent ce qui est connecté. L'activité de la caméra indique si chaque caméra est active, pas quelle app l'utilise. Flowlight n'ouvre jamais la caméra et ne lit aucune image.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "Aucun contenu ni attribution inventée. Le Bluetooth et l'USB indiquent les connexions, tandis que la surveillance de la caméra lit uniquement l'état actif de chaque appareil. macOS ne révèle ici publiquement aucune identité de l'app qui utilise la caméra : Flowlight nomme donc la caméra, ne devine jamais l'app et ne lit aucune image.";
@@ -1035,7 +1029,6 @@
"The network is quiet" = "Le réseau est calme";
"No app has sent or received data in the last few seconds." = "Aucune app n'a envoyé ou reçu de données ces dernières secondes.";
"Waiting for traffic data" = "En attente de données de trafic";
-"Open Capture Settings" = "Ouvrir les réglages de capture";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Répondre soi-même à un point de terminaison choisi au lieu de laisser la requête atteindre le serveur — un 500, une limite de débit, un corps mal formé ou une longue attente — et observer ce que l'agent en fait.";
@@ -1257,8 +1250,8 @@
"Until I resume" = "Jusqu'à la reprise";
"Pause Blocking" = "Suspendre le blocage";
"Stand every rule down for a while, without deleting anything" = "Mettre toutes les règles en veille un moment, sans rien supprimer";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "Une règle est surveillée mais pas appliquée. Seule l'extension réseau se trouve sur le trajet des données et peut refuser une connexion ; l'échantillonneur nettop compte le trafic après coup. Sélectionner l'extension réseau dans Capture pour appliquer ces règles.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld règles sont surveillées mais pas appliquées. Seule l'extension réseau se trouve sur le trajet des données et peut refuser une connexion ; l'échantillonneur nettop compte le trafic après coup. Sélectionner l'extension réseau dans Capture pour appliquer ces règles.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "Une règle est surveillée mais pas appliquée. Seule l'extension réseau se trouve sur le trajet des données et peut refuser une connexion ; l'échantillonneur nettop compte le trafic après coup. Sélectionner l'extension réseau dans Sources › Collecteur pour appliquer ces règles.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld règles sont surveillées mais pas appliquées. Seule l'extension réseau se trouve sur le trajet des données et peut refuser une connexion ; l'échantillonneur nettop compte le trafic après coup. Sélectionner l'extension réseau dans Sources › Collecteur pour appliquer ces règles.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "Une règle est surveillée mais pas appliquée — une règle qui nomme un chemin ne peut être mise en correspondance que par l'inspection HTTPS, et celle-ci est désactivée.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld règles sont surveillées mais pas appliquées — une règle qui nomme un chemin ne peut être mise en correspondance que par l'inspection HTTPS, et celle-ci est désactivée.";
"In force" = "En vigueur";
@@ -1308,7 +1301,7 @@
"Apply a Template" = "Appliquer un modèle";
"%@ · in force at once" = "%@ · en vigueur immédiatement";
"%@ · shown first" = "%@ · à examiner d'abord";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Chacun écrit des règles ordinaires dans la liste, où elles peuvent être lues, désactivées ou supprimées comme les autres. Refuser une connexion est le travail de l'extension réseau : avec l'échantillonneur nettop sélectionné dans Capture, ces règles sont surveillées plutôt qu'appliquées.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Chacun écrit des règles ordinaires dans la liste, où elles peuvent être lues, désactivées ou supprimées comme les autres. Refuser une connexion est le travail de l'extension réseau : avec l'échantillonneur nettop sélectionné dans Sources › Collecteur, ces règles sont surveillées plutôt qu'appliquées.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Facultatif. Laissé vide, cela s'applique à tout ce qui se passe sur le Mac ; nommer une app restreint la règle à cette app et aux outils qu'elle a lancés.";
"A domain, an IP address, or a range" = "Un domaine, une adresse IP ou une plage";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "Celles-ci nomment une méthode HTTP : seule l'inspection HTTPS peut les appliquer. Quand elle est désactivée, elles restent dans la liste à surveiller.";
diff --git a/Flowlight/Localization/it.lproj/Localizable.strings b/Flowlight/Localization/it.lproj/Localizable.strings
index 15b09a7d..eebba212 100644
--- a/Flowlight/Localization/it.lproj/Localizable.strings
+++ b/Flowlight/Localization/it.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "Dispositivi";
"Coverage" = "Copertura";
"Inspect" = "Ispeziona";
-"Capture" = "Acquisizione";
"Traffic" = "Traffico";
"Investigate" = "Analizza";
"Control" = "Controllo";
@@ -87,6 +86,7 @@
"Questions & Answers" = "Domande e risposte";
"What Flowlight Reads on This Mac" = "Cosa legge Flowlight su questo Mac";
"Privacy" = "Privacy";
+"Data & Privacy" = "Dati e privacy";
"Report an Issue" = "Segnala un problema";
"Turn Focus Off" = "Disattiva Focus";
"Turn Focus On" = "Attiva Focus";
@@ -634,8 +634,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "Eliminare tutto il traffico registrato, le linee di base e gli avvisi?";
"Delete everything" = "Elimina tutto";
-"nettop sampler · the extension didn't answer" = "Campionatore nettop · l'estensione non ha risposto";
-"Network Extension · unavailable" = "Estensione di rete · non disponibile";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "Impossibile raggiungere l’estensione del filtro. Abilitala in Filtro contenuti, quindi premi Aggiorna.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — abilita Flowlight in Filtro contenuti, quindi premi Aggiorna.";
"%@ — the content filter is unavailable" = "%@ — il filtro contenuti non è disponibile";
@@ -644,8 +642,6 @@
"Reconnect to the content filter" = "Riconnetti al filtro contenuti";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "Se una VPN o un agente di sicurezza occupa già quello slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e simili lo utilizzano — il filtro di Flowlight non può ricevere traffico finché tale filtro non viene disabilitato.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "Il filtro non risponde, quindi Flowlight non riceve traffico. Abilitalo in Filtro contenuti, quindi premi Aggiorna.";
-"%@ · receiving" = "%@ · ricezione in corso";
-"%@ · nothing arriving yet" = "%@ · ancora nessun dato in arrivo";
"Source" = "Origine";
"Content filter" = "Filtro contenuti";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Osserva i flussi TCP e UDP ammessi nel momento in cui si aprono. Richiede l'entitlement Network Extension e la tua approvazione.";
@@ -702,7 +698,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Senza questo, la maggior parte del traffico mostra solo un indirizzo IP o il proprietario della rete.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight legge le risposte DNS e i nomi server TLS sull'interfaccia di rete principale per dare un nome alle connessioni.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "Il contenuto dei pacchetti non viene mai memorizzato né inviato da nessuna parte. Vengono conservati solo i nomi host.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS consente solo agli amministratori di leggere i pacchetti, quindi la password viene richiesta una sola volta. Puoi revocare l'accesso in qualsiasi momento in Acquisizione.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS consente solo agli amministratori di leggere i pacchetti, quindi la password viene richiesta una sola volta. Puoi revocare l'accesso in qualsiasi momento in Origini › Collector.";
"Identify network owners when no hostname is available" = "Identifica i proprietari della rete quando non è disponibile un nome host";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "Attivo per impostazione predefinita. Invia gli IP pubblici di destinazione al servizio DNS di Team Cymru. Disattivalo per mantenere queste ricerche sul tuo Mac.";
"Not Now" = "Non ora";
@@ -733,8 +729,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Ancora nulla di registrato";
+"Nothing recorded in the last hour" = "Nessun dato registrato nell'ultima ora";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "La copertura è calcolata sul traffico che Flowlight ha già registrato. Lascialo in esecuzione per un momento.";
-"%@ of traffic fully accounted for" = "%@ del traffico interamente contabilizzato";
"How much of this Mac is covered" = "Quanta parte di questo Mac è coperta";
"HTTPS inspection is on" = "L'ispezione HTTPS è attiva";
"HTTPS inspection is off" = "L'ispezione HTTPS è disattivata";
@@ -782,8 +778,6 @@
"Camera" = "Fotocamera";
"Started" = "Avviata";
"Unknown camera" = "Fotocamera sconosciuta";
-"%@ · nothing active" = "%@ · nulla di attivo";
-"%@ · %lld active" = "%@ · %lld attivi";
"Watch camera activity" = "Monitora l'attività della fotocamera";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Bluetooth, USB e l'attività della fotocamera restano disattivati finché non li attivi. Non richiedono nuovi permessi: sono disattivati perché monitorarli amplia ciò che Flowlight osserva, e questa decisione dovrebbe spettare a te, non a un aggiornamento.\n\nBluetooth e USB mostrano ciò che è collegato. L'attività della fotocamera indica se ogni fotocamera è attiva, non quale app la sta usando. Flowlight non apre mai la fotocamera e non legge fotogrammi.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "Nessun contenuto e nessuna attribuzione inventata. Bluetooth e USB mostrano i collegamenti, mentre il monitoraggio della fotocamera legge solo lo stato attivo di ciascun dispositivo. macOS non rivela pubblicamente quale app usa la fotocamera, quindi Flowlight indica la fotocamera, non indovina mai l'app e non legge fotogrammi.";
@@ -1035,7 +1029,6 @@
"The network is quiet" = "La rete è tranquilla";
"No app has sent or received data in the last few seconds." = "Nessuna app ha inviato o ricevuto dati negli ultimi secondi.";
"Waiting for traffic data" = "In attesa dei dati sul traffico";
-"Open Capture Settings" = "Apri le impostazioni di acquisizione";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Rispondi tu a un endpoint scelto invece di lasciare che la richiesta raggiunga il server — un 500, un limite di frequenza, un corpo malformato o una lunga attesa — e osserva come reagisce l'agente.";
@@ -1257,8 +1250,8 @@
"Until I resume" = "Finché non riprendo";
"Pause Blocking" = "Sospendi il blocco";
"Stand every rule down for a while, without deleting anything" = "Metti in pausa tutte le regole per un po', senza eliminare nulla";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "Una regola viene osservata ma non applicata. Solo l'estensione di rete si trova sul percorso dei dati e può rifiutare una connessione; il campionatore nettop conta il traffico a posteriori. Seleziona l'estensione di rete in Acquisizione per applicare queste regole.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld regole vengono osservate ma non applicate. Solo l'estensione di rete si trova sul percorso dei dati e può rifiutare una connessione; il campionatore nettop conta il traffico a posteriori. Seleziona l'estensione di rete in Acquisizione per applicare queste regole.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "Una regola viene osservata ma non applicata. Solo l'estensione di rete si trova sul percorso dei dati e può rifiutare una connessione; il campionatore nettop conta il traffico a posteriori. Seleziona l'estensione di rete in Origini › Collector per applicare queste regole.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld regole vengono osservate ma non applicate. Solo l'estensione di rete si trova sul percorso dei dati e può rifiutare una connessione; il campionatore nettop conta il traffico a posteriori. Seleziona l'estensione di rete in Origini › Collector per applicare queste regole.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "Una regola viene osservata ma non applicata: una regola che indica un percorso può essere confrontata solo dall'ispezione HTTPS, che è disattivata.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld regole vengono osservate ma non applicate: una regola che indica un percorso può essere confrontata solo dall'ispezione HTTPS, che è disattivata.";
"In force" = "In vigore";
@@ -1308,7 +1301,7 @@
"Apply a Template" = "Applica un modello";
"%@ · in force at once" = "%@ · in vigore subito";
"%@ · shown first" = "%@ · mostrate prima";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Ognuno scrive regole normali nell'elenco, dove possono essere lette, disattivate o eliminate come tutte le altre. Rifiutare una connessione è compito dell'estensione di rete, quindi con il campionatore nettop selezionato in Acquisizione queste regole vengono osservate anziché applicate.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Ognuno scrive regole normali nell'elenco, dove possono essere lette, disattivate o eliminate come tutte le altre. Rifiutare una connessione è compito dell'estensione di rete, quindi con il campionatore nettop selezionato in Origini › Collector queste regole vengono osservate anziché applicate.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Facoltativo. Se lasciato vuoto si applica a tutto il Mac; indicare un'app lo limita a quell'app e agli strumenti che ha avviato.";
"A domain, an IP address, or a range" = "Un dominio, un indirizzo IP o un intervallo";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "Queste indicano un metodo HTTP, quindi solo l'ispezione HTTPS può applicarle. Con l'ispezione disattivata restano nell'elenco a osservare.";
diff --git a/Flowlight/Localization/ja.lproj/Localizable.strings b/Flowlight/Localization/ja.lproj/Localizable.strings
index 5b85ea84..4f3e1460 100644
--- a/Flowlight/Localization/ja.lproj/Localizable.strings
+++ b/Flowlight/Localization/ja.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "デバイス";
"Coverage" = "カバー範囲";
"Inspect" = "インスペクト";
-"Capture" = "キャプチャ";
"Traffic" = "トラフィック";
"Investigate" = "調査";
"Control" = "制御";
@@ -87,6 +86,7 @@
"Questions & Answers" = "よくある質問";
"What Flowlight Reads on This Mac" = "Flowlight がこの Mac で読み取るもの";
"Privacy" = "プライバシー";
+"Data & Privacy" = "データとプライバシー";
"Report an Issue" = "問題を報告";
"Turn Focus Off" = "フォーカスをオフにする";
"Turn Focus On" = "フォーカスをオンにする";
@@ -634,8 +634,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "記録したトラフィック・基準値・アラートをすべて削除しますか?";
"Delete everything" = "すべて削除";
-"nettop sampler · the extension didn't answer" = "nettop サンプラー · 機能拡張が応答しませんでした";
-"Network Extension · unavailable" = "ネットワーク機能拡張 · 利用不可";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "フィルター機能拡張に接続できませんでした。コンテンツフィルターで有効にしてから、更新を押してください。";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — コンテンツフィルターで Flowlight を有効にしてから、更新を押してください。";
"%@ — the content filter is unavailable" = "%@ — コンテンツフィルターを利用できません";
@@ -644,8 +642,6 @@
"Reconnect to the content filter" = "コンテンツフィルターに再接続";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "VPN やセキュリティエージェントがそのスロットを使用している場合(Palo Alto Networks GlobalProtect、CrowdStrike Falcon など)、そのフィルターを無効にするまで Flowlight のフィルターはトラフィックを受信できません。";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "フィルターが応答していないため、Flowlight はトラフィックを受信していません。コンテンツフィルターで有効にしてから、更新を押してください。";
-"%@ · receiving" = "%@ · 受信中";
-"%@ · nothing arriving yet" = "%@ · まだ届いていません";
"Source" = "ソース";
"Content filter" = "コンテンツフィルタ";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "対象となる TCP と UDP のフローを、開かれた時点で観測します。ネットワーク機能拡張の entitlement と、あなたの承認が必要です。";
@@ -702,7 +698,7 @@
"Without this, most traffic shows only an IP address or network owner." = "これがないと、ほとんどのトラフィックは IP アドレスかネットワーク所有者しか表示されません。";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight は接続に名前を付けるため、主ネットワークインターフェイスで DNS の応答と TLS のサーバ名を読み取ります。";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "パケットの内容は保存も送信もされません。保持するのはホスト名だけです。";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS はパケットの読み取りを管理者にしか許可しないため、パスワードを 1 回確認します。キャプチャでいつでも解除できます。";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS はパケットの読み取りを管理者にしか許可しないため、パスワードを 1 回確認します。「ソース › コレクタ」でいつでも解除できます。";
"Identify network owners when no hostname is available" = "ホスト名がない場合にネットワーク所有者を特定";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "デフォルトでオンです。パブリックな接続先 IP を Team Cymru の DNS サービスに送信します。オフにすると、この照会はこの Mac 内だけで行われます。";
"Not Now" = "今はしない";
@@ -733,8 +729,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "まだ何も記録されていません";
+"Nothing recorded in the last hour" = "過去 1 時間には何も記録されていません";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "カバー範囲は、Flowlight がすでに記録したトラフィックから算出します。しばらく動かしたままにしてください。";
-"%@ of traffic fully accounted for" = "トラフィックの %@ を完全に把握";
"How much of this Mac is covered" = "この Mac をどこまでカバーできているか";
"HTTPS inspection is on" = "HTTPS インスペクションはオンです";
"HTTPS inspection is off" = "HTTPS インスペクションはオフです";
@@ -782,8 +778,6 @@
"Camera" = "カメラ";
"Started" = "開始";
"Unknown camera" = "不明なカメラ";
-"%@ · nothing active" = "%@ · アクティブなし";
-"%@ · %lld active" = "%@ · %lld 台がアクティブ";
"Watch camera activity" = "カメラの動作を監視";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Bluetooth、USB、カメラの動作は、オンにするまで監視されません。新しい権限は必要ありません。オフになっているのは、監視すると Flowlight が見る範囲が広がるためであり、それはアップデートではなく、あなたが決めることです。\n\nBluetooth と USB では接続中のものを表示します。カメラの動作では各カメラがアクティブかどうかを表示しますが、使用中のアプリは表示しません。Flowlight がカメラを開いたり、フレームを読み取ったりすることはありません。";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "内容を読み取ることも、根拠のないアプリへの関連付けをすることもありません。Bluetooth と USB では接続を表示し、カメラの監視では各デバイスがアクティブかどうかだけを読み取ります。macOS はここでカメラを使用中のアプリを公開していないため、Flowlight はカメラ名のみを示し、アプリを推測せず、フレームも読み取りません。";
@@ -1035,7 +1029,6 @@
"The network is quiet" = "ネットワークは静かです";
"No app has sent or received data in the last few seconds." = "この数秒間にデータを送受信したアプリはありません。";
"Waiting for traffic data" = "トラフィックデータを待っています";
-"Open Capture Settings" = "キャプチャの設定を開く";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "リクエストをサーバに届けず、選んだエンドポイントに自分で応答します。500、レート制限、壊れた本文、長い待ち時間などを返して、エージェントがどう振る舞うかを確かめられます。";
@@ -1257,8 +1250,8 @@
"Until I resume" = "再開するまで";
"Pause Blocking" = "ブロックを一時停止";
"Stand every rule down for a while, without deleting anything" = "何も削除せずに、すべてのルールをしばらく止めます";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "1 件のルールは監視されているだけで、実行されていません。データ経路に入って接続を拒否できるのはネットワーク機能拡張だけで、nettop サンプラーは事後にトラフィックを数えます。これらのルールを実行するには、キャプチャでネットワーク機能拡張を選んでください。";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld 件のルールは監視されているだけで、実行されていません。データ経路に入って接続を拒否できるのはネットワーク機能拡張だけで、nettop サンプラーは事後にトラフィックを数えます。これらのルールを実行するには、キャプチャでネットワーク機能拡張を選んでください。";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "1 件のルールは監視されているだけで、実行されていません。データ経路に入って接続を拒否できるのはネットワーク機能拡張だけで、nettop サンプラーは事後にトラフィックを数えます。これらのルールを実行するには、ソース › コレクターでネットワーク機能拡張を選んでください。";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld 件のルールは監視されているだけで、実行されていません。データ経路に入って接続を拒否できるのはネットワーク機能拡張だけで、nettop サンプラーは事後にトラフィックを数えます。これらのルールを実行するには、ソース › コレクターでネットワーク機能拡張を選んでください。";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "1 件のルールは監視されているだけで、実行されていません。パスを指定したルールを照合できるのは HTTPS インスペクションだけで、それがオフになっています。";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld 件のルールは監視されているだけで、実行されていません。パスを指定したルールを照合できるのは HTTPS インスペクションだけで、それがオフになっています。";
"In force" = "有効";
@@ -1308,7 +1301,7 @@
"Apply a Template" = "テンプレートを適用";
"%@ · in force at once" = "%@ · すぐに有効";
"%@ · shown first" = "%@ · 適用前に確認";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "どのテンプレートも、ふつうのルールをリストに書き込みます。ほかのルールと同じように、内容を読み、オフにし、削除できます。接続を拒否するのはネットワーク機能拡張の役目のため、キャプチャで nettop サンプラーを選んでいる場合は、実行ではなく監視にとどまります。";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "どのテンプレートも、ふつうのルールをリストに書き込みます。ほかのルールと同じように、内容を読み、オフにし、削除できます。接続を拒否するのはネットワーク機能拡張の役目のため、ソース › コレクターで nettop サンプラーを選んでいる場合は、実行ではなく監視にとどまります。";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "省略できます。空のままにするとこの Mac 全体に適用され、アプリを指定すると、そのアプリとそれが起動したツールだけに絞られます。";
"A domain, an IP address, or a range" = "ドメイン、IP アドレス、または範囲";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "これらは HTTP メソッドを指定するため、実行できるのは HTTPS インスペクションだけです。オフの場合は、リストの中で監視するだけになります。";
diff --git a/Flowlight/Localization/ko.lproj/Localizable.strings b/Flowlight/Localization/ko.lproj/Localizable.strings
index 253bef7f..6ad2abc5 100644
--- a/Flowlight/Localization/ko.lproj/Localizable.strings
+++ b/Flowlight/Localization/ko.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "기기";
"Coverage" = "포착 범위";
"Inspect" = "검사";
-"Capture" = "캡처";
"Traffic" = "트래픽";
"Investigate" = "분석";
"Control" = "제어";
@@ -87,6 +86,7 @@
"Questions & Answers" = "질문과 답변";
"What Flowlight Reads on This Mac" = "Flowlight가 이 Mac에서 읽는 항목";
"Privacy" = "개인 정보 보호";
+"Data & Privacy" = "데이터 및 개인 정보 보호";
"Report an Issue" = "문제 보고";
"Turn Focus Off" = "집중 끄기";
"Turn Focus On" = "집중 켜기";
@@ -657,8 +657,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "기록된 트래픽, 기준선, 알림을 모두 삭제할까요?";
"Delete everything" = "모두 삭제";
-"nettop sampler · the extension didn't answer" = "nettop 샘플러 · 확장 프로그램이 응답하지 않았습니다";
-"Network Extension · unavailable" = "네트워크 확장 · 사용할 수 없음";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "필터 확장에 연결할 수 없습니다. 콘텐츠 필터에서 활성화한 다음 새로 고침을 누르세요.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — 콘텐츠 필터에서 Flowlight를 활성화한 다음 새로 고침을 누르세요.";
"%@ — the content filter is unavailable" = "%@ — 콘텐츠 필터를 사용할 수 없습니다";
@@ -667,8 +665,6 @@
"Reconnect to the content filter" = "콘텐츠 필터에 다시 연결";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "VPN 또는 보안 에이전트가 이미 해당 슬롯을 사용 중이라면(Palo Alto Networks GlobalProtect, CrowdStrike Falcon 등), 그 필터를 비활성화할 때까지 Flowlight 필터는 트래픽을 받을 수 없습니다.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "필터가 응답하지 않아 Flowlight가 트래픽을 받지 못하고 있습니다. 콘텐츠 필터에서 활성화한 다음 새로 고침을 누르세요.";
-"%@ · receiving" = "%@ · 수신 중";
-"%@ · nothing arriving yet" = "%@ · 아직 들어오는 데이터 없음";
"Source" = "소스";
"Content filter" = "콘텐츠 필터";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "대상이 되는 TCP·UDP 흐름이 열리는 순간 관찰합니다. 네트워크 확장 프로그램 권한과 사용자 승인이 필요합니다.";
@@ -725,7 +721,7 @@
"Without this, most traffic shows only an IP address or network owner." = "이 기능이 없으면 대부분의 트래픽은 IP 주소나 네트워크 소유자만 표시됩니다.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight는 연결에 이름을 붙이기 위해 주 네트워크 인터페이스에서 DNS 응답과 TLS 서버 이름을 읽습니다.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "패킷 내용은 저장하지도, 어디로 전송하지도 않습니다. 호스트 이름만 보관합니다.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS는 관리자만 패킷을 읽을 수 있게 하므로 암호를 한 번 요청합니다. 캡처에서 언제든 다시 해제할 수 있습니다.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS는 관리자만 패킷을 읽을 수 있게 하므로 암호를 한 번 요청합니다. 소스 › 수집기에서 언제든 다시 해제할 수 있습니다.";
"Identify network owners when no hostname is available" = "호스트 이름이 없을 때 네트워크 소유자 식별";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "기본적으로 켜져 있습니다. 공인 목적지 IP를 Team Cymru의 DNS 서비스로 보냅니다. 끄면 이 조회를 Mac 안에서만 수행합니다.";
"Not Now" = "나중에";
@@ -756,8 +752,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "아직 기록된 것이 없습니다";
+"Nothing recorded in the last hour" = "최근 한 시간 동안 기록된 것이 없습니다";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "포착 범위는 Flowlight가 이미 기록한 트래픽으로 계산합니다. 잠시 그대로 실행해 두세요.";
-"%@ of traffic fully accounted for" = "트래픽의 %@를 완전히 파악";
"How much of this Mac is covered" = "이 Mac을 어디까지 포착하고 있는지";
"HTTPS inspection is on" = "HTTPS 검사가 켜져 있습니다";
"HTTPS inspection is off" = "HTTPS 검사가 꺼져 있습니다";
@@ -805,8 +801,6 @@
"Camera" = "카메라";
"Started" = "시작됨";
"Unknown camera" = "알 수 없는 카메라";
-"%@ · nothing active" = "%@ · 활성 항목 없음";
-"%@ · %lld active" = "%@ · %lld개 활성";
"Watch camera activity" = "카메라 활동 감시";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "Bluetooth, USB 및 카메라 활동은 직접 켤 때까지 꺼져 있습니다. 새 권한은 필요하지 않습니다. 감시하면 Flowlight가 들여다보는 범위가 넓어지므로, 업데이트가 아니라 사용자가 결정하도록 꺼 두었습니다.\n\nBluetooth와 USB는 연결된 항목을 보여 줍니다. 카메라 활동은 각 카메라의 활성 여부만 보여 주며 어떤 앱이 사용하는지는 보여 주지 않습니다. Flowlight는 카메라를 열거나 프레임을 읽지 않습니다.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "내용을 읽거나 근거 없이 앱에 귀속하지 않습니다. Bluetooth와 USB는 연결 상태를 보여 주고, 카메라 감시는 각 기기의 활성 상태만 읽습니다. macOS는 여기서 카메라를 사용하는 앱의 신원을 공개하지 않으므로 Flowlight는 카메라 이름만 표시하고 앱을 추측하거나 프레임을 읽지 않습니다.";
@@ -1058,7 +1052,6 @@
"The network is quiet" = "네트워크가 조용합니다";
"No app has sent or received data in the last few seconds." = "최근 몇 초 동안 데이터를 주고받은 앱이 없습니다.";
"Waiting for traffic data" = "트래픽 데이터를 기다리는 중";
-"Open Capture Settings" = "캡처 설정 열기";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "요청이 서버에 닿기 전에 원하는 엔드포인트에 직접 응답합니다. 500 오류, 속도 제한, 잘못된 본문, 긴 지연 등을 돌려주고 에이전트가 어떻게 대응하는지 지켜보세요.";
@@ -1280,8 +1273,8 @@
"Until I resume" = "다시 시작할 때까지";
"Pause Blocking" = "차단 일시 중지";
"Stand every rule down for a while, without deleting anything" = "아무것도 삭제하지 않고 모든 규칙을 잠시 쉬게 합니다";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "규칙 1개가 관찰만 되고 실행되지는 않습니다. 데이터 경로에 자리해 연결을 거부할 수 있는 것은 네트워크 확장 프로그램뿐이며, nettop 샘플러는 트래픽을 사후에 집계합니다. 이 규칙을 적용하려면 캡처에서 네트워크 확장 프로그램을 선택하세요.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "규칙 %lld개가 관찰만 되고 실행되지는 않습니다. 데이터 경로에 자리해 연결을 거부할 수 있는 것은 네트워크 확장 프로그램뿐이며, nettop 샘플러는 트래픽을 사후에 집계합니다. 이 규칙을 적용하려면 캡처에서 네트워크 확장 프로그램을 선택하세요.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "규칙 1개가 관찰만 되고 실행되지는 않습니다. 데이터 경로에 자리해 연결을 거부할 수 있는 것은 네트워크 확장 프로그램뿐이며, nettop 샘플러는 트래픽을 사후에 집계합니다. 이 규칙을 적용하려면 소스 › 컬렉터에서 네트워크 확장 프로그램을 선택하세요.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "규칙 %lld개가 관찰만 되고 실행되지는 않습니다. 데이터 경로에 자리해 연결을 거부할 수 있는 것은 네트워크 확장 프로그램뿐이며, nettop 샘플러는 트래픽을 사후에 집계합니다. 이 규칙을 적용하려면 소스 › 컬렉터에서 네트워크 확장 프로그램을 선택하세요.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "규칙 1개가 관찰만 되고 실행되지는 않습니다. 경로를 지정한 규칙은 HTTPS 검사로만 일치시킬 수 있는데, 검사가 꺼져 있습니다.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "규칙 %lld개가 관찰만 되고 실행되지는 않습니다. 경로를 지정한 규칙은 HTTPS 검사로만 일치시킬 수 있는데, 검사가 꺼져 있습니다.";
"In force" = "적용 중";
@@ -1331,7 +1324,7 @@
"Apply a Template" = "템플릿 적용";
"%@ · in force at once" = "%@ · 즉시 적용";
"%@ · shown first" = "%@ · 먼저 표시";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "각 템플릿은 일반 규칙을 목록에 써 넣을 뿐이며, 다른 규칙과 똑같이 확인하고 끄고 삭제할 수 있습니다. 연결을 실제로 거부하는 일은 네트워크 확장 프로그램의 몫이므로, 캡처에서 nettop 샘플러를 선택한 상태에서는 이 규칙들이 실행되지 않고 관찰만 됩니다.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "각 템플릿은 일반 규칙을 목록에 써 넣을 뿐이며, 다른 규칙과 똑같이 확인하고 끄고 삭제할 수 있습니다. 연결을 실제로 거부하는 일은 네트워크 확장 프로그램의 몫이므로, 소스 › 컬렉터에서 nettop 샘플러를 선택한 상태에서는 이 규칙들이 실행되지 않고 관찰만 됩니다.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "선택 사항입니다. 비워 두면 이 Mac 전체에 적용되고, 앱을 지정하면 그 앱과 그 앱이 실행한 도구로 범위가 좁혀집니다.";
"A domain, an IP address, or a range" = "도메인, IP 주소 또는 범위";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "이 규칙은 HTTP 메서드를 지정하므로 HTTPS 검사만 실행할 수 있습니다. 검사가 꺼져 있으면 목록에서 관찰만 합니다.";
diff --git a/Flowlight/Localization/pt-PT.lproj/Localizable.strings b/Flowlight/Localization/pt-PT.lproj/Localizable.strings
index 3c51cac3..324de56f 100644
--- a/Flowlight/Localization/pt-PT.lproj/Localizable.strings
+++ b/Flowlight/Localization/pt-PT.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "Dispositivos";
"Coverage" = "Cobertura";
"Inspect" = "Inspecionar";
-"Capture" = "Captura";
"Traffic" = "Tráfego";
"Investigate" = "Investigar";
"Control" = "Controlo";
@@ -87,6 +86,7 @@
"Questions & Answers" = "Perguntas e respostas";
"What Flowlight Reads on This Mac" = "O que o Flowlight lê neste Mac";
"Privacy" = "Privacidade";
+"Data & Privacy" = "Dados e privacidade";
"Report an Issue" = "Comunicar um problema";
"Turn Focus Off" = "Desativar o Foco";
"Turn Focus On" = "Ativar o Foco";
@@ -657,8 +657,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "Eliminar todo o tráfego registado, as linhas de base e os alertas?";
"Delete everything" = "Eliminar tudo";
-"nettop sampler · the extension didn't answer" = "amostrador nettop · a extensão não respondeu";
-"Network Extension · unavailable" = "Extensão de rede · indisponível";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "Não foi possível aceder à extensão do filtro. Ative-a em Filtro de conteúdo e prima Atualizar.";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — ative o Flowlight em Filtro de conteúdo e prima Atualizar.";
"%@ — the content filter is unavailable" = "%@ — o filtro de conteúdo está indisponível";
@@ -667,8 +665,6 @@
"Reconnect to the content filter" = "Voltar a ligar ao filtro de conteúdo";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "Se uma VPN ou um agente de segurança já ocupar esse espaço — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e semelhantes utilizam-no — o filtro do Flowlight não pode receber tráfego até esse filtro ser desativado.";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "O filtro não está a responder, pelo que o Flowlight não recebe tráfego. Ative-o em Filtro de conteúdo e prima Atualizar.";
-"%@ · receiving" = "%@ · a receber";
-"%@ · nothing arriving yet" = "%@ · ainda nada a chegar";
"Source" = "Origem";
"Content filter" = "Filtro de conteúdo";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "Observa os fluxos TCP e UDP elegíveis à medida que abrem. Requer o entitlement da extensão de rede e a sua aprovação.";
@@ -725,7 +721,7 @@
"Without this, most traffic shows only an IP address or network owner." = "Sem isto, a maior parte do tráfego mostra apenas um endereço IP ou o proprietário da rede.";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "O Flowlight lê as respostas DNS e os nomes de servidor TLS na sua interface de rede principal para dar nome às ligações.";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "O conteúdo dos pacotes nunca é guardado nem enviado para nenhum sítio. Só são guardados os nomes de anfitrião.";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "O macOS só permite que os administradores leiam pacotes, por isso isto pede a sua palavra-passe uma vez. Pode removê-lo em qualquer momento em Captura.";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "O macOS só permite que os administradores leiam pacotes, por isso isto pede a sua palavra-passe uma vez. Pode removê-lo em qualquer momento em Origens › Coletor.";
"Identify network owners when no hostname is available" = "Identificar os proprietários da rede quando não há nome de anfitrião";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "Ativado por predefinição. Envia os IPs públicos de destino para o serviço DNS da Team Cymru. Desative para manter estas consultas no seu Mac.";
"Not Now" = "Não agora";
@@ -756,8 +752,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "Ainda não há nada registado";
+"Nothing recorded in the last hour" = "Nada registado na última hora";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "A cobertura é calculada a partir do tráfego que o Flowlight já registou. Deixe-o a correr por um momento.";
-"%@ of traffic fully accounted for" = "%@ do tráfego totalmente contabilizado";
"How much of this Mac is covered" = "Quanto deste Mac está coberto";
"HTTPS inspection is on" = "A inspeção HTTPS está ativada";
"HTTPS inspection is off" = "A inspeção HTTPS está desativada";
@@ -805,8 +801,6 @@
"Camera" = "Câmara";
"Started" = "Iniciada";
"Unknown camera" = "Câmara desconhecida";
-"%@ · nothing active" = "%@ · nada ativo";
-"%@ · %lld active" = "%@ · %lld ativos";
"Watch camera activity" = "Vigiar a atividade da câmara";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "O Bluetooth, o USB e a atividade da câmara estão desativados até os ativar. Não precisam de novas permissões — estão desativados porque vigiá-los amplia o que o Flowlight observa, e essa decisão deve ser sua, não de uma atualização.\n\nO Bluetooth e o USB mostram o que está ligado. A atividade da câmara mostra se cada câmara está ativa, não que app a está a usar. O Flowlight nunca abre a câmara nem lê fotogramas.";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "Sem conteúdos nem atribuições inventadas. O Bluetooth e o USB mostram as ligações, enquanto a monitorização da câmara lê apenas o estado ativo de cada dispositivo. O macOS não revela aqui publicamente qual é a app que usa a câmara, por isso o Flowlight identifica a câmara, nunca adivinha a app e nunca lê fotogramas.";
@@ -1058,7 +1052,6 @@
"The network is quiet" = "A rede está calma";
"No app has sent or received data in the last few seconds." = "Nenhuma app enviou ou recebeu dados nos últimos segundos.";
"Waiting for traffic data" = "À espera de dados de tráfego";
-"Open Capture Settings" = "Abrir as definições de captura";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "Responda você a um endpoint escolhido em vez de deixar o pedido chegar ao servidor — um 500, um limite de pedidos, um corpo malformado ou uma espera longa — e veja o que o agente faz com isso.";
@@ -1280,8 +1273,8 @@
"Until I resume" = "Até eu retomar";
"Pause Blocking" = "Pausar o bloqueio";
"Stand every rule down for a while, without deleting anything" = "Suspender todas as regras durante algum tempo, sem eliminar nada";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "Uma regra está a ser vigiada mas não aplicada. Só a extensão de rede está no caminho dos dados e pode recusar uma ligação; o amostrador nettop conta o tráfego depois do facto. Selecione a extensão de rede em Captura para aplicar estas regras.";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld regras estão a ser vigiadas mas não aplicadas. Só a extensão de rede está no caminho dos dados e pode recusar uma ligação; o amostrador nettop conta o tráfego depois do facto. Selecione a extensão de rede em Captura para aplicar estas regras.";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "Uma regra está a ser vigiada mas não aplicada. Só a extensão de rede está no caminho dos dados e pode recusar uma ligação; o amostrador nettop conta o tráfego depois do facto. Selecione a extensão de rede em Origens › Coletor para aplicar estas regras.";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld regras estão a ser vigiadas mas não aplicadas. Só a extensão de rede está no caminho dos dados e pode recusar uma ligação; o amostrador nettop conta o tráfego depois do facto. Selecione a extensão de rede em Origens › Coletor para aplicar estas regras.";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "Uma regra está a ser vigiada mas não aplicada — uma regra que nomeia um caminho só pode ser correspondida pela inspeção HTTPS, e ela está desativada.";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld regras estão a ser vigiadas mas não aplicadas — uma regra que nomeia um caminho só pode ser correspondida pela inspeção HTTPS, e ela está desativada.";
"In force" = "Em vigor";
@@ -1331,7 +1324,7 @@
"Apply a Template" = "Aplicar um modelo";
"%@ · in force at once" = "%@ · em vigor de imediato";
"%@ · shown first" = "%@ · mostrado primeiro";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "Cada um escreve regras normais na lista, onde podem ser lidas, desativadas ou eliminadas como quaisquer outras. Recusar uma ligação é tarefa da extensão de rede, por isso, com o amostrador nettop selecionado em Captura, estas são vigiadas em vez de aplicadas.";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "Cada um escreve regras normais na lista, onde podem ser lidas, desativadas ou eliminadas como quaisquer outras. Recusar uma ligação é tarefa da extensão de rede, por isso, com o amostrador nettop selecionado em Origens › Coletor, estas são vigiadas em vez de aplicadas.";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "Opcional. Se ficar vazio, aplica-se a tudo no Mac; nomear uma app restringe-o a essa app e às ferramentas que ela iniciou.";
"A domain, an IP address, or a range" = "Um domínio, um endereço IP, ou um intervalo";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "Estas nomeiam um método HTTP, por isso só a inspeção HTTPS as pode aplicar. Com ela desativada, ficam na lista a vigiar.";
diff --git a/Flowlight/Localization/zh-Hans.lproj/Localizable.strings b/Flowlight/Localization/zh-Hans.lproj/Localizable.strings
index 5b3fd309..b0dafb5f 100644
--- a/Flowlight/Localization/zh-Hans.lproj/Localizable.strings
+++ b/Flowlight/Localization/zh-Hans.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "设备";
"Coverage" = "覆盖范围";
"Inspect" = "检查";
-"Capture" = "捕获";
"Traffic" = "流量";
"Investigate" = "调查";
"Control" = "管控";
@@ -87,6 +86,7 @@
"Questions & Answers" = "问题与解答";
"What Flowlight Reads on This Mac" = "Flowlight 在这台 Mac 上读取什么";
"Privacy" = "隐私";
+"Data & Privacy" = "数据与隐私";
"Report an Issue" = "报告问题";
"Turn Focus Off" = "关闭聚焦";
"Turn Focus On" = "开启聚焦";
@@ -657,8 +657,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "删除所有已记录的流量、基线和警报?";
"Delete everything" = "全部删除";
-"nettop sampler · the extension didn't answer" = "nettop 采样器 · 扩展没有响应";
-"Network Extension · unavailable" = "网络扩展 · 不可用";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "无法连接过滤器扩展。请在“内容过滤器”中启用它,然后点按“刷新”。";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — 请在“内容过滤器”中启用 Flowlight,然后点按“刷新”。";
"%@ — the content filter is unavailable" = "%@ — 内容过滤器不可用";
@@ -667,8 +665,6 @@
"Reconnect to the content filter" = "重新连接内容过滤器";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "如果 VPN 或安全代理已占用该位置(Palo Alto Networks GlobalProtect、CrowdStrike Falcon 等都会使用它),则在停用该过滤器之前,Flowlight 的过滤器无法接收流量。";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "过滤器没有响应,因此 Flowlight 未收到流量。请在“内容过滤器”中启用它,然后点按“刷新”。";
-"%@ · receiving" = "%@ · 正在接收";
-"%@ · nothing arriving yet" = "%@ · 尚无数据到达";
"Source" = "来源";
"Content filter" = "内容过滤器";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "在符合条件的 TCP 和 UDP 流建立时进行观察。需要网络扩展授权和你的批准。";
@@ -725,7 +721,7 @@
"Without this, most traffic shows only an IP address or network owner." = "不开启的话,大多数流量只会显示 IP 地址或网络所有者。";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight 读取你主网络接口上的 DNS 应答和 TLS 服务器名称,用来为连接命名。";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "数据包内容从不保存,也从不发往任何地方。只保留主机名。";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS 只允许管理员读取数据包,因此这里会要求你输入一次密码。你可以随时在“捕获”中移除它。";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS 只允许管理员读取数据包,因此这里会要求你输入一次密码。你可以随时在“来源 › 收集器”中移除它。";
"Identify network owners when no hostname is available" = "在没有主机名时识别网络所有者";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "默认开启。会把公网目标 IP 发送到 Team Cymru 的 DNS 服务。关闭后,这些查询只在你的 Mac 上进行。";
"Not Now" = "以后再说";
@@ -756,8 +752,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "尚未记录到任何内容";
+"Nothing recorded in the last hour" = "最近一小时内没有记录";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "覆盖范围是根据 Flowlight 已经记录的流量算出来的。请让它再运行一会儿。";
-"%@ of traffic fully accounted for" = "%@ 的流量完全有据可查";
"How much of this Mac is covered" = "这台 Mac 被覆盖了多少";
"HTTPS inspection is on" = "HTTPS 检查已开启";
"HTTPS inspection is off" = "HTTPS 检查已关闭";
@@ -805,8 +801,6 @@
"Camera" = "摄像头";
"Started" = "已启动";
"Unknown camera" = "未知摄像头";
-"%@ · nothing active" = "%@ · 没有活动项";
-"%@ · %lld active" = "%@ · %lld 个活动项";
"Watch camera activity" = "监视摄像头活动";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "蓝牙、USB 和摄像头活动在你开启之前一直关闭。它们不需要新的权限 —— 默认关闭是因为监视它们会扩大 Flowlight 的观察范围,而这应该由你决定,不应由某次更新替你决定。\n\n蓝牙和 USB 会显示连接的设备。摄像头活动会显示每个摄像头是否处于活动状态,但不会显示哪个应用正在使用它。Flowlight 从不打开摄像头,也不读取画面。";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "不读取内容,也不凭空推断归属。蓝牙和 USB 显示连接状态,摄像头监视只读取每台设备是否处于活动状态。macOS 不在这里公开使用摄像头的应用,因此 Flowlight 只标明摄像头,从不猜测应用,也不读取画面。";
@@ -1058,7 +1052,6 @@
"The network is quiet" = "网络很安静";
"No app has sent or received data in the last few seconds." = "最近几秒内没有应用收发数据。";
"Waiting for traffic data" = "正在等待流量数据";
-"Open Capture Settings" = "打开捕获设置";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "自行响应指定的端点,而不让请求到达服务器 —— 返回 500、限流、格式错误的正文,或是长时间等待 —— 然后看看代理会如何应对。";
@@ -1280,8 +1273,8 @@
"Until I resume" = "直到我手动恢复";
"Pause Blocking" = "暂停阻止";
"Stand every rule down for a while, without deleting anything" = "让所有规则暂时停止生效,不删除任何内容";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "有一条规则只是被监视,而没有被执行。只有网络扩展位于数据路径上,能够拒绝连接;nettop 采样器是事后计数。请在“捕获”中选择网络扩展,以执行这些规则。";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "%lld 条规则只是被监视,而没有被执行。只有网络扩展位于数据路径上,能够拒绝连接;nettop 采样器是事后计数。请在“捕获”中选择网络扩展,以执行这些规则。";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "有一条规则只是被监视,而没有被执行。只有网络扩展位于数据路径上,能够拒绝连接;nettop 采样器是事后计数。请在“来源 › 收集器”中选择网络扩展,以执行这些规则。";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "%lld 条规则只是被监视,而没有被执行。只有网络扩展位于数据路径上,能够拒绝连接;nettop 采样器是事后计数。请在“来源 › 收集器”中选择网络扩展,以执行这些规则。";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "有一条规则只是被监视,而没有被执行 —— 指明路径的规则只能由 HTTPS 检查匹配,而它已关闭。";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "%lld 条规则只是被监视,而没有被执行 —— 指明路径的规则只能由 HTTPS 检查匹配,而它已关闭。";
"In force" = "生效中";
@@ -1331,7 +1324,7 @@
"Apply a Template" = "应用模板";
"%@ · in force at once" = "%@ · 立即生效";
"%@ · shown first" = "%@ · 先供你确认";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "每个模板都会向列表中写入普通规则,你可以像对待其他规则一样查看、关闭或删除它们。拒绝连接是网络扩展的工作,因此在“捕获”中选择 nettop 采样器时,这些规则只是被监视,而不会被执行。";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "每个模板都会向列表中写入普通规则,你可以像对待其他规则一样查看、关闭或删除它们。拒绝连接是网络扩展的工作,因此在“来源 › 收集器”中选择 nettop 采样器时,这些规则只是被监视,而不会被执行。";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "可选。留空则适用于这台 Mac 上的一切;指明某个应用会把范围收窄到该应用以及它启动的工具。";
"A domain, an IP address, or a range" = "域名、IP 地址或地址段";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "这些规则指明了 HTTP 方法,因此只有 HTTPS 检查才能执行它们。检查关闭时,它们只会留在列表里监视。";
diff --git a/Flowlight/Localization/zh-Hant.lproj/Localizable.strings b/Flowlight/Localization/zh-Hant.lproj/Localizable.strings
index 0c2468c6..9fb87054 100644
--- a/Flowlight/Localization/zh-Hant.lproj/Localizable.strings
+++ b/Flowlight/Localization/zh-Hant.lproj/Localizable.strings
@@ -71,7 +71,6 @@
"Devices" = "裝置";
"Coverage" = "涵蓋範圍";
"Inspect" = "檢查";
-"Capture" = "擷取";
"Traffic" = "流量";
"Investigate" = "調查";
"Control" = "管控";
@@ -87,6 +86,7 @@
"Questions & Answers" = "常見問答";
"What Flowlight Reads on This Mac" = "Flowlight 在這台 Mac 上讀取哪些資料";
"Privacy" = "隱私權";
+"Data & Privacy" = "資料與隱私權";
"Report an Issue" = "回報問題";
"Turn Focus Off" = "關閉焦點";
"Turn Focus On" = "開啟焦點";
@@ -657,8 +657,6 @@
/* UI/CaptureView.swift */
"Delete all recorded traffic, baselines and alerts?" = "要刪除所有已記錄的流量、基線和警示嗎?";
"Delete everything" = "全部刪除";
-"nettop sampler · the extension didn't answer" = "nettop 取樣器 · 延伸功能沒有回應";
-"Network Extension · unavailable" = "網路延伸功能 · 無法使用";
"Couldn't reach the filter extension. Enable it under Content filter, then press Refresh." = "無法連接過濾器延伸功能。請在「內容過濾器」中啟用,然後按一下「重新整理」。";
"%@ — enable Flowlight under Content filter, then press Refresh." = "%@ — 請在「內容過濾器」中啟用 Flowlight,然後按一下「重新整理」。";
"%@ — the content filter is unavailable" = "%@ — 內容過濾器無法使用";
@@ -667,8 +665,6 @@
"Reconnect to the content filter" = "重新連接內容過濾器";
"If a VPN or security agent already has that slot — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar all use it — Flowlight's filter cannot receive traffic until that filter is disabled." = "如果 VPN 或安全代理程式已佔用該位置(Palo Alto Networks GlobalProtect、CrowdStrike Falcon 等都會使用),則停用該過濾器之前,Flowlight 的過濾器無法接收流量。";
"The filter isn't answering, so Flowlight is not receiving traffic. Enable it under Content filter, then press Refresh." = "過濾器沒有回應,因此 Flowlight 未收到流量。請在「內容過濾器」中啟用,然後按一下「重新整理」。";
-"%@ · receiving" = "%@ · 正在接收";
-"%@ · nothing arriving yet" = "%@ · 還沒有資料傳入";
"Source" = "來源";
"Content filter" = "內容過濾器";
"Observes eligible TCP and UDP flows as they open. Requires the Network Extension entitlement and your approval." = "在符合條件的 TCP 和 UDP 流量建立時就觀察它們。需要網路延伸功能的權利,以及你的允許。";
@@ -725,7 +721,7 @@
"Without this, most traffic shows only an IP address or network owner." = "沒有這項功能,大部分流量只會顯示 IP 位址或網路擁有者。";
"Flowlight reads DNS answers and TLS server names on your primary network interface to name connections." = "Flowlight 會讀取你主要網路介面上的 DNS 回應和 TLS 伺服器名稱,用來為連線命名。";
"Packet contents are never stored or sent anywhere. Only hostnames are kept." = "封包內容一律不會儲存,也不會送到任何地方。只保留主機名稱。";
-"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture." = "macOS 只允許管理者讀取封包,所以這會要求輸入一次密碼。你隨時可以在「擷取」中移除它。";
+"macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector." = "macOS 只允許管理者讀取封包,所以這會要求輸入一次密碼。你隨時可以在「來源 › 收集器」中移除它。";
"Identify network owners when no hostname is available" = "沒有主機名稱時,辨識網路擁有者";
"On by default. Sends public destination IPs to Team Cymru's DNS service. Turn off to keep these lookups on your Mac." = "預設開啟。會把公開的目標 IP 傳送到 Team Cymru 的 DNS 服務。關閉後,這些查詢只會在你的 Mac 上進行。";
"Not Now" = "現在不要";
@@ -756,8 +752,8 @@
/* UI/CoverageView.swift */
"Nothing recorded yet" = "還沒有記錄到任何東西";
+"Nothing recorded in the last hour" = "最近一小時內沒有記錄";
"Coverage is worked out from traffic Flowlight has already recorded. Leave it running for a moment." = "涵蓋範圍是從 Flowlight 已經記錄的流量算出來的。請讓它再執行一會兒。";
-"%@ of traffic fully accounted for" = "%@ 的流量完全有據可查";
"How much of this Mac is covered" = "這台 Mac 涵蓋了多少";
"HTTPS inspection is on" = "HTTPS 檢查已開啟";
"HTTPS inspection is off" = "HTTPS 檢查已關閉";
@@ -805,8 +801,6 @@
"Camera" = "相機";
"Started" = "已啟動";
"Unknown camera" = "未知相機";
-"%@ · nothing active" = "%@ · 沒有活動項目";
-"%@ · %lld active" = "%@ · %lld 個活動項目";
"Watch camera activity" = "監看相機活動";
"Bluetooth, USB and camera activity are off until you turn them on. They need no new permission — they're off because watching them widens what Flowlight looks at, and that should be your decision rather than something an update did.\n\nBluetooth and USB show what is connected. Camera activity shows whether each camera is active, not which app is using it. Flowlight never opens the camera or reads frames." = "藍牙、USB 和相機活動要等你開啟才會作用。它們不需要新的權限 — 預設關閉是因為監看它們會擴大 Flowlight 觀察的範圍,而這應該由你決定,不該是某次更新替你決定的。\n\n藍牙和 USB 會顯示連接的裝置。相機活動會顯示每部相機是否正在使用,但不會顯示是哪個 App 在使用它。Flowlight 絕不會開啟相機或讀取畫面。";
"No payloads or invented attribution. Bluetooth and USB show attachment, while camera monitoring reads only each device's active state. macOS exposes no public camera-owner identity here, so Flowlight names the camera, never guesses the app, and never reads frames." = "不讀取內容,也不捏造歸屬。藍牙和 USB 顯示連接狀態,相機監看只讀取各裝置是否正在使用。macOS 不會在這裡公開使用相機的 App,因此 Flowlight 只標示相機,絕不猜測 App,也不讀取畫面。";
@@ -1058,7 +1052,6 @@
"The network is quiet" = "網路很安靜";
"No app has sent or received data in the last few seconds." = "最近幾秒內沒有 App 傳送或接收資料。";
"Waiting for traffic data" = "正在等待流量資料";
-"Open Capture Settings" = "開啟擷取設定";
/* UI/MockRulesView.swift */
"Answer a chosen endpoint yourself instead of letting the request reach the server — a 500, a rate limit, a malformed body, or a long wait — and watch what the agent does about it." = "由你自己回應選定的端點,而不讓請求送到伺服器 — 一個 500、一次速率限制、一段格式錯誤的內文,或是長時間的等待 — 然後看代理會怎麼處理。";
@@ -1280,8 +1273,8 @@
"Until I resume" = "直到我手動恢復";
"Pause Blocking" = "暫停封鎖";
"Stand every rule down for a while, without deleting anything" = "讓所有規則暫時停止作用,不刪除任何東西";
-"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "有 1 條規則只被監看,沒有實際執行。只有網路延伸功能位在資料路徑上,能夠拒絕連線;nettop 取樣器是事後計數流量的。請在「擷取」中選擇網路延伸功能來實際執行這些規則。";
-"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules." = "有 %lld 條規則只被監看,沒有實際執行。只有網路延伸功能位在資料路徑上,能夠拒絕連線;nettop 取樣器是事後計數流量的。請在「擷取」中選擇網路延伸功能來實際執行這些規則。";
+"One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "有 1 條規則只被監看,沒有實際執行。只有網路延伸功能位在資料路徑上,能夠拒絕連線;nettop 取樣器是事後計數流量的。請在「來源 › 收集器」中選擇網路延伸功能來實際執行這些規則。";
+"%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules." = "有 %lld 條規則只被監看,沒有實際執行。只有網路延伸功能位在資料路徑上,能夠拒絕連線;nettop 取樣器是事後計數流量的。請在「來源 › 收集器」中選擇網路延伸功能來實際執行這些規則。";
"One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "有 1 條規則只被監看,沒有實際執行 — 指名路徑的規則只有 HTTPS 檢查才比對得到,而它已關閉。";
"%lld rules are being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off." = "有 %lld 條規則只被監看,沒有實際執行 — 指名路徑的規則只有 HTTPS 檢查才比對得到,而它已關閉。";
"In force" = "生效中";
@@ -1331,7 +1324,7 @@
"Apply a Template" = "套用範本";
"%@ · in force at once" = "%@ · 立即生效";
"%@ · shown first" = "%@ · 優先顯示";
-"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out." = "每個範本都會把一般的規則寫進列表,你可以像對待其他規則一樣閱讀、關閉或刪除它們。拒絕連線是網路延伸功能的工作,所以當「擷取」中選用 nettop 取樣器時,這些規則只會被監看,不會實際執行。";
+"Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out." = "每個範本都會把一般的規則寫進列表,你可以像對待其他規則一樣閱讀、關閉或刪除它們。拒絕連線是網路延伸功能的工作,所以在「來源 › 收集器」中選用 nettop 取樣器時,這些規則只會被監看,不會實際執行。";
"Optional. Left empty this applies to everything on the Mac; naming an app narrows it to that app and the tools it started." = "選填。留空表示套用到這台 Mac 上的所有項目;指名某個 App 則會縮小到該 App 以及它啟動的工具。";
"A domain, an IP address, or a range" = "網域、IP 位址或範圍";
"These name an HTTP method, so only HTTPS inspection can carry them out. With it off they sit in the list watching." = "這些規則指名了 HTTP 方法,所以只有 HTTPS 檢查能執行它們。在它關閉時,這些規則只會留在列表中監看。";
diff --git a/Flowlight/Storage/TrafficDatabase.swift b/Flowlight/Storage/TrafficDatabase.swift
index b7bc6f0d..da133f1c 100644
--- a/Flowlight/Storage/TrafficDatabase.swift
+++ b/Flowlight/Storage/TrafficDatabase.swift
@@ -2837,7 +2837,8 @@ final class TrafficDatabase: @unchecked Sendable {
}
/// Share of bytes in the window that carry a hostname, and that have at least an owner.
- func coverage(since: Date) throws -> (named: Double, owned: Double) {
+ /// `hasTraffic` distinguishes an honest 0% from a window with no evidence at all.
+ func coverage(since: Date) throws -> (named: Double, owned: Double, hasTraffic: Bool) {
let row = try conn.query("""
SELECT SUM(bytes_in + bytes_out),
SUM(CASE WHEN domain != '' THEN bytes_in + bytes_out ELSE 0 END),
@@ -2845,8 +2846,8 @@ final class TrafficDatabase: @unchecked Sendable {
FROM agg_1m LEFT JOIN ip_owners o ON o.ip = agg_1m.remote_ip
WHERE ts >= ? AND remote_ip != '(unconnected)'
""", [.int(Int64(since.timeIntervalSince1970))]) { ($0.double(0), $0.double(1), $0.double(2)) }.first
- guard let row, row.0 > 0 else { return (0, 0) }
- return (row.1 / row.0, row.2 / row.0)
+ guard let row, row.0 > 0 else { return (0, 0, false) }
+ return (row.1 / row.0, row.2 / row.0, true)
}
// MARK: Alerts
diff --git a/Flowlight/UI/AlertsView.swift b/Flowlight/UI/AlertsView.swift
index 075d609f..4c6fd742 100644
--- a/Flowlight/UI/AlertsView.swift
+++ b/Flowlight/UI/AlertsView.swift
@@ -17,26 +17,43 @@ struct AlertsView: View {
}
var body: some View {
- Group {
- if visible.isEmpty {
- ContentUnavailableView(alerts.isEmpty ? L("No alerts") : L("Nothing to review"), systemImage: "checkmark.shield",
- description: Text(alerts.isEmpty
- ? L("Each app has a learning period (24 h by default) before first-contact and spike rules fire.")
- : L("All matching alerts have been acknowledged.")))
- } else {
- table
+ VStack(spacing: 0) {
+ Picker(L("Alerts"), selection: $nav.alertsTab) {
+ ForEach(AlertsTab.allCases) { item in Text(item.title).tag(item) }
}
+ .pickerStyle(.segmented)
+ .labelsHidden()
+ .frame(maxWidth: 320)
+ .padding(.vertical, 10)
+
+ Divider()
+
+ Group {
+ if nav.alertsTab == .detection {
+ DetectionSettingsView()
+ } else if visible.isEmpty {
+ ContentUnavailableView(alerts.isEmpty ? L("No alerts") : L("Nothing to review"), systemImage: "checkmark.shield",
+ description: Text(alerts.isEmpty
+ ? L("Each app has a learning period (24 h by default) before first-contact and spike rules fire.")
+ : L("All matching alerts have been acknowledged.")))
+ } else {
+ table
+ }
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
}
.navigationTitle(L("Alerts"))
// The sidebar badge counts what is unread; this says how much there is to read at all, which is the
// difference between "quiet" and "already dealt with".
- .navigationSubtitle(alerts.isEmpty ? ""
+ .navigationSubtitle(nav.alertsTab == .detection ? L("Detection")
+ : alerts.isEmpty ? ""
: monitor.unacknowledgedAlerts == 0 ? L("%lld alerts, all acknowledged", alerts.count)
: L("%lld to review of %lld", monitor.unacknowledgedAlerts, alerts.count))
.toolbar { toolbar }
.task(id: monitor.dataVersion) { await load() }
.task(id: monitor.unacknowledgedAlerts) { await load() }
.task(id: focus.scope) { await load() }
+ .task(id: nav.alertsTab) { await load() }
}
private var table: some View {
@@ -112,34 +129,36 @@ struct AlertsView: View {
private var toolbar: some ToolbarContent {
// Two menus rather than four controls of four different shapes. The filter gathers everything that
// narrows the list; acknowledging is one verb with two objects, so it reads better as one button.
- ToolbarItemGroup {
- Menu {
- Picker(L("Rule"), selection: $rule) {
- Text(L("All rules")).tag("")
- ForEach(rules, id: \.self) { Text(AnomalyEngine.Kind.localizedName($0)).tag($0) }
+ if nav.alertsTab == .alerts {
+ ToolbarItemGroup {
+ Menu {
+ Picker(L("Rule"), selection: $rule) {
+ Text(L("All rules")).tag("")
+ ForEach(rules, id: \.self) { Text(AnomalyEngine.Kind.localizedName($0)).tag($0) }
+ }
+ .pickerStyle(.inline)
+ Divider()
+ Toggle(L("Show acknowledged"), isOn: $showAcknowledged)
+ } label: {
+ Label(filterLabel, systemImage: isFiltered ? "line.3.horizontal.decrease.circle.fill"
+ : "line.3.horizontal.decrease.circle")
}
- .pickerStyle(.inline)
- Divider()
- Toggle(L("Show acknowledged"), isOn: $showAcknowledged)
- } label: {
- Label(filterLabel, systemImage: isFiltered ? "line.3.horizontal.decrease.circle.fill"
- : "line.3.horizontal.decrease.circle")
- }
- .labelStyle(.titleAndIcon) // icon-only reads as two mystery buttons in the corner
- .disabled(alerts.isEmpty)
- .help(L("Filter which alerts are listed"))
+ .labelStyle(.titleAndIcon) // icon-only reads as two mystery buttons in the corner
+ .disabled(alerts.isEmpty)
+ .help(L("Filter which alerts are listed"))
- Menu {
- Button(L("Selected (%lld)", selection.count)) { monitor.acknowledgeAlerts(ids: Array(selection)) }
- .disabled(selection.isEmpty)
- Button(L("All unacknowledged (%lld)", monitor.unacknowledgedAlerts)) { monitor.acknowledgeAlerts(ids: nil) }
- .disabled(monitor.unacknowledgedAlerts == 0)
- } label: {
- Label(L("Acknowledge"), systemImage: "checkmark.circle")
+ Menu {
+ Button(L("Selected (%lld)", selection.count)) { monitor.acknowledgeAlerts(ids: Array(selection)) }
+ .disabled(selection.isEmpty)
+ Button(L("All unacknowledged (%lld)", monitor.unacknowledgedAlerts)) { monitor.acknowledgeAlerts(ids: nil) }
+ .disabled(monitor.unacknowledgedAlerts == 0)
+ } label: {
+ Label(L("Acknowledge"), systemImage: "checkmark.circle")
+ }
+ .labelStyle(.titleAndIcon)
+ .disabled(alerts.isEmpty)
+ .help(L("Mark alerts as seen"))
}
- .labelStyle(.titleAndIcon)
- .disabled(alerts.isEmpty)
- .help(L("Mark alerts as seen"))
}
}
@@ -166,6 +185,7 @@ struct AlertsView: View {
}
private func load() async {
+ guard nav.alertsTab == .alerts else { return }
let scope = focus.scope
alerts = (try? await monitor.read { try $0.alerts(focus: scope) }) ?? []
}
diff --git a/Flowlight/UI/AskView.swift b/Flowlight/UI/AskView.swift
index 3bd7f19f..553ce4d4 100644
--- a/Flowlight/UI/AskView.swift
+++ b/Flowlight/UI/AskView.swift
@@ -76,10 +76,10 @@ private struct AskContent: View {
if let filter = call.filter {
nav.showReport(filter: filter, end: call.to)
} else if let screen = call.screen {
- nav.show(screen)
+ open(screen, sourcesTab: call.sourcesTab)
}
- } go: { screen in
- nav.show(screen)
+ } go: { call in
+ if let screen = call.screen { open(screen, sourcesTab: call.sourcesTab) }
}
.entrance()
if turn.id != ask.turns.last?.id { Divider() }
@@ -91,6 +91,14 @@ private struct AskContent: View {
}
}
+ private func open(_ screen: SidebarItem, sourcesTab: SourcesTab?) {
+ if screen == .sources {
+ nav.showSources(sourcesTab ?? .collector)
+ } else {
+ nav.show(screen)
+ }
+ }
+
// MARK: Asking
private var composer: some View {
@@ -192,7 +200,7 @@ private struct AskTurnView: View {
let turn: AskTurn
let thinking: Bool
let open: (AskRecordedCall) -> Void
- let go: (SidebarItem) -> Void
+ let go: (AskRecordedCall) -> Void
@State private var showingSent = false
@State private var showingCalls = false
@@ -223,12 +231,12 @@ private struct AskTurnView: View {
if let charted = turn.calls.first(where: { $0.chart != nil }), let chart = charted.chart {
AskChartView(chart: chart).entrance()
}
- if let screen = turn.calls.compactMap(\.screen).first {
+ if let destination = turn.calls.first(where: { $0.screen != nil }), let screen = destination.screen {
// An answer about the app should end somewhere you can act on it — but the app moves when you
// click, not when the model decides to. The documentation sits beside it for the longer version,
// opened at the section about that same screen.
HStack(spacing: 14) {
- Button(L("Open %@", screen.title)) { go(screen) }
+ Button(L("Open %@", screen.title)) { go(destination) }
Button(L("Documentation")) { NSWorkspace.shared.open(Help.forScreen(screen)) }
}
.buttonStyle(.link)
diff --git a/Flowlight/UI/CaptureView.swift b/Flowlight/UI/CaptureView.swift
index 30775ab3..815dbd01 100644
--- a/Flowlight/UI/CaptureView.swift
+++ b/Flowlight/UI/CaptureView.swift
@@ -1,5 +1,180 @@
import SwiftUI
+/// Pure recovery-state decisions keep the Sources checklist honest and easy to exercise without constructing views.
+enum SourceSetupPolicy {
+ enum CoverageHealth: Equatable { case empty, good, warning }
+
+ static func coverageHealth(named: Double, hasTraffic: Bool) -> CoverageHealth {
+ guard hasTraffic else { return .empty }
+ return named > 0.8 ? .good : .warning
+ }
+
+ static func collectorConfigured(mode: CaptureMode, extensionState: ExtensionManager.State,
+ extensionFellBack: Bool) -> Bool {
+ if mode == .nettop { return true }
+ return extensionState == .enabled && !extensionFellBack
+ }
+
+ static func setupComplete(mode: CaptureMode, extensionState: ExtensionManager.State,
+ extensionFellBack: Bool, isReceiving: Bool) -> Bool {
+ collectorConfigured(mode: mode, extensionState: extensionState,
+ extensionFellBack: extensionFellBack) && isReceiving
+ }
+}
+
+/// Collector setup, device channels and coverage belong to one operational destination. The compact health strip
+/// answers "is Flowlight working?" before someone has to know which of the three tabs contains the recovery action.
+struct SourcesView: View {
+ @Binding var selection: SourcesTab
+ @EnvironmentObject var monitor: TrafficMonitor
+ @EnvironmentObject var extensionManager: ExtensionManager
+
+ var body: some View {
+ VStack(spacing: 0) {
+ VStack(alignment: .leading, spacing: 10) {
+ Picker(L("Sources"), selection: $selection) {
+ ForEach(SourcesTab.allCases) { tab in Text(tab.title).tag(tab) }
+ }
+ .pickerStyle(.segmented)
+ .labelsHidden()
+ .frame(maxWidth: 420)
+
+ HStack(spacing: 10) {
+ healthCard(.collector, icon: "antenna.radiowaves.left.and.right",
+ title: L("Collector"), detail: collectorDetail,
+ tint: monitor.isReceiving ? FL.good : FL.warning)
+ healthCard(.coverage, icon: "circle.dashed.inset.filled",
+ title: L("Coverage"), detail: coverageDetail,
+ tint: coverageTint)
+ healthCard(.devices, icon: "dot.radiowaves.left.and.right",
+ title: L("Devices"), detail: deviceDetail,
+ tint: monitor.devices.isWatchingAnything ? FL.good : .secondary)
+ }
+
+ if !sourceSetupComplete { sourceRecoveryChecklist }
+ }
+ .padding(.horizontal, Measure.gutter)
+ .padding(.vertical, 12)
+ .background(.bar)
+ .overlay(alignment: .bottom) { Divider() }
+
+ Group {
+ switch selection {
+ case .collector: CaptureView()
+ case .devices: DevicesView()
+ case .coverage: CoverageView()
+ }
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ }
+ .navigationTitle(L("Sources"))
+ .navigationSubtitle(selection.title)
+ }
+
+ private var collectorDetail: String {
+ if monitor.extensionFellBack {
+ #if APP_STORE
+ // The Store product has no sampler fallback; its fail-closed source is unavailable, not nettop.
+ return L("Nothing is arriving")
+ #else
+ return L("nettop sampler")
+ #endif
+ }
+ return monitor.isReceiving ? L("Data is arriving") : L("Nothing is arriving")
+ }
+
+ private var coverageHealth: SourceSetupPolicy.CoverageHealth {
+ SourceSetupPolicy.coverageHealth(named: monitor.coverage.named,
+ hasTraffic: monitor.coverage.hasTraffic)
+ }
+
+ private var coverageDetail: String {
+ guard coverageHealth != .empty else { return L("Nothing recorded in the last hour") }
+ return "\(monitor.coverage.named.formatted(.percent.precision(.fractionLength(0)))) \(L("Named"))"
+ }
+
+ private var coverageTint: Color {
+ switch coverageHealth {
+ case .empty: return .secondary
+ case .good: return FL.good
+ case .warning: return FL.warning
+ }
+ }
+
+ private var deviceDetail: String {
+ guard monitor.devices.isWatchingAnything else { return L("Not watching") }
+ var channels: [String] = []
+ if monitor.devices.watchingBluetooth { channels.append(L("Bluetooth")) }
+ if monitor.devices.watchingUSB { channels.append(L("USB")) }
+ if monitor.devices.watchingCamera { channels.append(L("Camera")) }
+ return channels.joined(separator: " · ")
+ }
+
+ private var collectorConfigured: Bool {
+ SourceSetupPolicy.collectorConfigured(mode: monitor.mode, extensionState: extensionManager.state,
+ extensionFellBack: monitor.extensionFellBack)
+ }
+
+ private var sourceSetupComplete: Bool {
+ SourceSetupPolicy.setupComplete(mode: monitor.mode, extensionState: extensionManager.state,
+ extensionFellBack: monitor.extensionFellBack,
+ isReceiving: monitor.isReceiving)
+ }
+
+ /// A short recovery path stays beside the source status. It reports completed steps instead of presenting one
+ /// generic error, and the action opens the one place where every unfinished step can be repaired.
+ private var sourceRecoveryChecklist: some View {
+ HStack(alignment: .top, spacing: 14) {
+ VStack(alignment: .leading, spacing: 7) {
+ Text(monitor.isReceiving ? L("Collector") : L("Nothing is arriving"))
+ .font(.caption.weight(.semibold))
+ checklistRow(monitor.mode == .networkExtension ? L("Network Extension") : L("nettop sampler"),
+ complete: collectorConfigured)
+ checklistRow(L("Data is arriving"), complete: monitor.isReceiving)
+ }
+ Spacer(minLength: 8)
+ Button { selection = .collector } label: {
+ Label(L("Collector"), systemImage: "chevron.right")
+ .labelStyle(.titleAndIcon)
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.small)
+ }
+ .padding(10)
+ .background(FL.warning.opacity(0.10), in: RoundedRectangle(cornerRadius: 9))
+ .overlay(RoundedRectangle(cornerRadius: 9).stroke(FL.warning.opacity(0.25)))
+ }
+
+ private func checklistRow(_ title: String, complete: Bool) -> some View {
+ Label(title, systemImage: complete ? "checkmark.circle.fill" : "circle")
+ .font(.caption)
+ .foregroundStyle(complete ? FL.good : .secondary)
+ }
+
+ private func healthCard(_ tab: SourcesTab, icon: String, title: String,
+ detail: String, tint: Color) -> some View {
+ Button { selection = tab } label: {
+ HStack(alignment: .top, spacing: 9) {
+ Image(systemName: icon)
+ .foregroundStyle(tint)
+ .frame(width: 22, height: 22)
+ VStack(alignment: .leading, spacing: 2) {
+ Text(title).font(.caption.weight(.semibold))
+ Text(detail).font(.caption2).foregroundStyle(.secondary).lineLimit(1)
+ }
+ Spacer(minLength: 0)
+ }
+ .padding(10)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .background(selection == tab ? FL.accent.opacity(0.10) : Color.secondary.opacity(0.07),
+ in: RoundedRectangle(cornerRadius: 9))
+ .contentShape(Rectangle())
+ }
+ .buttonStyle(.plain)
+ .accessibilityAddTraits(selection == tab ? .isSelected : [])
+ }
+}
+
/// Where Flowlight's data comes from, and everything that decides whether it can come from there.
///
/// The screen is read top down, in the order the questions are asked: which source is chosen, whether anything is
@@ -9,7 +184,6 @@ import SwiftUI
struct CaptureView: View {
@EnvironmentObject var monitor: TrafficMonitor
@EnvironmentObject var extensionManager: ExtensionManager
- @State private var confirmClear = false
@State private var showExtensionSetup = false
@State private var otherFilters: [InstalledSystemExtension] = []
@@ -35,36 +209,16 @@ struct CaptureView: View {
#if !APP_STORE
if monitor.mode == .nettop { HostnameSection() }
#endif
- storageSection
}
// A settings panel is read, not scanned, and a line of prose stretched across a maximised window is
// unreadable. The column stops at a comfortable measure and stays against the sidebar rather than
// floating in the middle of the window.
.padding(Measure.gutter)
}
- .navigationTitle(L("Capture"))
- // The one thing worth a trip to this screen to find out — what is feeding the app right now — said in the
- // title bar, so it can be read from any other screen's neighbour.
- .navigationSubtitle(subtitle)
#if !APP_STORE
// Which other content filters exist decides whether ours can work at all, so it's read when the screen opens.
.task { otherFilters = SystemExtensionScan.competingFilters(in: await SystemExtensionScan.read()) }
#endif
- .confirmationDialog(L("Delete all recorded traffic, baselines and alerts?"), isPresented: $confirmClear) {
- Button(L("Delete everything"), role: .destructive) { monitor.clearAllData() }
- }
- }
-
- private var subtitle: String {
- if monitor.extensionFellBack {
- #if APP_STORE
- return L("Network Extension · unavailable")
- #else
- return L("nettop sampler · the extension didn't answer")
- #endif
- }
- let source = monitor.mode == .networkExtension ? L("Network Extension") : L("nettop sampler")
- return monitor.isReceiving ? L("%@ · receiving", source) : L("%@ · nothing arriving yet", source)
}
// MARK: Source
@@ -350,33 +504,6 @@ struct CaptureView: View {
}
.padding(.horizontal, 12).padding(.bottom, 14).padding(.leading, 38)
}
-
- // MARK: Storage
-
- private var storageSection: some View {
- VStack(alignment: .leading, spacing: 8) {
- CaptureHeading(L("Storage"))
- VStack(alignment: .leading, spacing: 10) {
- HStack(alignment: .top, spacing: 12) {
- CaptureGlyph(symbol: "internaldrive", tint: .secondary)
- VStack(alignment: .leading, spacing: 3) {
- Text(L("Database")).font(.body.weight(.medium))
- Text(monitor.db.url.path)
- .font(.caption.monospaced()).foregroundStyle(.secondary)
- .textSelection(.enabled)
- .frame(maxWidth: .infinity, alignment: .leading)
- }
- }
- HStack(spacing: 8) {
- Button(L("Reveal in Finder")) { NSWorkspace.shared.activateFileViewerSelecting([monitor.db.url]) }
- Spacer(minLength: 8)
- Button(L("Clear All Data…"), role: .destructive) { confirmClear = true }
- }
- .controlSize(.small)
- }
- .captureCard()
- }
- }
}
/// Where hostnames come from in nettop mode, with the one-time packet-capture setup.
@@ -551,7 +678,7 @@ struct CaptureOnboardingView: View {
VStack(alignment: .leading, spacing: 10) {
point("text.magnifyingglass", L("Flowlight reads DNS answers and TLS server names on your primary network interface to name connections."))
point("lock.shield", L("Packet contents are never stored or sent anywhere. Only hostnames are kept."))
- point("key", L("macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Capture."))
+ point("key", L("macOS only lets administrators read packets, so this asks for your password once. You can remove it any time in Sources › Collector."))
}
Toggle(isOn: $ownerLookup) {
diff --git a/Flowlight/UI/ContentView.swift b/Flowlight/UI/ContentView.swift
index 7ed9e650..39685c3c 100644
--- a/Flowlight/UI/ContentView.swift
+++ b/Flowlight/UI/ContentView.swift
@@ -15,6 +15,9 @@ struct ContentView: View {
NavigationSplitView {
List(selection: Binding(get: { nav.selection }, set: { value in
guard let value, value != nav.selection else { return }
+ // AppKit can replay a restored sidebar row after screenshot launch arguments have selected a screen.
+ // Pin only deterministic demo captures; ordinary demo sessions remain navigable.
+ guard !(DemoData.isEnabled && UserDefaults.standard.bool(forKey: "FLPinScreenshotScreen")) else { return }
// AppKit reports selection from inside NSTableView's delegate callback. A main-actor Task can begin
// before that callback unwinds, so dispatch explicitly to the next run-loop turn before publishing
// navigation. AppKit warns about the reentrant reload today and will assert on it in the future.
@@ -53,7 +56,7 @@ struct ContentView: View {
}
#endif
FocusBar()
- Button { nav.show(.capture) } label: {
+ Button { nav.showSources(.collector) } label: {
HStack(alignment: .top, spacing: 8) {
LiveDot(color: monitor.isReceiving ? FL.good : FL.warning, active: monitor.isReceiving)
.padding(.top, 4)
@@ -89,9 +92,7 @@ struct ContentView: View {
InspectView()
#endif
case .ask: AskView()
- case .devices: DevicesView()
- case .coverage: CoverageView()
- case .capture: CaptureView()
+ case .sources: SourcesView(selection: $nav.sourcesTab)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
diff --git a/Flowlight/UI/CoverageView.swift b/Flowlight/UI/CoverageView.swift
index 203657ad..8900c456 100644
--- a/Flowlight/UI/CoverageView.swift
+++ b/Flowlight/UI/CoverageView.swift
@@ -35,8 +35,6 @@ private struct CoverageContent: View {
}
.padding(Measure.gutter)
}
- .navigationTitle(L("Coverage"))
- .navigationSubtitle(subtitle)
.toolbar {
ToolbarItem(placement: .primaryAction) {
Picker(L("Window"), selection: $window) {
@@ -50,12 +48,6 @@ private struct CoverageContent: View {
private struct LoadKey: Equatable { var window: AgentWindow; var version: Int; var inspecting: Bool }
- private var subtitle: String {
- guard !rows.isEmpty else { return L("Nothing recorded yet") }
- return L("%@ of traffic fully accounted for",
- CoverageReport.overall(rows).formatted(.percent.precision(.fractionLength(0))))
- }
-
/// The two engine-wide facts first, because they explain most of the rows underneath and are fixed in one
/// place rather than per app.
private var summary: some View {
diff --git a/Flowlight/UI/DevicesView.swift b/Flowlight/UI/DevicesView.swift
index 38574f48..17936168 100644
--- a/Flowlight/UI/DevicesView.swift
+++ b/Flowlight/UI/DevicesView.swift
@@ -25,25 +25,9 @@ private struct DevicesContent: View {
offer
}
}
- .navigationTitle(L("Devices"))
- .navigationSubtitle(subtitle)
.toolbar { toolbar }
}
- /// Which channels are on, and how much of it is live. Both channels are off by default, so "nothing here" and
- /// "not watching" look the same on the screen — the title bar is where that difference can be stated once.
- private var subtitle: String {
- var on: [String] = []
- if store.watchingBluetooth { on.append(L("Bluetooth")) }
- if store.watchingUSB { on.append(L("USB")) }
- if store.watchingCamera { on.append(L("Camera")) }
- guard !on.isEmpty else { return L("Not watching") }
- let active = store.bluetooth.filter(\.connected).count + store.usb.count
- + store.cameras.filter { $0.state == .active }.count
- let channels = on.joined(separator: " · ")
- return active == 0 ? L("%@ · nothing active", channels) : L("%@ · %lld active", channels, active)
- }
-
@ToolbarContentBuilder
private var toolbar: some ToolbarContent {
ToolbarItemGroup {
diff --git a/Flowlight/UI/LiveView.swift b/Flowlight/UI/LiveView.swift
index 88fd21d1..edacf629 100644
--- a/Flowlight/UI/LiveView.swift
+++ b/Flowlight/UI/LiveView.swift
@@ -108,7 +108,7 @@ struct LiveView: View {
Text(monitor.status)
}
} actions: {
- Button(L("Open Capture Settings")) { nav.show(.capture) }
+ Button(L("Sources")) { nav.showSources(.collector) }
}
}
}
diff --git a/Flowlight/UI/ReportsView.swift b/Flowlight/UI/ReportsView.swift
index 2575ff31..f60f974c 100644
--- a/Flowlight/UI/ReportsView.swift
+++ b/Flowlight/UI/ReportsView.swift
@@ -420,11 +420,15 @@ struct ReportsView: View {
private var coverageNotice: some View {
HStack(spacing: 6) {
Image(systemName: "info.circle")
- Text(L("Hostname coverage, last hour: %@ of bytes",
- monitor.coverage.named.formatted(.percent.precision(.fractionLength(0)))))
- Text("·")
- Text(L("including network owners: %@",
- monitor.coverage.owned.formatted(.percent.precision(.fractionLength(0)))))
+ if monitor.coverage.hasTraffic {
+ Text(L("Hostname coverage, last hour: %@ of bytes",
+ monitor.coverage.named.formatted(.percent.precision(.fractionLength(0)))))
+ Text("·")
+ Text(L("including network owners: %@",
+ monitor.coverage.owned.formatted(.percent.precision(.fractionLength(0)))))
+ } else {
+ Text(L("Nothing recorded in the last hour"))
+ }
}
.font(.caption)
.foregroundStyle(.secondary)
diff --git a/Flowlight/UI/RulesView.swift b/Flowlight/UI/RulesView.swift
index 59a37747..94d6323d 100644
--- a/Flowlight/UI/RulesView.swift
+++ b/Flowlight/UI/RulesView.swift
@@ -159,8 +159,8 @@ struct RulesView: View {
// sentence is a sentence no translator can shape.
if monitor.mode != .networkExtension && blind.contains(where: { $0.engine == .flow }) {
return blind.count == 1
- ? L("One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules.")
- : L("%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Capture to enforce these rules.", blind.count)
+ ? L("One rule is being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules.")
+ : L("%lld rules are being watched but not carried out. Only the Network Extension sits in the data path and can refuse a connection; the nettop sampler counts traffic after the fact. Select the Network Extension in Sources › Collector to enforce these rules.", blind.count)
}
return blind.count == 1
? L("One rule is being watched but not carried out — a rule that names a path can only be matched by HTTPS inspection, and it is off.")
@@ -732,7 +732,7 @@ struct RuleTemplateLibrary: View {
private var header: some View {
VStack(alignment: .leading, spacing: 6) {
Text(L("Templates")).font(.title3.weight(.semibold))
- Text(L("Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Capture these are watched rather than carried out."))
+ Text(L("Each one writes ordinary rules into the list, where they can be read, switched off or deleted like anything else. Refusing a connection is the Network Extension's job, so with the nettop sampler selected in Sources › Collector these are watched rather than carried out."))
.font(.callout).foregroundStyle(.secondary).fixedSize(horizontal: false, vertical: true)
}
.padding(Measure.gutter)
diff --git a/Flowlight/UI/SettingsView.swift b/Flowlight/UI/SettingsView.swift
index 84daa6dd..d5fda6e2 100644
--- a/Flowlight/UI/SettingsView.swift
+++ b/Flowlight/UI/SettingsView.swift
@@ -2,25 +2,10 @@ import ServiceManagement
import SwiftUI
struct SettingsView: View {
- @EnvironmentObject var monitor: TrafficMonitor
typealias K = AnomalySettings.Keys
- @AppStorage(K.sigma) private var sigma = 3.0
- @AppStorage(K.learningHours) private var learningHours = 24.0
- @AppStorage(K.minAlertMB) private var minAlertMB = 1.0
- @AppStorage(K.idleMinutes) private var idleMinutes = 10.0
- @AppStorage(K.idleUploadMB) private var idleUploadMB = 5.0
- @AppStorage(K.firstContact) private var firstContact = true
- @AppStorage(K.nonStandardPorts) private var nonStandardPorts = true
- @AppStorage(K.ignoreAppleApps) private var ignoreAppleApps = true
@AppStorage(K.notifications) private var notifications = true
- @AppStorage(K.retentionHours) private var retentionHours = 6.0
@AppStorage(K.menuBarRates) private var menuBarRates = true
- @AppStorage(K.agentSensitive) private var agentSensitive = true
- @AppStorage(K.agentUnnamed) private var agentUnnamed = true
- @AppStorage(K.agentEgressMB) private var agentEgressMB = 100.0
- @AppStorage(K.agentAway) private var agentAway = true
- @AppStorage(K.agentAwayMinutes) private var agentAwayMinutes = 15.0
- @AppStorage(AnomalySettings.Keys.backgroundOnly) private var backgroundOnly = false
+ @AppStorage(K.backgroundOnly) private var backgroundOnly = false
// Read once the pane is on screen, never in the property's default expression: that
// expression re-runs every time this struct is constructed, and `Settings { }` is
// rebuilt whenever the App body is invalidated — which TrafficMonitor does every
@@ -28,7 +13,6 @@ struct SettingsView: View {
// form put blocking IPC on the main thread at 1 Hz for the life of the process.
@State private var launchAtLogin = false
@State private var loginItemError: String?
- @State private var showClearLocalRiskConfirmation = false
var body: some View {
TabView {
@@ -55,60 +39,8 @@ struct SettingsView: View {
.frame(height: 340)
.tabItem { Label(L("General"), systemImage: "gearshape") }
- Form {
- Section {
- Stepper(value: $sigma, in: 1.5...10, step: 0.5) { LabeledContent(L("Z-score threshold"), value: "\(sigma.formatted())σ") }
- Stepper(value: $learningHours, in: 0...336, step: 6) { LabeledContent(L("Learning period per app"), value: L("%lld h", Int(learningHours))) }
- Stepper(value: $minAlertMB, in: 0...1000, step: 1) { LabeledContent(L("Ignore hours below"), value: L("%@ MB", minAlertMB.formatted())) }
- } footer: {
- Text(L("Hourly traffic and daily destination counts are compared with each app's rolling baseline."))
- .font(.caption).foregroundStyle(.secondary)
- }
- Section(L("Rules")) {
- Toggle(L("First contact with a new domain"), isOn: $firstContact)
- Toggle(L("Connections to non-standard ports"), isOn: $nonStandardPorts)
- Toggle(L("Ignore Apple's own apps"), isOn: $ignoreAppleApps)
- Text(L("macOS talks to Apple constantly — updates, iCloud, push, time — and reporting all of it buries the one line that matters. Their traffic is still recorded, still shown in Live and History, and still subject to every rule and guardrail."))
- .font(.caption).foregroundStyle(.secondary)
- }
- Section {
- Toggle(L("Agent uses email, file transfer, SSH, tunnels or databases"), isOn: $agentSensitive)
- Toggle(L("Agent connects to a raw IP on an unusual port"), isOn: $agentUnnamed)
- Stepper(value: $agentEgressMB, in: 1...10_000, step: 10) {
- LabeledContent(L("Uploads to non-AI hosts above"), value: L("%lld MB/h", Int(agentEgressMB)))
- }
- Toggle(L("Agent active while you're away"), isOn: $agentAway)
- Stepper(value: $agentAwayMinutes, in: 1...240, step: 1) {
- LabeledContent(L("Away after"), value: L("%lld min without input", Int(agentAwayMinutes)))
- }
- .disabled(!agentAway)
- } header: {
- Text(L("AI agents"))
- } footer: {
- Text(L("Agents include recognized tools such as Claude Code, Codex and Cursor, plus non-browser apps that contact a known LLM API provider. Their learning period is 1 hour instead of 24 hours."))
- .font(.caption).foregroundStyle(.secondary)
- }
- Section(L("Traffic without UI activity")) {
- Stepper(value: $idleMinutes, in: 1...240, step: 1) { LabeledContent(L("App idle for at least"), value: L("%lld min", Int(idleMinutes))) }
- Stepper(value: $idleUploadMB, in: 0.5...1000, step: 0.5) { LabeledContent(L("Uploading more than"), value: L("%@ MB/min", idleUploadMB.formatted())) }
- }
- LocalRiskSettingsSection(showClearConfirmation: $showClearLocalRiskConfirmation)
- }
- .formStyle(.grouped)
- .frame(height: 640)
- .tabItem { Label(L("Detection"), systemImage: "waveform.badge.exclamationmark") }
-
- Form {
- Section {
- Stepper(value: $retentionHours, in: 1...72, step: 1) { LabeledContent(L("Keep per-second data"), value: L("%lld h", Int(retentionHours))) }
- } footer: {
- Text(L("Minute rollups are kept 14 days, hourly 400 days, daily forever. Alerts are kept 90 days."))
- .font(.caption).foregroundStyle(.secondary)
- }
- }
- .formStyle(.grouped)
- .frame(height: 150)
- .tabItem { Label(L("Storage"), systemImage: "internaldrive") }
+ DataPrivacySettingsTab()
+ .tabItem { Label(L("Data & Privacy"), systemImage: "hand.raised.square") }
#if !APP_STORE
PluginSettingsView()
@@ -118,12 +50,7 @@ struct SettingsView: View {
ExportSettingsTab()
.tabItem { Label(L("Export"), systemImage: "arrow.up.forward.square") }
}
- .frame(width: 500)
- .confirmationDialog(L("Clear local analyses?"), isPresented: $showClearLocalRiskConfirmation, titleVisibility: .visible) {
- Button(L("Clear analyses"), role: .destructive) { monitor.clearLocalRiskAnalyses() }
- } message: {
- Text(L("This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place."))
- }
+ .frame(width: 540)
}
private func setLaunchAtLogin(_ enabled: Bool) {
@@ -137,6 +64,137 @@ struct SettingsView: View {
}
}
+/// Durable local-data choices stay in Settings; source operation and alert tuning live where their effects appear.
+struct DataPrivacySettingsTab: View {
+ @EnvironmentObject var monitor: TrafficMonitor
+ @AppStorage(AnomalySettings.Keys.retentionHours) private var retentionHours = 6.0
+ @State private var confirmClear = false
+
+ var body: some View {
+ Form {
+ Section {
+ Stepper(value: $retentionHours, in: 1...72, step: 1) {
+ LabeledContent(L("Keep per-second data"), value: L("%lld h", Int(retentionHours)))
+ }
+ } header: {
+ Text(L("Storage"))
+ } footer: {
+ Text(L("Minute rollups are kept 14 days, hourly 400 days, daily forever. Alerts are kept 90 days."))
+ .font(.caption).foregroundStyle(.secondary)
+ }
+ Section {
+ LabeledContent(L("Database")) {
+ Text(monitor.db.url.path)
+ .font(.caption.monospaced())
+ .foregroundStyle(.secondary)
+ .textSelection(.enabled)
+ .lineLimit(2)
+ }
+ Button(L("Reveal in Finder")) {
+ NSWorkspace.shared.activateFileViewerSelecting([monitor.db.url])
+ }
+ Button(L("Clear All Data…"), role: .destructive) { confirmClear = true }
+ } header: {
+ Text(L("Data & Privacy"))
+ }
+ }
+ .formStyle(.grouped)
+ .frame(height: 300)
+ .confirmationDialog(L("Delete all recorded traffic, baselines and alerts?"), isPresented: $confirmClear) {
+ Button(L("Delete everything"), role: .destructive) { monitor.clearAllData() }
+ }
+ // Settings is a separate scene. A database-clear failure must be visible here even when the main window,
+ // which has its own monitor error alert, is closed or behind this one.
+ .alert(L("Error"), isPresented: Binding(
+ get: { monitor.lastError != nil },
+ set: { if !$0 { monitor.lastError = nil } }
+ )) {
+ Button(L("OK")) { monitor.lastError = nil }
+ } message: {
+ Text(monitor.lastError ?? "")
+ }
+ }
+}
+
+/// Alert sensitivity is edited beside the alerts it produces instead of in a remote Settings tab.
+struct DetectionSettingsView: View {
+ @EnvironmentObject var monitor: TrafficMonitor
+ typealias K = AnomalySettings.Keys
+ @AppStorage(K.sigma) private var sigma = 3.0
+ @AppStorage(K.learningHours) private var learningHours = 24.0
+ @AppStorage(K.minAlertMB) private var minAlertMB = 1.0
+ @AppStorage(K.idleMinutes) private var idleMinutes = 10.0
+ @AppStorage(K.idleUploadMB) private var idleUploadMB = 5.0
+ @AppStorage(K.firstContact) private var firstContact = true
+ @AppStorage(K.nonStandardPorts) private var nonStandardPorts = true
+ @AppStorage(K.ignoreAppleApps) private var ignoreAppleApps = true
+ @AppStorage(K.agentSensitive) private var agentSensitive = true
+ @AppStorage(K.agentUnnamed) private var agentUnnamed = true
+ @AppStorage(K.agentEgressMB) private var agentEgressMB = 100.0
+ @AppStorage(K.agentAway) private var agentAway = true
+ @AppStorage(K.agentAwayMinutes) private var agentAwayMinutes = 15.0
+ @State private var showClearLocalRiskConfirmation = false
+
+ var body: some View {
+ Form {
+ Section {
+ Stepper(value: $sigma, in: 1.5...10, step: 0.5) {
+ LabeledContent(L("Z-score threshold"), value: "\(sigma.formatted())σ")
+ }
+ Stepper(value: $learningHours, in: 0...336, step: 6) {
+ LabeledContent(L("Learning period per app"), value: L("%lld h", Int(learningHours)))
+ }
+ Stepper(value: $minAlertMB, in: 0...1000, step: 1) {
+ LabeledContent(L("Ignore hours below"), value: L("%@ MB", minAlertMB.formatted()))
+ }
+ } footer: {
+ Text(L("Hourly traffic and daily destination counts are compared with each app's rolling baseline."))
+ .font(.caption).foregroundStyle(.secondary)
+ }
+ Section(L("Rules")) {
+ Toggle(L("First contact with a new domain"), isOn: $firstContact)
+ Toggle(L("Connections to non-standard ports"), isOn: $nonStandardPorts)
+ Toggle(L("Ignore Apple's own apps"), isOn: $ignoreAppleApps)
+ Text(L("macOS talks to Apple constantly — updates, iCloud, push, time — and reporting all of it buries the one line that matters. Their traffic is still recorded, still shown in Live and History, and still subject to every rule and guardrail."))
+ .font(.caption).foregroundStyle(.secondary)
+ }
+ Section {
+ Toggle(L("Agent uses email, file transfer, SSH, tunnels or databases"), isOn: $agentSensitive)
+ Toggle(L("Agent connects to a raw IP on an unusual port"), isOn: $agentUnnamed)
+ Stepper(value: $agentEgressMB, in: 1...10_000, step: 10) {
+ LabeledContent(L("Uploads to non-AI hosts above"), value: L("%lld MB/h", Int(agentEgressMB)))
+ }
+ Toggle(L("Agent active while you're away"), isOn: $agentAway)
+ Stepper(value: $agentAwayMinutes, in: 1...240, step: 1) {
+ LabeledContent(L("Away after"), value: L("%lld min without input", Int(agentAwayMinutes)))
+ }
+ .disabled(!agentAway)
+ } header: {
+ Text(L("AI agents"))
+ } footer: {
+ Text(L("Agents include recognized tools such as Claude Code, Codex and Cursor, plus non-browser apps that contact a known LLM API provider. Their learning period is 1 hour instead of 24 hours."))
+ .font(.caption).foregroundStyle(.secondary)
+ }
+ Section(L("Traffic without UI activity")) {
+ Stepper(value: $idleMinutes, in: 1...240, step: 1) {
+ LabeledContent(L("App idle for at least"), value: L("%lld min", Int(idleMinutes)))
+ }
+ Stepper(value: $idleUploadMB, in: 0.5...1000, step: 0.5) {
+ LabeledContent(L("Uploading more than"), value: L("%@ MB/min", idleUploadMB.formatted()))
+ }
+ }
+ LocalRiskSettingsSection(showClearConfirmation: $showClearLocalRiskConfirmation)
+ }
+ .formStyle(.grouped)
+ .confirmationDialog(L("Clear local analyses?"), isPresented: $showClearLocalRiskConfirmation,
+ titleVisibility: .visible) {
+ Button(L("Clear analyses"), role: .destructive) { monitor.clearLocalRiskAnalyses() }
+ } message: {
+ Text(L("This removes only local potential-harm scores and explanations. Recorded requests, response bodies, alerts, rules, and inspection settings stay in place."))
+ }
+ }
+}
+
private struct NotificationSettingsRow: View {
@Binding var enabled: Bool
@State private var authorization: NotificationAuthorizationState = .unknown
@@ -185,7 +243,7 @@ struct MenuBarContent: View {
var body: some View {
if extensionManager.state.showsMenuBarNotice {
Button {
- nav.show(.capture)
+ nav.showSources(.collector)
openWindow(id: "main")
NSApp.activate()
} label: {
@@ -222,7 +280,7 @@ struct MenuBarContent: View {
}
if monitor.unacknowledgedAlerts > 0 {
Button(L("Review Alerts…")) {
- nav.show(.alerts)
+ nav.showAlerts()
openWindow(id: "main")
NSApp.activate()
}
diff --git a/FlowlightTests/AskFeatureTests.swift b/FlowlightTests/AskFeatureTests.swift
index 4d4c0f15..968d24dd 100644
--- a/FlowlightTests/AskFeatureTests.swift
+++ b/FlowlightTests/AskFeatureTests.swift
@@ -82,7 +82,8 @@ final class AskSettingsQueryTests: XCTestCase {
XCTAssertEqual(json["httpsInspection"] as? String, "off")
XCTAssertEqual(json["canRefuseConnections"] as? String, "yes")
XCTAssertEqual(json["watchingCameraActivity"] as? String, "yes")
- XCTAssertEqual(result.screen, .capture)
+ XCTAssertEqual(result.screen, .sources)
+ XCTAssertEqual(result.sourcesTab, .collector)
}
func testSettingsCarryNoSecrets() throws {
@@ -100,6 +101,20 @@ final class AskSettingsQueryTests: XCTestCase {
XCTAssertEqual(result.screen, .inspect, "the answer should be able to offer to take you there")
}
+ func testHowToSourcesSelectTheExactOperationalTab() throws {
+ let collector = try AskQueryRunner.run(
+ AskCall(query: .howTo, arguments: ["topic": "capture source"]), db: db, environment: environment
+ )
+ XCTAssertEqual(collector.screen, .sources)
+ XCTAssertEqual(collector.sourcesTab, .collector)
+
+ let devices = try AskQueryRunner.run(
+ AskCall(query: .howTo, arguments: ["topic": "camera and bluetooth"]), db: db, environment: environment
+ )
+ XCTAssertEqual(devices.screen, .sources)
+ XCTAssertEqual(devices.sourcesTab, .devices)
+ }
+
func testHowToWithNoMatchListsWhatThereIsInsteadOfGuessing() throws {
let result = try AskQueryRunner.run(AskCall(query: .howTo, arguments: ["topic": "zzzzqqqq"]),
db: db, environment: environment)
diff --git a/FlowlightTests/AskTests.swift b/FlowlightTests/AskTests.swift
index 1c63c574..8b4aa799 100644
--- a/FlowlightTests/AskTests.swift
+++ b/FlowlightTests/AskTests.swift
@@ -257,7 +257,8 @@ final class AskTests: XCTestCase {
XCTAssertEqual(rows.first?["device"] as? String, "Desk Camera")
XCTAssertEqual(rows.first?["started"] as? Int, 1)
XCTAssertEqual(rows.first?["stopped"] as? Int, 1)
- XCTAssertEqual(result.screen, .devices)
+ XCTAssertEqual(result.screen, .sources)
+ XCTAssertEqual(result.sourcesTab, .devices)
XCTAssertFalse(result.json.contains("private-camera-uid"), "stable hardware identifiers never leave the Mac")
XCTAssertFalse(result.json.contains("private-usb-serial"))
}
diff --git a/FlowlightTests/VisualizeNavigationTests.swift b/FlowlightTests/VisualizeNavigationTests.swift
index 00cb26f1..ff99d071 100644
--- a/FlowlightTests/VisualizeNavigationTests.swift
+++ b/FlowlightTests/VisualizeNavigationTests.swift
@@ -35,14 +35,39 @@ final class VisualizeNavigationTests: XCTestCase {
XCTAssertEqual(SidebarSection.traffic.items, [.live, .agents, .reports, .visualize, .alerts])
XCTAssertEqual(SidebarItem.sidebarOrder,
[.live, .agents, .reports, .visualize, .alerts,
- .ask, .inspect, .rules, .devices, .coverage, .capture])
+ .ask, .inspect, .rules, .sources])
XCTAssertEqual(SidebarItem.visualize.shortcut, "4")
XCTAssertEqual(SidebarItem.alerts.shortcut, "5")
XCTAssertEqual(SidebarItem.rules.shortcut, "8")
- XCTAssertEqual(SidebarItem.coverage.shortcut, "0")
- XCTAssertNil(SidebarItem.capture.shortcut,
- "the eleventh destination remains reachable without inventing a shortcut")
- XCTAssertEqual(SidebarItem.sidebarOrder.filter { $0.shortcut == nil }, [.capture])
+ XCTAssertEqual(SidebarItem.sources.shortcut, "9")
+ XCTAssertTrue(SidebarItem.sidebarOrder.allSatisfy { $0.shortcut != nil })
+ }
+
+ func testSourcesCoverageDistinguishesNoEvidenceFromZeroPercentNamed() {
+ XCTAssertEqual(SourceSetupPolicy.coverageHealth(named: 0, hasTraffic: false), .empty)
+ XCTAssertEqual(SourceSetupPolicy.coverageHealth(named: 0, hasTraffic: true), .warning)
+ XCTAssertEqual(SourceSetupPolicy.coverageHealth(named: 0.8, hasTraffic: true), .warning)
+ XCTAssertEqual(SourceSetupPolicy.coverageHealth(named: 0.81, hasTraffic: true), .good)
+ }
+
+ func testSourcesRecoveryChecklistRequiresAConfiguredCollectorAndArrivingData() {
+ XCTAssertTrue(SourceSetupPolicy.collectorConfigured(mode: .nettop, extensionState: .notInstalled,
+ extensionFellBack: false),
+ "the sampler needs no separate filter setup")
+ XCTAssertFalse(SourceSetupPolicy.collectorConfigured(mode: .networkExtension,
+ extensionState: .notInstalled,
+ extensionFellBack: false))
+ XCTAssertTrue(SourceSetupPolicy.collectorConfigured(mode: .networkExtension,
+ extensionState: .enabled,
+ extensionFellBack: false))
+ XCTAssertFalse(SourceSetupPolicy.collectorConfigured(mode: .networkExtension,
+ extensionState: .enabled,
+ extensionFellBack: true),
+ "fallback is working but is not the configured collector")
+ XCTAssertFalse(SourceSetupPolicy.setupComplete(mode: .nettop, extensionState: .unknown,
+ extensionFellBack: false, isReceiving: false))
+ XCTAssertTrue(SourceSetupPolicy.setupComplete(mode: .nettop, extensionState: .unknown,
+ extensionFellBack: false, isReceiving: true))
}
func testFocusNoticeClaimsFilteringOnlyWhereTheWholeScopeApplies() {
@@ -60,9 +85,7 @@ final class VisualizeNavigationTests: XCTestCase {
XCTAssertFalse(SidebarItem.alerts.fullyAppliesFocus(mixed))
XCTAssertFalse(SidebarItem.ask.fullyAppliesFocus(mixed))
XCTAssertFalse(SidebarItem.rules.fullyAppliesFocus(mixed))
- XCTAssertFalse(SidebarItem.devices.fullyAppliesFocus(mixed))
- XCTAssertFalse(SidebarItem.coverage.fullyAppliesFocus(mixed))
- XCTAssertFalse(SidebarItem.capture.fullyAppliesFocus(mixed))
+ XCTAssertFalse(SidebarItem.sources.fullyAppliesFocus(mixed))
}
func testConnectionsKeepsTheCompatibleVisualizeRouteAndHelpAnchor() {
@@ -154,6 +177,17 @@ final class VisualizeNavigationTests: XCTestCase {
)
}
+ func testReviewAlertsNavigationReturnsToTheAlertList() {
+ let nav = AppNavigation()
+ nav.show(.alerts)
+ nav.alertsTab = .detection
+
+ nav.showAlerts()
+
+ XCTAssertEqual(nav.selection, .alerts)
+ XCTAssertEqual(nav.alertsTab, .alerts)
+ }
+
func testExactInspectNavigationCarriesExactMemberScope() {
let nav = AppNavigation()
VisualizeActionScope.showInspect(nav, filter: TrafficFilter(
diff --git a/README.md b/README.md
index 95881298..8aa6a92b 100644
--- a/README.md
+++ b/README.md
@@ -220,8 +220,10 @@ there is still data. It says which rung it is on and how long until the next one
rewritten, blocking is switched off while the sampler stands in (the sampler can't refuse anything, and Rules
shouldn't claim otherwise), and **Try the extension again** starts over.
-### Devices: channels that aren't the network
-A Mac sends and receives over more than TCP and UDP. The **Devices** screen covers the rest, with every channel off
+### Sources: collector, coverage and devices
+**Sources** keeps collector health and recovery, hostname coverage, and opt-in device channels in one destination. Its health summary shows whether traffic is arriving, how much is named, and which device channels are active.
+
+A Mac sends and receives over more than TCP and UDP. **Sources › Devices** covers the non-network channels, with every channel off
until you turn it on because watching more of your Mac should be a decision rather than something an update did.
**Camera activity**: whether each camera is active and when it started or stopped. Flowlight reads the public
@@ -277,7 +279,7 @@ talks to a lot of places for good reasons.
Flowlight keeps recording with its window closed and costs almost nothing while idle. **Settings › General › Run in
the background** drops the Dock icon and the Cmd-Tab entry; the menu bar keeps the rates and offers **Show Dock
Icon** to undo it. Quitting stops the sampler — it does not stop the Network Extension, which runs on its own until
-you disable it in Capture.
+you disable it in Sources › Collector.
### Running in the background, quietly
The window reopens where and how you left it; a first run fills the screen. Hostname setup is offered a little after
@@ -314,7 +316,7 @@ appears in Live and History like any other app's traffic, including a collector
No account, no cloud, no telemetry. Everything stays in a local SQLite database. Packet capture reads only DNS
answers and TLS ClientHellos (a kernel filter drops everything else), and **packet contents are never stored**.
Naming who owns an IP with no known hostname is **on by default**: it sends those public IPs (never private ones) to
-Team Cymru's DNS service, and you can turn it off in Capture. Release and official rule-pack checks make standard HTTPS
+Team Cymru's DNS service, and you can turn it off in Sources › Collector. Release and official rule-pack checks make standard HTTPS
requests with no traffic or pack settings; each has its own off switch in Settings or Rules › Packs. To attribute tools
and MCP servers, Flowlight reads process command lines and your agents' MCP config files
on your Mac; none of it leaves your Mac. HTTPS inspection is off unless you turn it on, and what it records stays in the
@@ -354,7 +356,7 @@ same local database.
asks to quit and install it (Flowlight › Check for Updates…). Updating by hand? Quit Flowlight before dragging the
new version in.
3. On first launch, **Name Your Traffic** offers the one-time setup that lets Flowlight read hostnames (it asks
- for your password once). Network-owner lookups are on by default and can be turned off there or in Capture.
+ for your password once). Network-owner lookups are on by default and can be turned off there or in Sources › Collector.
> **Try it without your own data:** `open /Applications/Flowlight.app --args -FLDemo YES` launches with 90 days
> of synthetic traffic, including an inspected Claude Code session. That's what the screenshots show.
@@ -438,7 +440,7 @@ The [threat model](https://flowlight.xinbetween.com/threat-model/) says what is
to confirm the filter. Flowlight works without it on the nettop sampler.
- **Only one content filter runs at a time on macOS.** On a Mac where security software already holds that slot —
Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar — Flowlight's filter installs and connects but is never handed
- any traffic. Capture lists the filters it finds and offers the sampler instead, which needs no filter.
+ any traffic. Sources › Collector lists the filters it finds and offers the sampler instead, which needs no filter.
## Roadmap
@@ -551,7 +553,7 @@ Flowlight/
Storage/ SQLite store, rollups, queries
Analysis/ anomaly engine, AI agent catalog + rules
Inspection/ opt-in HTTPS inspection: local CA, proxy, HTTP parser, tool-call reader
- UI/ Live · AI Agents · History · Alerts · Inspect · Connections · Capture
+ UI/ Live · AI Agents · History · Alerts · Inspect · Connections · Sources
FlowlightTests/ 105 unit tests: parsers, BPF filter, rollups, charts, agents, MCP, allowlists, inspection, updates
docs/ website (GitHub Pages) and developer guide
```
diff --git a/docs/404.html b/docs/404.html
index 8c4e1fed..0d6bebcd 100644
--- a/docs/404.html
+++ b/docs/404.html
@@ -86,7 +86,7 @@
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
index e3878414..7d39f944 100644
--- a/docs/DEVELOPMENT.md
+++ b/docs/DEVELOPMENT.md
@@ -27,7 +27,7 @@ Flowlight/ SwiftUI host app
Analysis/ EWMA/z-score baselines, rule engine, AI agent catalog + rules, UI-activity tracker
Inspection/ HTTPS inspection: local CA, decrypting proxy, HTTP parser, recorder, mock rules
Export/ opt-in export to a collector the user chooses: OTLP/NDJSON payloads, queue, Keychain
- UI/ Live, AI Agents, History (charts + three breakdown groupings + CSV), Alerts, Connections, Capture
+ UI/ Live, AI Agents, History (charts + three breakdown groupings + CSV), Alerts, Connections, Sources
Channels/ Opt-in Bluetooth, USB/storage and CoreMediaIO camera-activity monitors
Shared/Classification/ProtocolCatalog.swift 108 protocols in 13 families, used by both capture engines
FlowlightTests/ Parser, classifier, BPF filter, rollup, chart, agent and anomaly tests
@@ -43,16 +43,16 @@ FlowlightTests/ Parser, classifier, BPF filter, rollup, chart, agent
| Protocols | First bytes + ports | Ports only |
| Short-lived flows | Every flow | Flows shorter than ~1 s are missed |
-Choose the source in **Capture**. Both produce the same per-second batches, so storage, reports and
+Choose the source in **Sources › Collector**. Both produce the same per-second batches, so storage, reports and
anomaly detection work the same way with either one.
### Hostnames in nettop mode
nettop only reports IP addresses, so Flowlight fills in names from several sources, in order:
-1. **Packet capture** (Capture › Hostnames › *Enable Packet Capture…*). A one-time admin prompt installs
+1. **Packet capture** (Sources › Collector › Hostnames › *Enable Packet Capture…*). A one-time admin prompt installs
`/Library/LaunchDaemons/com.flowlight.bpf-access.plist`, which gives the `access_bpf` group read access to
- `/dev/bpf*` at boot. This is the same approach as Wireshark's ChmodBPF. Capture follows the primary interface,
+ `/dev/bpf*` at boot. This is the same approach as Wireshark's ChmodBPF. The collector follows the primary interface,
so traffic confined to another interface or tunnel may lack names. A kernel BPF filter passes only DNS
responses and TLS ClientHellos, so the cost doesn't grow with traffic. Packet contents are never stored.
*Remove Packet Capture Access…* undoes the setup. On first launch, Flowlight offers the setup once
@@ -60,7 +60,7 @@ nettop only reports IP addresses, so Flowlight fills in names from several sourc
granting BPF access. Launch with `-FLForceCaptureOnboarding YES` to show the offer again.
2. **Reverse DNS**, as a last resort.
3. **Network owner**: the IP's autonomous system (e.g. "Cloudflare, Inc. · AS13335"), from Team Cymru's DNS
- interface. This lookup is on by default and sends only public IPs; turn it off during setup or in Capture.
+ interface. This lookup is on by default and sends only public IPs; turn it off during setup or in Sources › Collector.
Public IPs are sent to that service, while local and reserved addresses stay on the Mac.
History groups any traffic still without a hostname under its network owner.
@@ -100,7 +100,7 @@ without a test host, so it is the quicker way to check that particular thing any
(https://developer.apple.com/contact/request/network-extension). A free Personal Team can't sign it.
2. For development, before the entitlement is granted: disable SIP on a test Mac and run
`systemextensionsctl developer on`.
-3. Copy the app to `/Applications`, open **Capture**, and click **Install & enable filter**.
+3. Copy the app to `/Applications`, open **Sources › Collector**, and click **Install & enable filter**.
Then approve it in System Settings › General › Login Items & Extensions, and allow the content filter.
4. Switch the source to **Network Extension**.
5. Check the extension's logs:
@@ -110,7 +110,7 @@ The App Group and Mach service names come from `$(TeamIdentifierPrefix)com.flowl
## Device activity
-The **Devices** screen is opt-in per channel. Bluetooth and USB/storage report attachment, while camera monitoring
+**Sources › Devices** is opt-in per channel. Bluetooth and USB/storage report attachment, while camera monitoring
uses public CoreMediaIO device metadata only: `kCMIOHardwarePropertyDevices` for enumeration and
`kCMIODevicePropertyDeviceIsRunningSomewhere` for active state. A property listener reports transitions without
opening an `AVCaptureSession`, requesting TCC capture access, or reading frames. The public signal is per camera and
diff --git a/docs/about/index.html b/docs/about/index.html
index 07f34f9b..5ede6eb9 100644
--- a/docs/about/index.html
+++ b/docs/about/index.html
@@ -153,7 +153,7 @@
Ein Filter im Kernel verwirft jedes andere Paket, bevor Flowlight es sieht, und Paketinhalte werden nie gespeichert.
macOS lässt nur Administratoren Pakete lesen, deshalb fragt das Fenster Deinem Datenverkehr Namen geben einmal nach deinem Passwort. Es installiert
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, das der Gruppe access_bpf bei jedem Start Lesezugriff auf
- /dev/bpf* gibt – derselbe Weg, den Wireshark geht. Jederzeit entfernbar über Erfassung › Paketmitschnitt-Zugriff entfernen.
+ /dev/bpf* gibt – derselbe Weg, den Wireshark geht. Jederzeit entfernbar über Quellen › Collector › Paketmitschnitt-Zugriff entfernen.
Netzinhaber bestimmen beschriftet Datenverkehr ohne Hostnamen damit, wer die Adresse betreibt
(Cloudflare, Inc. · AS13335). Es ist standardmäßig ein und sendet diese öffentlichen IP-Adressen (nie private) an den
- DNS-Dienst von Team Cymru. Abschalten kannst du es unter Erfassung.
+ DNS-Dienst von Team Cymru. Abschalten kannst du es unter Quellen › Collector.
Sprache
Flowlight ist übersetzt in English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español und
@@ -168,15 +168,13 @@
Die Ansichten
Verlauf
⌘3
Wohin der Datenverkehr ging, von der Sekunde bis zum Jahr. Gruppiert nach App, Ziel oder IP; umschaltbar auf Diagramme oder Genauer hinsehen; CSV-Export.
Eine stabile Karte der Apps und ihrer genauen Ziele mit gewichteten Pfaden, bewegten Richtungsmarkern, Verbindungszahlen und einer gleichwertigen Liste.
Fragen zu deinem eigenen Datenverkehr in normaler Sprache, beantwortet aus der aufgezeichneten Historie von einem lokalen oder einem gehosteten Modell.
Optional: entschlüsselte Anfragen der Agenten, die du über Flowlight leitest, und die Tool-Aufrufe dahinter. Die Suche reicht in Anfrage- und Antwort-Bodys hinein.
Optional: entschlüsselte Anfragen der Agenten, die du über Flowlight leitest, und die Tool-Aufrufe dahinter. Die Suche reicht in Anfrage- und Antwort-Bodys hinein.
Collector-Zustand, Gerätekanäle und Benennungsabdeckung in drei Tabs.
-
Die Kurzbefehle folgen der Reihenfolge der Seitenleiste: ⌘0 ist das zehnte Element, und das elfte bleibt ohne einen erfundenen Kurzbefehl erreichbar.
-
Die Kurzbefehle folgen der sichtbaren Reihenfolge der Seitenleiste. Developer-ID-Versionen enthalten Inspizieren auf ⌘7; App-Store-Versionen lassen es weg, daher rücken Regeln und Quellen auf ⌘7 und ⌘8.
+
Live, der Bildschirm, mit dem Flowlight startet.
Bewege in Verlauf den Zeiger über einen Balken, um eine mitlaufende, scrollbare Karte mit den beteiligten Apps zu öffnen; die Balken zoomen beim Klicken nicht. Doppelklicke eine Zeile, um den Verlauf darauf einzugrenzen.
@@ -479,7 +477,7 @@
Verbindungen verweigern
verweigert: Die Verbindung wird verworfen, und eine Warnung hält fest, was verweigert wurde – mit … ab jetzt erlauben, um es
mit einem Klick in die Liste aufzunehmen. Der nächste Versuch des Agenten geht durch.
Es braucht die Netzwerkerweiterung. Eine Verbindung zu verweigern heißt, in ihrem Weg zu sitzen, und das kann der nettop-Sampler
- nicht – Erfassung sagt das, statt einen Schalter anzubieten, der nichts tut.
+ nicht – Quellen › Collector sagt das, statt einen Schalter anzubieten, der nichts tut.
Manches wird nie verweigert, was auch in einer Liste steht: dein lokales Netzwerk, DNS, Apples eigene Dienste und Flowlights eigener
Datenverkehr. Ein blockierter Mac ist schlimmer als ein blockierter Agent, im Zweifel wird die Verbindung also erlaubt und aufgezeichnet.
Die Durchsetzung endet außerdem wenige Sekunden nachdem Flowlight nicht mehr läuft – eine Verweigerung, die niemand sehen kann, ist schlimmer als keine, und der Weg,
@@ -511,8 +509,8 @@
Schutzregeln für Agenten: ein Tool, einen Server oder eine
Das ist keine Sandbox. Ein verweigertes Tool wird nicht mehr angeboten und nicht mehr beantwortet. Ein Agent, der noch eine
Shell hat, kann von Hand tun, was das Tool getan hätte. Flowlight zeichnet das auf; es tut nicht so, als würde es das verhindern.
-
Erfassung: Engines und Quellen
-
Flowlight zeichnet Datenverkehr auf eine von zwei Weisen auf, wählbar unter Erfassung. Sie unterscheiden sich darin, was sie verpassen können, und das lohnt
+
Quellen: Collector und Engines
+
Flowlight zeichnet Datenverkehr auf eine von zwei Weisen auf, wählbar unter Quellen › Collector. Sie unterscheiden sich darin, was sie verpassen können, und das lohnt
sich zu verstehen, bevor du dich auf eine verlässt.
nettop-Sampler (Standard)
Netzwerkerweiterung
@@ -538,7 +536,7 @@
Erfassung: Engines und Quellen
ohne deine gewählte Quelle zu verändern. Erweiterung erneut versuchen unter Netzwerkerweiterung fängt von vorn an.
Auf manchen Macs kann sie gar nicht laufen. macOS erlaubt nur einen Inhaltsfilter zur Zeit, und normalerweise hält Sicherheitssoftware
aus dem Unternehmen ihn – Palo Alto Networks GlobalProtect, CrowdStrike Falcon und dergleichen. Flowlights Filter installiert sich auf diesen
- Rechnern und verbindet sich auch, bekommt dann aber nie eine Verbindung übergeben. Erfassung listet jeden Filter auf, den es findet, und bietet an, zurück auf den Sampler zu schalten, der
+ Rechnern und verbindet sich auch, bekommt dann aber nie eine Verbindung übergeben. Quellen › Collector listet jeden Filter auf, den es findet, und bietet an, zurück auf den Sampler zu schalten, der
keinen Filter braucht und neben ihnen funktioniert.
Wie es gebaut ist, steht im Entwicklerhandbuch.
@@ -607,7 +605,7 @@
Im Hintergrund laufen
hast. Die Hostnamen-Einrichtung wird etwas nach dem Start angeboten und nur, solange ein Fenster offen ist, statt einen ersten Start mit einer
Passwortfrage zu begrüßen; das Angebot kommt beim nächsten Start wieder, bis du es annimmst oder wegklickst.
Flowlight zu beenden stoppt den Sampler. Es stoppt nicht die Netzwerkerweiterung: Eine Systemerweiterung läuft für sich, der Filter
- prüft Verbindungen also weiter, bis du ihn unter Erfassung deaktivierst oder deinstallierst.
+ prüft Verbindungen also weiter, bis du ihn unter Quellen › Collector deaktivierst oder deinstallierst.
Export an OpenTelemetry oder ein SIEM
Aus, bis du es einrichtest – und es gibt keinen Flowlight-Dienst, an den gesendet würde. Du nennst den Endpunkt – deinen eigenen
@@ -647,7 +645,7 @@
Export an OpenTelemetry oder ein SIEM
Deine Daten
Alles liegt in ~/Library/Application Support/Flowlight/traffic.sqlite. Sekundenzeilen werden 6 Stunden aufbewahrt
(einstellbar), Minutenzeilen 14 Tage, Stundenzeilen 400 Tage, Tageszeilen dauerhaft und Warnungen 90 Tage.
- Erfassung › Alle Daten löschen löscht sie.
Erscheint eine neue Version, sagt Flowlight es mit einer Benachrichtigung und einem Zeichen in der Seitenleiste, statt dich zu unterbrechen;
@@ -666,7 +664,7 @@
Demomodus
Deinstallieren
-
Wähle unter Erfassung den Punkt Paketmitschnitt-Zugriff entfernen (fragt nach deinem Passwort), falls du ihn eingerichtet hast,
+
Wähle unter Quellen › Collector den Punkt Paketmitschnitt-Zugriff entfernen (fragt nach deinem Passwort), falls du ihn eingerichtet hast,
deinstalliere den Inhaltsfilter, falls du ihn installiert hast, und schalte die HTTPS-Inspektion unter Inspizieren aus, damit ihr Zertifikat
deinen Schlüsselbund verlässt. Nur Flowlight selbst kann diese drei zurücknehmen.
Beende Flowlight und lege es aus dem Programme-Ordner in den Papierkorb – oder, wenn du es mit Homebrew installiert hast,
@@ -685,19 +683,19 @@
Fragen & Antworten
Byte-Zähler von macOS einmal pro Sekunde und zeichnet die Veränderung auf – eine lange Übertragung wird also exakt gezählt, aber eine Verbindung, die zwischen
zwei Messungen öffnet und schließt, erscheint überhaupt nicht. Die Netzwerkerweiterung wird von macOS bei jedem Verbindungsaufbau aufgerufen, sodass
selbst eine Anfrage von fünf Millisekunden aufgezeichnet wird. Wenn du einen KI-Agenten beobachtest, der viele kurze Anfragen abfeuert, installiere die
- Erweiterung unter Erfassung. Der vollständige Vergleich steht oben.
+ Erweiterung unter Quellen › Collector. Der vollständige Vergleich steht oben.
Ich habe die Netzwerkerweiterung eingeschaltet und es erscheint nichts. Der Sampler läuft gut.
Fast immer, weil ein anderer Inhaltsfilter den Platz schon hat. macOS führt einen Inhaltsfilter zur Zeit aus, und
Sicherheitssoftware aus dem Unternehmen beansprucht ihn meist – Palo Alto Networks GlobalProtect, CrowdStrike Falcon und Ähnliches. Flowlights
- Filter installiert, aktiviert und verbindet sich trotzdem, Erfassung sagt also Mit Filtererweiterung verbunden, aber macOS übergibt ihm nie eine
- einzige Verbindung und die Bildschirme bleiben leer. Erfassung listet die Filter auf, die es findet, und bietet an, zurück auf den
+ Filter installiert, aktiviert und verbindet sich trotzdem, Quellen › Collector sagt also Mit Filtererweiterung verbunden, aber macOS übergibt ihm nie eine
+ einzige Verbindung und die Bildschirme bleiben leer. Quellen › Collector listet die Filter auf, die es findet, und bietet an, zurück auf den
Sampler zu schalten, der keinen Filter nutzt und neben ihnen funktioniert. Du verlierst nur die ganz kurzen Verbindungen
(der Vergleich); alles andere wird genauso aufgezeichnet.
Die Erweiterung hat nach einem Flowlight-Update aufgehört zu arbeiten.
Versionen vor 0.2.5 hatten das: macOS führt weiter den Build der Erweiterung aus, der zuletzt aktiviert wurde, nach einem Update war die
Erweiterung also die alte Version, und macOS verweigert die Verbindung zwischen einem nicht passenden Paar. Ab 0.2.5 prüft Flowlight beim Start
- und aktiviert den Filter selbst neu. Drücke bei einer älteren Version einmal Filter installieren & aktivieren unter Erfassung.
-
Mit der Erfassung ist etwas anderes nicht in Ordnung und ich weiß nicht, was.
+ und aktiviert den Filter selbst neu. Drücke bei einer älteren Version einmal Filter installieren & aktivieren unter Quellen › Collector.
+
Mit Quellen › Collector stimmt etwas anderes nicht und ich weiß nicht, was.
Führe das aus und lies, was es ausgibt – es meldet nur Zustände und Zähler, nie etwas, das Flowlight über deinen Datenverkehr aufgezeichnet hat:
Es zeigt, welche Erweiterungen installiert sind, ob macOS Flowlights Filter wirklich gestartet hat und wie kürzlich überhaupt etwas aufgezeichnet wurde.
@@ -763,7 +761,7 @@
Sieh, was deine Apps im Netz tun. brew install --cask xinbetween/tap/flowlight
-
v0.17.2macOS 15+UniversalGPL-3.0Keine Telemetrie
+
v0.17.3macOS 15+UniversalGPL-3.0Keine Telemetrie
@@ -127,7 +127,7 @@
Sieh, was deine Apps im Netz tun.
-
Sieh die tatsächliche KI-Route: Agenten, zugeordnete Werkzeuge, konfigurierte Gateways, Flowlights beobachtete Proxy-Stufe und exakte Ziele. Die Bandbreite zeigt empfangene plus gesendete Daten im gewählten Zeitraum. Mit Demodaten.
@@ -135,7 +135,7 @@
Sieh, was deine Apps im Netz tun.
-
Die Ansicht KI-Agenten: der Modellanbieter jedes Agenten – und alles andere, mit dem er gesprochen hat. Mit Demodaten gezeigt.
@@ -179,13 +179,13 @@
Verlauf
Wo ist alles hingegangen? Sekunde bis Jahr, gruppiert nach Ap
Warnungen
Was sah falsch aus? Nachvollziehbare Warnungen pro App, mit Ziel und Schwellenwert.
⌘5
-
Regeln
Was habe ich verweigert – und passiert es? Jede Regel, was sie blockiert hat, und ein Verlauf jeder Entscheidung.
⌘8
+
Regeln
Was habe ich verweigert – und passiert es? Jede Regel, was sie blockiert hat, und ein Verlauf jeder Entscheidung.
⌘8 · Developer ID / ⌘7 · App Store
Fragen
Fragen in normaler Sprache, beantwortet aus dem Verlauf – mit jeder ausgeführten Abfrage darunter.
⌘6
-
-
Geräte
Bluetooth, USB und Kameras: was gekoppelt, angeschlossen oder aktiv ist und wann sich das geändert hat. Aus, bis du es einschaltest.
⌘9
+
+
Quellen
Kommen Daten an, wie viel ist benannt und welche Gerätekanäle sind aktiv? Collector, Geräte und Abdeckung an einem Ort.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspizieren
Optional. Was hat der Agent wirklich gesendet, und welcher Tool-Aufruf hat es ausgelöst? Entschlüsselte Anfragen, Tool-Aufrufe, Ergebnisse.
⌘7
+
Inspizieren
Optional. Was hat der Agent wirklich gesendet, und welcher Tool-Aufruf hat es ausgelöst? Entschlüsselte Anfragen, Tool-Aufrufe, Ergebnisse.
⌘7 · Developer ID
Verbindungen
Was kommuniziert? Eine zoombare Sankey-Karte für App-Verkehr und nachgewiesene KI-Agentenpfade, mit exakter Listenansicht.
⌘4
@@ -405,16 +405,16 @@
Unterstützte Tool-Aufrufe mit Netzwerkanfragen verknüpfen
Mac. Starte einen Agenten aus einem inspizierten Terminal, und der unterstützte HTTP-Verkehr des Agenten und seiner Tools wird entschlüsselt – mit den
Tool-Aufrufen, die das Modell angefordert hat, und den Ergebnissen, die zurückgingen.
-
Wo sind meine Notizen gelandet? Der curl-Upload zu paste.example, zurückverfolgt bis zum Bash-Befehl, den das Modell angefordert hat, mit dem
gesendeten Body.
-
Jedes Tool, das ein Agent dem Modell anbietet. Agenten deklarieren ihre Tools bei jedem Zug, also listet Flowlight alle auf – mit denen,
die das Modell tatsächlich genutzt hat, und denen, die es nie angefasst hat.
-
Auch die, die du auf der Leitung nicht siehst. Bittet ein Agent den Anbieter, sich mit einem MCP-Server zu verbinden, erreicht dieser Datenverkehr
deinen Mac nie. Seine Anfrage schon – also tauchen der Server, seine URL, seine Freigabeeinstellung und seine Tools trotzdem auf.
@@ -460,7 +460,7 @@
Ein Wächter, den du nicht bewachen musst
-
Ein Agent, jeder Tool-Aufruf. Der Datenverkehr der git-, curl- und MCP-Server, die Claude Code gestartet hat, zählt als Datenverkehr von Claude Code.
Mit eingeschalteter HTTPS-Inspektion zeigt der Tab Tool-Aufrufe, was das Modell angefordert hat, was zurückkam und welche Anfragen jedes Tool gestellt hat:
@@ -470,10 +470,10 @@
Ein Wächter, den du nicht bewachen musst
-
Verlauf. Zoom von der Sekunde bis zum Jahr, drei Gruppierungen, Diagramme, die auch bei hunderten Apps lesbar bleiben.
-
Warnungen. Jede nennt die App, das Ziel und den Wert, der sie ausgelöst hat.
@@ -523,7 +523,7 @@
In unter einer Minute einsatzbereit
Basislinien für Anomalien und Regeln, die für KI-Agenten gemacht sind. Beides funktioniert gut nebeneinander.
Warum fragt es nach meinem Passwort?
macOS lässt nur Administratoren Netzwerkpakete lesen. Die einmalige Einrichtung gibt deinem Benutzerkonto Lesezugriff – genauso, wie
- Wireshark es tut. Du kannst ihn jederzeit im Bereich Erfassung wieder entfernen.
+ Wireshark es tut. Du kannst ihn jederzeit unter Quellen › Collector wieder entfernen.
Erkennt es, welcher MCP-Server oder welches Tool eine Anfrage gestellt hat?
Ja, auf Prozessebene. Flowlight verfolgt jeden Prozess zurück zu dem Agenten, der ihn gestartet hat – das curl eines Shell-Tools
oder die Verbindungen eines MCP-Servers werden also diesem Agenten zugeordnet, und MCP-Server werden aus den Konfigurationen von Claude Code, Claude
@@ -589,7 +589,7 @@
verhindert das, und kein Überwachungswerkzeug auf macOS kann es verhindern und dabei ein Werkzeug bleiben, das du auch selbst abschalten kannst.
Die ehrliche Aussage ist schmaler und trotzdem nützlich: Software, die sich schlecht verhält, aber einer Überwachung nicht aktiv ausweicht,
wird gesehen. Software, die ihr aktiv ausweicht, vielleicht nicht – und sie lässt zumindest eine Lücke zurück: eine Erweiterung, die stehen
- geblieben ist, ein Zeitraum ohne Daten. Dafür ist der Bildschirm Abdeckung da.
Systemdienste, die von Inhaltsfiltern ausgenommen sind. macOS zeigt einem Inhaltsfilter nicht alles; ein Teil seines
eigenen Datenverkehrs erreicht unseren nie.
Ein anderer Inhaltsfilter, der den Platz hält. macOS führt einen zur Zeit aus. Hat ihn ein VPN oder ein
- Sicherheitsagent, installiert sich Flowlights Filter, verbindet sich und wird nie gebeten, etwas zu filtern – Erfassung sagt das, statt einen
+ Sicherheitsagent, installiert sich Flowlights Filter, verbindet sich und wird nie gebeten, etwas zu filtern – Quellen › Collector sagt das, statt einen
leeren Bildschirm zu zeigen.
Kurze Verbindungen, beim Sampler. Ohne die Erweiterung liest Flowlight Zähler einmal pro Sekunde: Eine Verbindung, die
zwischen zwei Messungen öffnet und schließt, wird nie aufgezeichnet.
@@ -151,7 +151,7 @@
Was der Inspektion entgeht
Die HTTPS-Inspektion liest nur, was über Flowlights lokalen Proxy geleitet wird, und darüber entscheidet ein Programm beim Start. Eine App,
die Proxy-Einstellungen ignoriert, eine, die vor dem Einschalten der Inspektion gestartet wurde, oder eine, die ihre Zertifikate anpinnt, geht
unberührt durch – absichtlich, denn eine angepinnte Verbindung zu brechen würde die App brechen. QUIC wird dem Proxy ebenfalls nicht angeboten.
-
Ein leerer Bildschirm Inspizieren heißt also „hier wurde nichts durchgeleitet“ und nicht „es ist nichts passiert“. Abdeckung sagt pro App,
+
Ein leerer Bildschirm Inspizieren heißt also „hier wurde nichts durchgeleitet“ und nicht „es ist nichts passiert“. Quellen › Abdeckung sagt pro App,
welches von beidem gilt.
A filter in the kernel drops every other packet before Flowlight sees it, and packet contents are never stored.
macOS only lets administrators read packets, so the Name Your Traffic window asks for your password once. It installs
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, which gives the access_bpf group read access to
- /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Capture › Remove Packet Capture Access.
+ /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Sources › Collector › Remove Packet Capture Access.
Identify network owners labels traffic with no hostname by who operates the address
(Cloudflare, Inc. · AS13335). It's on by default and sends those public IP addresses (never private ones) to Team Cymru's
- DNS service. Turn it off in Capture.
+ DNS service. Turn it off in Sources › Collector.
Language
Flowlight is translated into English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español and
@@ -169,14 +169,12 @@
Optional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
Optional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
Collector health and recovery, hostname coverage, and opt-in camera, Bluetooth, USB and storage activity in three tabs.
-
The shortcuts follow the sidebar's visible order: ⌘0 is the tenth item, and an eleventh remains available without an invented key.
-
The shortcuts follow the visible sidebar order. Developer ID builds include Inspect at ⌘7; App Store builds omit Inspect, so Rules and Sources move to ⌘7 and ⌘8.
+
Live, the screen Flowlight opens on.
In History, choose 15 min, 1h, 6h, 1d, 1w, 1 mo, 6 mo, 1y, or All. Hover-only bars open a cursor-following, scrollable card with the bucket totals and contributing apps; they never change the selected range. The navigator below the chart starts with Nearby context and can switch to All history: drag the brush to pan the selected window, or drag either edge to resize it. Double-click any breakdown row to narrow History to it.
@@ -197,7 +195,7 @@
AI agent rules
Unnamed host
connects to a raw IP with no hostname on an unusual port
On
Active while you're away
moves 1 MB or more in a minute after you stop using the keyboard and mouse
15 minutes
-
Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Settings › Detection.
+
Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Alerts › Detection.
Tools & MCP servers
Agents do much of their work through other processes: a shell tool runs curl, git or npm, and MCP
@@ -281,7 +279,7 @@
Other alerts
Apple's own apps are left out by default. macOS contacts Apple constantly — Software Update, iCloud,
push, time, Maps tiles — on hosts and ports that are new the first time they appear, and listing all of it buries the one
- line worth reading. Turn it off in Settings › Detection › Rules if you want them. Either way the traffic is still
+ line worth reading. Turn it off in Alerts › Detection › Rules if you want them. Either way the traffic is still
recorded, still appears in Live, History and Ask, and is still subject to every rule, guardrail and allowlist: the setting
decides what is listed, never what is allowed.
@@ -341,7 +339,7 @@
HTTPS inspection (optional)
Flowlight certificate; Flowlight notices and passes them through encrypted. By default, header values are kept only when the header is one you
allow, and everything else is replaced by its length before anything is stored — recorded requests are kept for as long as you set, and Remove Certificate & Recorded Data deletes the certificate, its trust
setting and everything recorded. Inspection is HTTP/1.1 only (Flowlight asks both sides for it) and not available in demo mode.
-
Local risk analysis is separate and off by default. In History or Settings › Detection, you can ask
+
Local risk analysis is separate and off by default. In History or Alerts › Detection, you can ask
Apple’s on-device model to review only meaningful, already-recorded decrypted HTTP candidates after capture. It gets a
bounded redacted description — never request or response bodies, header values, cookies, credentials or tool arguments —
and nothing leaves the Mac. The result is a potential-harm hint, not proof of intent: Flowlight never blocks, changes,
@@ -520,7 +518,7 @@
Refusing connections
refuse them: the connection is dropped and an alert records what was refused, with Allow … from Now On to add it
to the list in one click. The agent's next attempt goes through.
It needs the Network Extension. Refusing a connection means sitting in its path, which the nettop sampler
- cannot do — Capture will say so rather than offer a switch that does nothing.
+ cannot do — Sources › Collector will say so rather than offer a switch that does nothing.
Some things are never refused, whatever a list says: your local network, DNS, essential Apple system services, and Flowlight's own
traffic. A blocked Mac is a worse outcome than a blocked agent, so where there is doubt the connection is allowed and recorded.
Enforcement also lapses a few seconds after Flowlight stops running — a refusal nobody can see is worse than none, and the way
@@ -553,8 +551,9 @@
Agent guardrails: block a tool, a server or a resource
This is not a sandbox. A refused tool stops being offered and stops being answered. An agent that still has a
shell can do by hand what the tool would have done. Flowlight will record that; it does not pretend to prevent it.
-
Capture: engines and sources
-
Flowlight records traffic one of two ways, chosen in Capture. They differ in what they can miss, which is worth
+
Sources: collector, coverage and devices
+
Sources keeps operational setup in one place. Its health summary shows whether traffic is arriving, how much is named, and which optional device channels are active; any unfinished collector step links directly to Sources › Collector.
+
Flowlight records traffic one of two ways, chosen under Sources › Collector. They differ in what they can miss, which is worth
understanding before you rely on either.
nettop sampler (default)
Network Extension
@@ -580,12 +579,12 @@
Capture: engines and sources
and leaving your chosen source alone. Try the extension again under Network Extension starts over.
It also can't run at all on some Macs. macOS allows one content filter at a time, and corporate security software
normally holds it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and the like. Flowlight's filter will install and connect on those
- machines and then never be handed a connection. Capture lists any it finds and offers to switch you back to the sampler, which
+ machines and then never be handed a connection. Sources › Collector lists any it finds and offers to switch you back to the sampler, which
needs no filter and works alongside them.
See the developer guide for how it's built.
Coverage: what Flowlight can't account for
-
Every other screen answers what happened. Coverage answers what you would not have been told, which is what
+
Sources › Coverage answers what you would not have been told, which is what
decides how much the other screens are worth. It asks three questions per app, because they fail independently.
Was it seen? The Network Extension sees each flow as it opens. The nettop sampler reads counters once a
second, so a connection that opens and closes between two readings — a DNS lookup, a fast API call, a script that runs curl
@@ -603,7 +602,7 @@
Coverage: what Flowlight can't account for
fact.
Devices: camera activity, Bluetooth, USB and external storage
-
A Mac sends and receives over more than TCP and UDP. The Devices screen covers the rest, with every channel
+
A Mac sends and receives over more than TCP and UDP. Sources › Devices covers the rest, with every channel
off until you turn it on because watching more of your Mac should be your decision rather than something an update did.
Camera activity shows whether each camera is active and records confirmed start and stop transitions.
Flowlight reads the public CoreMediaIO device state; it never opens a capture session, requests camera access, or reads a
@@ -653,7 +652,7 @@
Running in the background
have. Hostname setup is offered a little after launch and only while a window is open, rather than greeting a first run with a
request for your password; the offer returns next launch until you take or dismiss it.
Quitting Flowlight stops the sampler. It does not stop the Network Extension: a system extension runs on its own, so the filter
- carries on inspecting connections until you disable or uninstall it in Capture.
+ carries on inspecting connections until you disable or uninstall it in Sources › Collector.
Export to OpenTelemetry or a SIEM
Off until you configure it, and there is no Flowlight service to send to. You name the endpoint — your own
@@ -692,7 +691,7 @@
Export to OpenTelemetry or a SIEM
Your data
Everything lives in ~/Library/Application Support/Flowlight/traffic.sqlite. Per-second rows are kept 6 hours
(adjustable), minute rows 14 days, hourly rows 400 days, daily rows indefinitely, and alerts 90 days.
- Capture › Clear all data deletes it.
+ Settings › Data & Privacy › Clear All Data deletes it.
Updates
After you quit Flowlight cleanly and launch it again, a newly found version opens the update window. At other times,
@@ -712,7 +711,7 @@
Demo mode
Uninstall
-
In Capture, choose Remove Packet Capture Access (asks for your password) if you enabled it,
+
In Sources › Collector, choose Remove Packet Capture Access (asks for your password) if you enabled it,
uninstall the content filter if you installed it, and turn HTTPS inspection off in Inspect so its certificate
leaves your keychain. Only Flowlight itself can withdraw those three.
Quit Flowlight and move it from Applications to the Trash — or, if you installed it with Homebrew,
@@ -731,18 +730,18 @@
Questions & answers
byte counters once a second and records the change, so a long transfer is counted exactly — but a connection that opens and
closes between two readings never appears at all. The Network Extension is called by macOS as each connection is made, so
even a five-millisecond request is recorded. If you're watching an AI agent that fires many short requests, install the
- extension from Capture. The full comparison is above.
+ extension from Sources › Collector. The full comparison is above.
I turned on the Network Extension and nothing appears. The sampler works fine.
Almost always because another content filter already has the slot. macOS runs one content filter at a time, and
corporate security software usually claims it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar. Flowlight's
- filter still installs, activates and connects, so Capture says Connected to filter extension, but macOS never hands it a
- single connection and the screens stay empty. Capture lists the filters it finds and offers to switch you back to
+ filter still installs, activates and connects, so Sources › Collector says Connected to filter extension, but macOS never hands it a
+ single connection and the screens stay empty. Sources › Collector lists the filters it finds and offers to switch you back to
the sampler, which doesn't use a filter and works alongside them. You lose only the very short connections
(the comparison); everything else is recorded the same way.
The extension stopped working after Flowlight updated.
Versions before 0.2.5 had this: macOS keeps running whichever build of the extension was last activated, so after an update the
extension was the old version and macOS refuses the connection between a mismatched pair. From 0.2.5 Flowlight checks at launch
- and re-activates the filter itself. On an older version, press Install & enable filter in Capture once.
+ and re-activates the filter itself. On an older version, press Install & enable filter in Sources › Collector once.
Something else is wrong with capture and I don't know what.
Run this and read what it prints — it reports state and counts only, never anything Flowlight recorded about your traffic:
Un filtro en el núcleo descarta todos los demás paquetes antes de que Flowlight los vea, y el contenido de los paquetes no se guarda nunca.
macOS solo permite leer paquetes a los administradores, así que la ventana Poner nombre a tu tráfico pide tu contraseña una vez. Instala
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, que da al grupo access_bpf acceso de lectura a
- /dev/bpf* en cada arranque, el mismo método que usa Wireshark. Puedes retirarlo cuando quieras desde Captura › Retirar el acceso a la captura de paquetes.
+ /dev/bpf* en cada arranque, el mismo método que usa Wireshark. Puedes retirarlo cuando quieras desde Fuentes › Colector › Retirar el acceso a la captura de paquetes.
Identificar a los propietarios de la red etiqueta el tráfico sin nombre de host con quién opera la dirección
(Cloudflare, Inc. · AS13335). Está activado por defecto y envía esas direcciones IP públicas (nunca las privadas) al servicio
- DNS de Team Cymru. Desactívalo en Captura.
+ DNS de Team Cymru. Desactívalo en Fuentes › Colector.
Idioma
Flowlight está traducido a English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español y
@@ -168,15 +168,13 @@
Las vistas
Historial
⌘3
Adónde fue el tráfico, del segundo al año. Agrupa por App, Destino o IP; cambia a Gráficos o a Merece un vistazo; exporta a CSV.
Un mapa estable de apps y sus destinos exactos, con rutas ponderadas, marcadores de dirección en movimiento, recuentos de conexiones y una lista equivalente.
Opcional: las peticiones descifradas de los agentes que encamines por Flowlight, y las llamadas de herramientas que hay detrás. La búsqueda llega a los cuerpos de las peticiones y las respuestas.
Opcional: las peticiones descifradas de los agentes que encamines por Flowlight, y las llamadas de herramientas que hay detrás. La búsqueda llega a los cuerpos de las peticiones y las respuestas.
Estado del colector, canales de dispositivos y cobertura de nombres en tres pestañas.
-
Los atajos siguen el orden de la barra lateral: ⌘0 es el décimo elemento y el undécimo sigue disponible sin inventar una tecla.
-
Los atajos siguen el orden visible de la barra lateral. Las versiones Developer ID incluyen Inspeccionar en ⌘7; las de App Store lo omiten, así que Reglas y Fuentes pasan a ⌘7 y ⌘8.
+
En vivo, la pantalla con la que se abre Flowlight.
En Historial, pasa el cursor sobre una barra para abrir una tarjeta desplazable que sigue al puntero y muestra las apps que contribuyeron; las barras no amplían al hacer clic. Haz doble clic en cualquier fila para limitar el historial a ella.
@@ -473,7 +471,7 @@
Rechazar conexiones
rechazará: la conexión se descarta y una alerta registra qué se rechazó, con Permitir … a partir de ahora para añadirlo
a la lista con un clic. El siguiente intento del agente pasa.
Necesita la extensión de red. Rechazar una conexión implica situarse en su camino, y eso el muestreador nettop
- no puede hacerlo; Captura lo dirá en vez de ofrecer un interruptor que no hace nada.
+ no puede hacerlo; Fuentes › Colector lo dirá en vez de ofrecer un interruptor que no hace nada.
Hay cosas que nunca se rechazan, diga lo que diga una lista: tu red local, el DNS, los servicios de Apple y el propio tráfico
de Flowlight. Un Mac bloqueado es peor resultado que un agente bloqueado, así que ante la duda la conexión se permite y se registra.
La aplicación de las reglas también caduca unos segundos después de que Flowlight deje de ejecutarse: un rechazo que nadie puede ver es peor que ninguno, y la forma
@@ -505,8 +503,8 @@
Salvaguardas de agente: bloquear una herramienta, un servido
Esto no es un sandbox. Una herramienta rechazada deja de ofrecerse y deja de responderse. Un agente que siga teniendo un
shell puede hacer a mano lo que habría hecho la herramienta. Flowlight lo registrará; no pretende impedirlo.
-
Captura: motores y fuentes
-
Flowlight registra el tráfico de una de dos maneras, que se eligen en Captura. Se diferencian en lo que pueden perderse, y conviene
+
Fuentes: colector y motores
+
Flowlight registra el tráfico de una de dos maneras, que se eligen en Fuentes › Colector. Se diferencian en lo que pueden perderse, y conviene
entenderlo antes de confiar en cualquiera de las dos.
muestreador nettop (predeterminado)
extensión de red
@@ -532,7 +530,7 @@
Captura: motores y fuentes
y sin tocar la fuente que tú elegiste. Volver a intentar la extensión, dentro de Extensión de red, empieza de nuevo.
Y en algunos Mac no puede funcionar en absoluto. macOS permite un filtro de contenido a la vez, y normalmente lo ocupa el software de seguridad
corporativo: Palo Alto Networks GlobalProtect, CrowdStrike Falcon y similares. En esas máquinas el filtro de Flowlight se instalará y se conectará, y
- después nunca recibirá una conexión. Captura lista los que encuentra y te ofrece volver al muestreador, que
+ después nunca recibirá una conexión. Fuentes › Colector lista los que encuentra y te ofrece volver al muestreador, que
no necesita filtro y funciona junto a ellos.
Consulta la guía para desarrolladores para ver cómo está construido.
@@ -601,7 +599,7 @@
Ejecutar en segundo plano
sí tienes. La configuración de los nombres de host se ofrece un rato después del arranque y solo mientras haya una ventana abierta, en lugar de recibir un primer arranque con una
petición de contraseña; la oferta vuelve en el siguiente arranque hasta que la aceptes o la descartes.
Salir de Flowlight detiene el muestreador. No detiene la extensión de red: una extensión del sistema se ejecuta por su cuenta, así que el filtro
- sigue examinando conexiones hasta que la desactives o la desinstales en Captura.
+ sigue examinando conexiones hasta que la desactives o la desinstales en Fuentes › Colector.
Exportar a OpenTelemetry o a un SIEM
Desactivada hasta que la configures, y no hay ningún servicio de Flowlight al que enviar. El endpoint lo pones tú —tu propio
@@ -640,7 +638,7 @@
Exportar a OpenTelemetry o a un SIEM
Tus datos
Todo vive en ~/Library/Application Support/Flowlight/traffic.sqlite. Las filas por segundo se guardan 6 horas
(ajustable), las de minuto 14 días, las horarias 400 días, las diarias indefinidamente, y las alertas 90 días.
- Captura › Borrar todos los datos las elimina.
+ Ajustes › Datos y privacidad › Borrar todos los datos las elimina.
Actualizaciones
Cuando aparece una versión nueva, Flowlight te lo dice con una notificación y un distintivo en la barra lateral en vez de interrumpir lo que estás
@@ -659,7 +657,7 @@
Modo demo
Desinstalación
-
En Captura, elige Retirar el acceso a la captura de paquetes (pide tu contraseña) si lo activaste,
+
En Fuentes › Colector, elige Retirar el acceso a la captura de paquetes (pide tu contraseña) si lo activaste,
desinstala el filtro de contenido si lo instalaste y desactiva la inspección HTTPS en Inspeccionar para que su certificado
salga de tu llavero. Esas tres cosas solo puede retirarlas Flowlight.
Sal de Flowlight y muévelo de Aplicaciones a la papelera; o, si lo instalaste con Homebrew,
@@ -678,18 +676,18 @@
Preguntas y respuestas
acumulados de macOS una vez por segundo y registra el cambio, así que una transferencia larga se cuenta con exactitud; pero una conexión que se abre y se
cierra entre dos lecturas no aparece en absoluto. A la extensión de red la llama macOS cada vez que se hace una conexión, así que
incluso una petición de cinco milisegundos queda registrada. Si vigilas un agente de IA que dispara muchas peticiones cortas, instala la
- extensión desde Captura. La comparación completa está más arriba.
+ extensión desde Fuentes › Colector. La comparación completa está más arriba.
He activado la extensión de red y no aparece nada. El muestreador funciona bien.
Casi siempre es porque otro filtro de contenido ya ocupa la plaza. macOS ejecuta un filtro de contenido a la vez, y
normalmente lo reclama el software de seguridad corporativo: Palo Alto Networks GlobalProtect, CrowdStrike Falcon y similares. El filtro de
- Flowlight se instala, se activa y se conecta, así que Captura dice Conectado a la extensión de filtro, pero macOS no le entrega ni una
- conexión y las pantallas se quedan vacías. Captura lista los filtros que encuentra y te ofrece volver
+ Flowlight se instala, se activa y se conecta, así que Fuentes › Colector dice Conectado a la extensión de filtro, pero macOS no le entrega ni una
+ conexión y las pantallas se quedan vacías. Fuentes › Colector lista los filtros que encuentra y te ofrece volver
al muestreador, que no usa filtro y funciona junto a ellos. Solo pierdes las conexiones muy cortas
(la comparación); todo lo demás se registra igual.
La extensión dejó de funcionar después de actualizar Flowlight.
Las versiones anteriores a la 0.2.5 tenían esto: macOS sigue ejecutando la compilación de la extensión que se activó por última vez, así que tras una actualización la
extensión era la versión antigua y macOS rechaza la conexión entre una pareja que no coincide. Desde la 0.2.5, Flowlight lo comprueba al arrancar
- y reactiva el filtro él mismo. En una versión anterior, pulsa una vez Instalar y activar el filtro en Captura.
+ y reactiva el filtro él mismo. En una versión anterior, pulsa una vez Instalar y activar el filtro en Fuentes › Colector.
Algo más va mal con la captura y no sé qué.
Ejecuta esto y lee lo que imprime: informa solo de estados y recuentos, nunca de nada que Flowlight haya registrado sobre tu tráfico:
diff --git a/docs/es/index.html b/docs/es/index.html
index 5c9aedb4..1b4e7b85 100644
--- a/docs/es/index.html
+++ b/docs/es/index.html
@@ -48,7 +48,7 @@
-
+
Ir al contenido
@@ -97,7 +97,7 @@
Observa la actividad de red de tus apps.
brew install --cask xinbetween/tap/flowlight
-
v0.17.2macOS 15+UniversalGPL-3.0Sin telemetría
+
v0.17.3macOS 15+UniversalGPL-3.0Sin telemetría
@@ -127,7 +127,7 @@
Observa la actividad de red de tus apps.
-
Ve la ruta real de IA: agentes, herramientas atribuidas, puertas de enlace configuradas, la etapa de proxy observada por Flowlight y destinos exactos. El ancho muestra el total recibido y enviado en el período seleccionado. Con datos de demostración.
@@ -135,7 +135,7 @@
Observa la actividad de red de tus apps.
-
La vista Agentes de IA: el proveedor de modelo de cada agente y todo lo demás con lo que habló. Con datos de demostración.
@@ -179,13 +179,13 @@
Historial
¿Adónde ha ido todo? Del segundo al año, agrupado por ap
Alertas
¿Qué ha pintado mal? Alertas por app, explicables, con el destino y el umbral.
⌘5
-
Reglas
¿Qué he rechazado y se está cumpliendo? Cada regla, lo que ha bloqueado y un flujo con todas las decisiones.
⌘8
+
Reglas
¿Qué he rechazado y se está cumpliendo? Cada regla, lo que ha bloqueado y un flujo con todas las decisiones.
⌘8 · Developer ID / ⌘7 · App Store
Preguntar
Preguntas en lenguaje corriente, respondidas con el historial, y debajo cada consulta que ejecutó.
⌘6
-
-
Dispositivos
Bluetooth, USB y cámaras: qué está emparejado, conectado o activo y cuándo cambió. Desactivado hasta que lo actives.
⌘9
+
+
Fuentes
¿Están llegando datos, cuánto tiene nombre y qué canales de dispositivos están activos? Colector, Dispositivos y Cobertura en un solo lugar.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspeccionar
Opcional. ¿Qué envió el agente en realidad y qué llamada de herramienta lo provocó? Peticiones descifradas, llamadas de herramientas, resultados.
⌘7
+
Inspeccionar
Opcional. ¿Qué envió el agente en realidad y qué llamada de herramienta lo provocó? Peticiones descifradas, llamadas de herramientas, resultados.
⌘7 · Developer ID
Conexiones
¿Qué se comunica? Un mapa Sankey ampliable del tráfico de apps y las rutas comprobadas de agentes de IA, con una lista exacta equivalente.
⌘4
@@ -405,16 +405,16 @@
Correlaciona las llamadas de herramientas compatibles con las peticiones de
Mac. Arranca un agente desde un Terminal inspeccionado y el tráfico HTTP compatible del agente y de sus herramientas se descifra, con las llamadas de herramientas que
pidió el modelo y los resultados que volvieron.
-
¿Adónde han ido mis notas? La subida de curl a paste.example, rastreada hasta el comando Bash que pidió el modelo, con el
cuerpo que envió.
-
Todas las herramientas que un agente ofrece al modelo. Los agentes declaran sus herramientas en cada turno, así que Flowlight las lista todas, señalando
las que el modelo usó de verdad y las que no tocó nunca.
-
Incluidos los que no se ven en el cable. Cuando un agente pide al proveedor que conecte con un servidor MCP, ese tráfico
nunca llega a tu Mac. Su petición sí, así que el servidor, su URL, su ajuste de aprobación y sus herramientas siguen apareciendo.
@@ -460,7 +460,7 @@
Un monitor que no tienes que vigilar
-
Un agente, todas sus llamadas de herramientas. El tráfico del git, del curl y de los servidores MCP que arrancó Claude Code cuenta como de Claude Code.
Con la inspección HTTPS activada, la pestaña Llamadas de herramientas muestra qué pidió el modelo, qué volvió y las peticiones que hizo cada herramienta:
@@ -470,10 +470,10 @@
Un monitor que no tienes que vigilar
-
Historial. Zoom del segundo al año, tres agrupaciones y gráficos que siguen legibles con cientos de apps.
-
Alertas. Cada una nombra la app, el destino y la cifra que la activó.
@@ -523,7 +523,7 @@
Funcionando en menos de un minuto
líneas base para detectar anomalías y reglas pensadas para los agentes de IA. Conviven bien.
¿Por qué me pide la contraseña?
macOS solo permite leer paquetes de red a los administradores. La configuración inicial da acceso de lectura a tu cuenta, igual
- que hace Wireshark. Puedes retirarlo cuando quieras desde la pantalla Captura.
+ que hace Wireshark. Puedes retirarlo cuando quieras desde Fuentes › Colector.
¿Puede saber qué servidor MCP o qué herramienta hizo una petición?
Sí, a nivel de proceso. Flowlight sigue cada proceso hasta el agente que lo arrancó, así que el curl de una herramienta de shell
o las conexiones de un servidor MCP se atribuyen a ese agente, y los servidores MCP toman su nombre de las configuraciones de Claude Code, Claude
@@ -589,7 +589,7 @@
cualquier cosa cuyo instalador apruebes— puede descargar esa extensión, detener la app o borrar su base de datos. Nada en el diseño lo impide,
y ninguna herramienta de monitorización en macOS puede impedirlo y seguir siendo una herramienta que también puedas apagar tú.
La afirmación honesta es más estrecha y sigue siendo útil: el software que se porta mal pero no elude activamente un monitor se verá. El
- software que sí lo elude activamente puede no verse, y al menos dejará un hueco —una extensión que se detuvo, un periodo sin datos— que la
- pantalla Cobertura está ahí para mostrar.
+ software que sí lo elude activamente puede no verse, y al menos dejará un hueco —una extensión que se detuvo, un periodo sin datos— que
+ Fuentes › Cobertura está ahí para mostrar.
Lo que la captura se pierde
@@ -137,7 +137,7 @@
Lo que la captura se pierde
Los servicios del sistema exentos de los filtros de contenido. macOS no le muestra todo a un filtro de contenido; parte
de su propio tráfico no llega nunca al nuestro.
Otro filtro de contenido que ocupa el sitio. macOS ejecuta uno a la vez. Si lo tiene una VPN o un agente de seguridad, el
- filtro de Flowlight se instala, se conecta y nunca se le pide filtrar nada: Captura lo dice en vez de mostrar una pantalla vacía.
+ filtro de Flowlight se instala, se conecta y nunca se le pide filtrar nada: Fuentes › Colector lo dice en vez de mostrar una pantalla vacía.
Las conexiones cortas, con el muestreador. Sin la extensión, Flowlight lee contadores una vez por segundo: una conexión
que se abre y se cierra entre dos lecturas no se registra nunca.
Los canales que no son TCP ni UDP. Bluetooth y USB se ven como dispositivos, no como bytes. El servidor MCP local de un
@@ -148,7 +148,7 @@
Lo que la inspección se pierde
La inspección HTTPS lee solo lo que se encamina por el proxy local de Flowlight, y eso lo decide un programa cuando arranca. Una app que
ignora los ajustes de proxy, una que se arrancó antes de activar la inspección, o una que fija sus certificados pasa intacta: a propósito,
porque romper una conexión con certificado fijado rompería la app. QUIC tampoco se le ofrece al proxy.
-
Así que una pantalla Inspeccionar vacía significa «aquí no se ha encaminado nada», no «no ha pasado nada». Cobertura dice cuál de las dos
+
Así que una pantalla Inspeccionar vacía significa «aquí no se ha encaminado nada», no «no ha pasado nada». Fuentes › Cobertura dice cuál de las dos
cosas se aplica, app por app.
Un filtre dans le noyau écarte tous les autres paquets avant que Flowlight les voie, et le contenu des paquets n’est jamais conservé.
macOS ne laisse que les administrateurs lire les paquets : la fenêtre Nommer votre trafic demande donc votre mot de passe une fois. Elle installe
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, qui donne au groupe access_bpf un accès en lecture à
- /dev/bpf* à chaque démarrage, la même approche que celle de Wireshark. Retirez-le à tout moment depuis Capture › Retirer l’accès à la capture de paquets.
+ /dev/bpf* à chaque démarrage, la même approche que celle de Wireshark. Retirez-le à tout moment depuis Sources › Collecteur › Retirer l’accès à la capture de paquets.
Identifier les propriétaires de réseau étiquette le trafic sans nom d’hôte par l’exploitant de l’adresse
(Cloudflare, Inc. · AS13335). C’est activé par défaut et cela envoie ces adresses IP publiques (jamais les privées) au
- service DNS de Team Cymru. Désactivez-le dans Capture.
+ service DNS de Team Cymru. Désactivez-le dans Sources › Collecteur.
Langue
Flowlight est traduit en anglais, 简体中文, 繁體中文, 日本語, 한국어, français, allemand, italien, espagnol et
@@ -168,15 +168,13 @@
Les vues
Historique
⌘3
Où le trafic est parti, de la seconde à l’année. Groupez par App, Destination ou IP ; passez aux Graphiques ou à À regarder de près ; exportez en CSV.
Une carte stable des apps et de leurs destinations exactes, avec des chemins pondérés, des marqueurs de direction animés, le nombre de connexions et une liste équivalente.
Facultatif : les requêtes déchiffrées des agents que vous faites passer par Flowlight, et les appels d’outils qui les ont causées. La recherche va jusque dans les corps de requête et de réponse.
Facultatif : les requêtes déchiffrées des agents que vous faites passer par Flowlight, et les appels d’outils qui les ont causées. La recherche va jusque dans les corps de requête et de réponse.
La santé et la récupération du collecteur, la couverture des noms d’hôte, ainsi que l’activité facultative des caméras, du Bluetooth, de l’USB et du stockage dans trois onglets.
-
Les raccourcis suivent l’ordre de la barre latérale : ⌘0 est le dixième élément et le onzième reste accessible sans inventer de touche.
-
Les raccourcis suivent l’ordre visible de la barre latérale. Les versions Developer ID incluent Inspecter en ⌘7 ; les versions App Store l’omettent, donc Règles et Sources passent à ⌘7 et ⌘8.
+
En direct, l’écran sur lequel Flowlight s’ouvre.
Dans Historique, survolez une barre pour ouvrir une fiche défilante qui suit le pointeur et affiche les apps contributrices ; les barres ne zooment pas au clic. Double-cliquez une ligne pour y restreindre l’historique.
@@ -195,7 +193,7 @@
Règles pour les agents IA
Hôte sans nom
se connecte à une IP brute sans nom d’hôte, sur un port inhabituel
Activé
Actif pendant votre absence
déplace 1 MB ou plus en une minute après que vous avez cessé d’utiliser le clavier et la souris
15 minutes
-
Les agents bénéficient d’une période d’apprentissage d’1 heure avant les premières alertes de nouvelle destination. Modifiez tout cela dans Réglages › Détection.
+
Les agents bénéficient d’une période d’apprentissage d’1 heure avant les premières alertes de nouvelle destination. Modifiez tout cela dans Alertes › Détection.
Outils & serveurs MCP
Les agents font une grande part de leur travail via d’autres processus : un outil shell lance curl, git ou npm, et les serveurs
@@ -477,7 +475,7 @@
Refuser des connexions
refusera aussi : la connexion est abandonnée et une alerte consigne ce qui a été refusé, avec Autoriser … désormais pour l’ajouter
à la liste en un clic. La tentative suivante de l’agent passe.
Cela nécessite l’extension réseau. Refuser une connexion suppose de se trouver sur son chemin, ce que l’échantillonneur nettop
- ne peut pas faire — Capture le dira plutôt que de proposer un interrupteur qui ne fait rien.
+ ne peut pas faire — Sources › Collecteur le dira plutôt que de proposer un interrupteur qui ne fait rien.
Certaines choses ne sont jamais refusées, quoi qu’en dise une liste : votre réseau local, le DNS, les services d’Apple et le trafic de
Flowlight lui-même. Un Mac bloqué est un pire résultat qu’un agent bloqué : en cas de doute, la connexion est donc autorisée et enregistrée.
L’application des refus cesse aussi quelques secondes après l’arrêt de Flowlight — un refus que personne ne peut voir est pire que pas de refus, et le moyen
@@ -509,8 +507,9 @@
Garde-fous des agents : bloquer un outil, un serveur ou
Ce n’est pas un bac à sable. Un outil refusé cesse d’être proposé et cesse d’obtenir une réponse. Un agent qui a encore un
shell peut faire à la main ce que l’outil aurait fait. Flowlight l’enregistrera ; il ne prétend pas l’empêcher.
-
Capture : moteurs et sources
-
Flowlight enregistre le trafic de deux façons, au choix dans Capture. Elles diffèrent par ce qu’elles peuvent manquer, ce qu’il vaut la peine de
+
Sources : collecteur, couverture et appareils
+
Sources réunit la configuration opérationnelle. Son résumé de santé indique si le trafic arrive, quelle part est nommée et quels canaux d’appareils facultatifs sont actifs ; toute étape inachevée mène directement à Sources › Collecteur.
+
Flowlight enregistre le trafic de deux façons, au choix dans Sources › Collecteur. Elles diffèrent par ce qu’elles peuvent manquer, ce qu’il vaut la peine de
comprendre avant de compter sur l’une ou l’autre.
échantillonneur nettop (par défaut)
Extension réseau
@@ -536,12 +535,12 @@
Capture : moteurs et sources
Réessayer l’extension, sous Extension réseau, reprend tout à zéro.
Elle ne peut pas non plus fonctionner du tout sur certains Mac. macOS n’autorise qu’un filtre de contenu à la fois, et les logiciels de sécurité
d’entreprise le détiennent d’ordinaire — Palo Alto Networks GlobalProtect, CrowdStrike Falcon et compagnie. Le filtre de Flowlight s’installera et se connectera sur ces
- machines, puis ne recevra jamais une seule connexion. Capture liste ceux qu’il trouve et propose de vous ramener à l’échantillonneur, qui
+ machines, puis ne recevra jamais une seule connexion. Sources › Collecteur liste ceux qu’il trouve et propose de vous ramener à l’échantillonneur, qui
n’a besoin d’aucun filtre et fonctionne à côté d’eux.
Voyez le guide du développeur pour la façon dont c’est construit.
Couverture : ce dont Flowlight ne peut pas rendre compte
-
Tous les autres écrans répondent à ce qui s’est passé. Couverture répond à ce qu’on ne vous aurait pas dit, et c’est cela
+
Sources › Couverture répond à ce qu’on ne vous aurait pas dit, et c’est cela
qui décide de ce que valent les autres écrans. Elle pose trois questions par app, parce qu’elles échouent indépendamment.
Est-ce que ça a été vu ? L’extension réseau voit chaque flux à son ouverture. L’échantillonneur nettop lit des compteurs
une fois par seconde : une connexion qui s’ouvre et se ferme entre deux relevés — une recherche DNS, un appel d’API bref, un script qui
@@ -560,7 +559,7 @@
Couverture : ce dont Flowlight ne peut pas rendre compte<
réconfort et non un fait.
Appareils : Bluetooth, USB et stockage externe
-
Un Mac émet et reçoit par plus que TCP et UDP. L’écran Appareils couvre le reste, et il est désactivé
+
Un Mac émet et reçoit par plus que TCP et UDP. Sources › Appareils couvre le reste, et chaque canal est désactivé
jusqu’à ce que vous l’activiez — non parce qu’il demanderait une autorisation que Flowlight n’a pas déjà, mais parce que surveiller davantage de
votre Mac devrait être votre décision plutôt que le fait d’une mise à jour.
Bluetooth montre quels appareils sont appairés, lesquels sont connectés, et quand cela a changé, lu depuis le système
@@ -606,7 +605,7 @@
Fonctionner en arrière-plan
avez. La configuration des noms d’hôte est proposée un peu après le lancement et seulement tant qu’une fenêtre est ouverte, plutôt que d’accueillir un premier lancement par une
demande de mot de passe ; la proposition revient au lancement suivant jusqu’à ce que vous l’acceptiez ou l’écartiez.
Quitter Flowlight arrête l’échantillonneur. Cela n’arrête pas l’extension réseau : une extension système tourne pour son compte, donc le filtre
- continue d’inspecter les connexions jusqu’à ce que vous le désactiviez ou le désinstalliez dans Capture.
+ continue d’inspecter les connexions jusqu’à ce que vous le désactiviez ou le désinstalliez dans Sources › Collecteur.
Exporter vers OpenTelemetry ou un SIEM
Désactivé tant que vous ne l’avez pas configuré, et il n’existe aucun service Flowlight vers lequel envoyer. C’est vous qui nommez le point de terminaison — votre propre
@@ -646,7 +645,7 @@
Exporter vers OpenTelemetry ou un SIEM
Vos données
Tout vit dans ~/Library/Application Support/Flowlight/traffic.sqlite. Les lignes par seconde sont conservées 6 heures
(réglable), les lignes à la minute 14 jours, les lignes horaires 400 jours, les lignes quotidiennes indéfiniment, et les alertes 90 jours.
- Capture › Effacer toutes les données les supprime.
+ Réglages › Données et confidentialité › Effacer toutes les données les supprime.
Mises à jour
Quand une nouvelle version paraît, Flowlight vous le signale par une notification et un badge dans la barre latérale plutôt qu’en interrompant ce que vous
@@ -665,7 +664,7 @@
Mode démo
Désinstallation
-
Dans Capture, choisissez Retirer l’accès à la capture de paquets (demande votre mot de passe) si vous l’aviez activé,
+
Dans Sources › Collecteur, choisissez Retirer l’accès à la capture de paquets (demande votre mot de passe) si vous l’aviez activé,
désinstallez le filtre de contenu si vous l’aviez installé, et désactivez l’inspection HTTPS dans Inspecter pour que son certificat
quitte votre trousseau. Flowlight seul peut retirer ces trois choses.
Quittez Flowlight et déplacez-le d’Applications vers la Corbeille — ou, si vous l’avez installé avec Homebrew,
@@ -684,18 +683,18 @@
Questions & réponses
cumulés de macOS une fois par seconde et enregistre l’écart : un transfert long est donc compté exactement — mais une connexion qui s’ouvre et
se ferme entre deux relevés n’apparaît pas du tout. L’extension réseau est appelée par macOS à chaque connexion établie, donc
même une requête de cinq millisecondes est enregistrée. Si vous surveillez un agent IA qui déclenche beaucoup de requêtes brèves, installez
- l’extension depuis Capture. La comparaison complète est plus haut.
+ l’extension depuis Sources › Collecteur. La comparaison complète est plus haut.
J’ai activé l’extension réseau et rien n’apparaît. L’échantillonneur fonctionne très bien.
Presque toujours parce qu’un autre filtre de contenu occupe déjà la place. macOS n’exécute qu’un filtre de contenu à la fois, et les
logiciels de sécurité d’entreprise se l’accaparent d’ordinaire — Palo Alto Networks GlobalProtect, CrowdStrike Falcon et similaires. Le filtre de Flowlight
- s’installe, s’active et se connecte quand même, donc Capture affiche Connecté à l’extension de filtrage, mais macOS ne lui remet jamais une
- seule connexion et les écrans restent vides. Capture liste les filtres qu’il trouve et propose de vous ramener à
+ s’installe, s’active et se connecte quand même, donc Sources › Collecteur affiche Connecté à l’extension de filtrage, mais macOS ne lui remet jamais une
+ seule connexion et les écrans restent vides. Sources › Collecteur liste les filtres qu’il trouve et propose de vous ramener à
l’échantillonneur, qui n’utilise pas de filtre et fonctionne à côté d’eux. Vous ne perdez que les connexions très brèves
(la comparaison) ; tout le reste est enregistré de la même façon.
L’extension a cessé de fonctionner après une mise à jour de Flowlight.
Les versions antérieures à 0.2.5 avaient ce défaut : macOS continue d’exécuter la version de l’extension activée en dernier, donc après une mise à jour
l’extension était l’ancienne version, et macOS refuse la connexion entre une paire dépareillée. À partir de 0.2.5, Flowlight vérifie au lancement
- et réactive le filtre lui-même. Sur une version plus ancienne, appuyez une fois sur Installer & activer le filtre dans Capture.
+ et réactive le filtre lui-même. Sur une version plus ancienne, appuyez une fois sur Installer & activer le filtre dans Sources › Collecteur.
Autre chose ne va pas avec la capture et je ne sais pas quoi.
Lancez ceci et lisez ce qui s’affiche — cela ne rapporte que des états et des comptes, jamais rien de ce que Flowlight a enregistré sur votre trafic :
diff --git a/docs/fr/index.html b/docs/fr/index.html
index fac96d23..bd083475 100644
--- a/docs/fr/index.html
+++ b/docs/fr/index.html
@@ -48,7 +48,7 @@
-
+
Aller au contenu
@@ -97,7 +97,7 @@
Voyez l’activité réseau de vos apps.
brew install --cask xinbetween/tap/flowlight
-
v0.17.2macOS 15+UniverselGPL-3.0Sans télémétrie
+
v0.17.3macOS 15+UniverselGPL-3.0Sans télémétrie
@@ -127,7 +127,7 @@
Voyez l’activité réseau de vos apps.
-
Voyez la route IA réelle : agents, outils attribués, passerelles configurées, étape proxy observée par Flowlight et destinations exactes. La largeur indique le total reçu et envoyé pendant la période sélectionnée. Avec des données de démonstration.
@@ -135,7 +135,7 @@
Voyez l’activité réseau de vos apps.
-
La vue Agents IA : le fournisseur de modèle de chaque agent, et tout le reste de ce qu’il a contacté. Avec des données de démonstration.
@@ -179,13 +179,13 @@
Historique
Où tout cela est-il parti ? De la seconde à l’ann
Alertes
Qu’est-ce qui clochait ? Des alertes explicables, par app, avec la destination et le seuil.
⌘5
-
Règles
Qu’ai-je refusé, et est-ce bien appliqué ? Chaque règle, ce qu’elle a bloqué, et le flux de toutes les décisions.
⌘8
+
Règles
Qu’ai-je refusé, et est-ce bien appliqué ? Chaque règle, ce qu’elle a bloqué, et le flux de toutes les décisions.
⌘8 · Developer ID / ⌘7 · App Store
Demander
Des questions en langage courant, auxquelles l’historique répond — avec la liste des requêtes exécutées juste en dessous.
⌘6
-
-
Appareils
Bluetooth, USB et caméras : ce qui est appairé, branché ou actif, et quand cela a changé. Désactivé jusqu’à ce que vous l’activiez.
⌘9
+
+
Sources
Les données arrivent-elles, quelle part est nommée et quels canaux d’appareils sont actifs ? Collecteur, Appareils et Couverture au même endroit.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspecter
Facultatif. Qu’a réellement envoyé l’agent, et quel appel d’outil en est la cause ? Requêtes déchiffrées, appels d’outils, résultats.
⌘7
+
Inspecter
Facultatif. Qu’a réellement envoyé l’agent, et quel appel d’outil en est la cause ? Requêtes déchiffrées, appels d’outils, résultats.
⌘7 · Developer ID
Connexions
Qui communique ? Une carte Sankey zoomable du trafic des apps et des chemins attestés des agents IA, avec une liste exacte équivalente.
⌘4
@@ -405,16 +405,16 @@
Reliez les appels d’outils pris en charge aux requêtes réseau
Mac. Lancez un agent depuis un Terminal inspecté et le trafic HTTP pris en charge de l’agent et de ses outils est déchiffré, avec les appels d’outils que le
modèle a demandés et les résultats qui lui sont revenus.
-
Où sont parties mes notes ? L’envoi de curl vers paste.example, remonté jusqu’à la commande Bash demandée par le modèle, avec le
corps transmis.
-
Tous les outils qu’un agent propose au modèle. Les agents déclarent leurs outils à chaque tour, donc Flowlight les liste tous, en distinguant
ceux que le modèle a vraiment utilisés de ceux qu’il n’a jamais touchés.
-
Y compris ceux qu’on ne voit pas passer sur le réseau. Quand un agent demande au fournisseur de se connecter à un serveur MCP, ce trafic
ne passe jamais par votre Mac. Sa requête, si : le serveur, son URL, son réglage d’approbation et ses outils apparaissent quand même.
@@ -460,7 +460,7 @@
Un moniteur que vous n’avez pas à surveiller
-
Un agent, tous ses appels d’outils. Le trafic des git, curl et serveurs MCP lancés par Claude Code compte comme celui de Claude Code.
Avec l’inspection HTTPS activée, l’onglet Appels d’outils montre ce que le modèle a demandé, ce qui est revenu et les requêtes émises par chaque outil :
@@ -470,10 +470,10 @@
Un moniteur que vous n’avez pas à surveiller
-
Historique. Zoom de la seconde à l’année, trois regroupements, des graphiques qui restent lisibles avec des centaines d’apps.
-
Alertes. Chacune nomme l’app, la destination et le chiffre qui l’a déclenchée.
@@ -523,7 +523,7 @@
En marche en moins d’une minute
des références pour détecter les anomalies, et des règles conçues pour les agents IA. Les deux cohabitent très bien.
Pourquoi demande-t-il mon mot de passe ?
macOS ne laisse que les administrateurs lire les paquets réseau. La configuration unique donne à votre compte un accès en lecture, exactement
- comme le fait Wireshark. Vous pouvez la retirer à tout moment depuis l’écran Capture.
+ comme le fait Wireshark. Vous pouvez la retirer à tout moment depuis Sources › Collecteur.
Peut-il dire quel serveur MCP ou quel outil a émis une requête ?
Oui, au niveau du processus. Flowlight remonte chaque processus jusqu’à l’agent qui l’a lancé, de sorte que le curl d’un outil
shell ou les connexions d’un serveur MCP sont attribués à cet agent, et les serveurs MCP sont nommés d’après les configurations de Claude Code, Claude
@@ -589,7 +589,7 @@
L’image disque et son fichier de somme de contrôle
Seulement quand vous cliquez sur Télécharger & ouvrir
Mise à jour du pack de règles officiel
flowlight.xinbetween.com
Une requête HTTPS standard vers le flux officiel fixe. Le serveur voit votre adresse IP, l’agent utilisateur Flowlight/<version> et les validateurs conditionnels du cache ; il ne reçoit ni trafic, ni réglages des packs, ni identifiant d’appareil
Après le démarrage, lorsqu’une vérification est due, puis au maximum une fois par jour tant que le service fonctionne normalement. Activée par défaut ; interrupteur de désactivation et option manuelle Rechercher maintenant dans Règles › Packs
DNS inverse
Le résolveur DNS que vous avez configuré
Une recherche du nom enregistré d’une adresse IP, quand aucun nom d’hôte n’a été observé
Au besoin, dans le mode de capture par échantillonnage, qui est celui par défaut jusqu’à ce que l’extension réseau tourne. Pas d’interrupteur d’arrêt : sans elle, l’échantillonneur ne peut pas nommer la plupart des connexions. L’extension réseau les nomme à partir du trafic lui-même et ne fait pas cette recherche
-
Recherche du propriétaire de réseau
Team Cymru, par DNS
Des adresses IP publiques sans nom d’hôte connu. Les adresses privées et réservées ne quittent jamais votre Mac
Activé par défaut. Interrupteur d’arrêt dans Capture › Identifier les propriétaires de réseau
+
Recherche du propriétaire de réseau
Team Cymru, par DNS
Des adresses IP publiques sans nom d’hôte connu. Les adresses privées et réservées ne quittent jamais votre Mac
Activé par défaut. Interrupteur d’arrêt dans Sources › Collecteur › Identifier les propriétaires de réseau
Demander avec un modèle hébergé
Le fournisseur que vous choisissez : Anthropic, OpenAI, Google Gemini ou un point de terminaison compatible
Votre question et les résultats renvoyés par les requêtes Flowlight en lecture seule choisies par le modèle. La base de données de trafic elle-même n’est pas envoyée
Seulement quand vous choisissez un fournisseur hébergé et soumettez une question. L’écran Demander montre les requêtes transmises
Exportation vers un collecteur
Le point de terminaison OpenTelemetry ou HTTP que vous configurez
Les champs indiqués dans Réglages › Exportation, comme les agrégats de trafic et les alertes. Les en-têtes d’authentification sont stockés dans le trousseau
Seulement après que vous avez configuré un point de terminaison et activé l’exportation
Trafic d’une application inspectée
La destination d’origine demandée par l’application inspectée
La requête de l’application, transmise par le proxy local de Flowlight après déchiffrement
Seulement tant que l’inspection HTTPS est activée et que l’application est acheminée par le proxy
@@ -135,14 +135,14 @@
Les requêtes réseau que fait l’app
Autorisations
-
Mot de passe administrateur, une fois, pour l’accès à la capture de paquets. Retirable depuis l’écran Capture.
+
Mot de passe administrateur, une fois, pour l’accès à la capture de paquets. Retirable depuis Sources › Collecteur.
Notifications, pour les avertissements. Facultatif.
Élément d’ouverture, seulement si vous activez Lancer à l’ouverture de session.
Conservation
Les données par seconde 6 heures (réglable), les données à la minute 14 jours, les données horaires 400 jours, les totaux quotidiens indéfiniment, les alertes 90 jours.
- Capture › Effacer toutes les données supprime tout, et retirer ~/Library/Application Support/Flowlight fait de même.
+ Réglages › Données et confidentialité › Effacer toutes les données supprime tout, et retirer ~/Library/Application Support/Flowlight fait de même.
Ce site
Ce site est une page statique hébergée sur GitHub Pages et servie via Cloudflare. Il ne dépose aucun cookie et n’exécute aucune analytique. GitHub
@@ -189,7 +189,7 @@
et aucun outil de surveillance sur macOS ne peut l’empêcher tout en restant un outil que vous pouvez aussi éteindre vous-même.
L’affirmation honnête est plus étroite et reste utile : un logiciel qui se comporte mal sans chercher activement à échapper à une
surveillance sera vu. Un logiciel qui y échappe activement, peut-être pas — et il laissera au moins un trou : une extension qui s’est
- arrêtée, une période sans données. C’est ce que l’écran Couverture est là pour montrer.
+ arrêtée, une période sans données. C’est ce que Sources › Couverture est là pour montrer.
Ce que la capture manque
@@ -139,7 +139,7 @@
Ce que la capture manque
Les services système dispensés des filtres de contenu. macOS ne montre pas tout à un filtre de contenu ; une partie
de son propre trafic n’atteint jamais le nôtre.
Un autre filtre de contenu qui détient la place. macOS n’en exécute qu’un à la fois. Si un VPN ou un agent de sécurité le
- détient, le filtre de Flowlight s’installe, se connecte, et on ne lui demande jamais de filtrer quoi que ce soit — Capture le dit plutôt que
+ détient, le filtre de Flowlight s’installe, se connecte, et on ne lui demande jamais de filtrer quoi que ce soit — Sources › Collecteur le dit plutôt que
de montrer un écran vide.
Les connexions brèves, avec l’échantillonneur. Sans l’extension, Flowlight lit des compteurs une fois par seconde :
une connexion qui s’ouvre et se ferme entre deux relevés n’est jamais enregistrée.
@@ -151,7 +151,7 @@
Ce que l’inspection manque
L’inspection HTTPS ne lit que ce qui est acheminé par le proxy local de Flowlight, et c’est un programme qui en décide à son démarrage. Une
app qui ignore les réglages de proxy, une app lancée avant l’activation de l’inspection, ou une app qui épingle ses certificats passe sans être
touchée — délibérément, parce que casser une connexion épinglée casserait l’app. QUIC n’est pas proposé au proxy non plus.
-
Un écran Inspecter vide signifie donc « rien n’a été acheminé ici », pas « rien ne s’est passé ». Couverture dit laquelle
+
Un écran Inspecter vide signifie donc « rien n’a été acheminé ici », pas « rien ne s’est passé ». Sources › Couverture dit laquelle
des deux s’applique, app par app.
See your apps' network activity. brew install --cask xinbetween/tap/flowlight
-
v0.17.2macOS 15+UniversalGPL-3.0No telemetry
+
v0.17.3macOS 15+UniversalGPL-3.0No telemetry
@@ -127,7 +127,7 @@
See your apps' network activity.
-
See the real AI route: agents, attributed tools, configured gateways, Flowlight's observed proxy stage, and exact destinations. Ribbon width shows total received plus sent traffic for the selected period. Shown with demo data.
@@ -135,7 +135,7 @@
See your apps' network activity.
-
The AI Agents view: each agent's model provider, and everything else it talked to. Shown with demo data.
@@ -143,7 +143,7 @@
See your apps' network activity.
-
Always monitor an agent: Flowlight writes the proxy into the agent's own settings so it routes through on every launch, and says what it's keeping — stop any of it in a click. Shown with demo data.
@@ -187,13 +187,13 @@
History
Where did it all go? From 15 minutes through all history, gro
Alerts
What looked wrong? Explainable, per-app alerts with the destination and the threshold.
⌘5
-
Rules
What have I refused, and is it happening? Every rule, what each has blocked, and a feed of every decision.
⌘8
+
Rules
What have I refused, and is it happening? Every rule, what each has blocked, and a feed of every decision.
⌘8 · Developer ID / ⌘7 · App Store
Ask
Questions in plain language, answered from the history — with every query it ran listed underneath.
⌘6
-
-
Devices
Bluetooth, USB, and cameras: what's paired, what's attached or active, and when that changed. Off until you turn it on.
⌘9
+
+
Sources
Is data arriving, how much is named, and which device channels are active? Collector, Devices and Coverage in one place.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspect
Optional. What did the agent actually send, and which tool call made it? Decrypted requests, tool calls, results.
⌘7
+
Inspect
Optional. What did the agent actually send, and which tool call made it? Decrypted requests, tool calls, results.
⌘7 · Developer ID
Connections
What is communicating? A zoomable Sankey map for app traffic and proved AI-agent paths, with exact list parity.
⌘4
@@ -427,16 +427,16 @@
Correlate supported tool calls with network requests
Mac. Start an agent from an inspected Terminal and supported HTTP traffic from the agent and its tools is decrypted, with tool calls the
model asked for and the results that went back.
-
Where did my notes go? curl's upload to paste.example, traced to the Bash command the model asked for, with the
body it sent.
-
Every tool an agent offers the model. Agents declare their tools on each turn, so Flowlight lists them all, with the
ones the model actually used and the ones it never touched.
-
Including the ones you can't see on the wire. When an agent asks the provider to connect to an MCP server, that traffic
never reaches your Mac. Its request does, so the server, its URL, its approval setting and its tools still show up.
@@ -482,7 +482,7 @@
A monitor you don't have to monitor
-
One agent, every tool call. Traffic from the git, curl and MCP servers Claude Code started counts as Claude Code's.
With HTTPS inspection on, the Tool calls tab shows what the model asked for, what came back, and the requests each tool made:
@@ -492,10 +492,10 @@
A monitor you don't have to monitor
-
History. Preset ranges, a draggable navigator, three groupings, and charts that stay readable with hundreds of apps.
-
Alerts. Each one names the app, the destination and the number that tripped it.
@@ -545,7 +545,7 @@
Running in under a minute
anomaly baselines, and rules built for AI agents. They work well side by side.
Why does it ask for my password?
macOS only lets administrators read network packets. The one-time setup gives your account read access, the
- same way Wireshark does. You can remove it any time from the Capture screen.
+ same way Wireshark does. You can remove it any time from Sources › Collector.
Can it tell which MCP server or tool made a request?
Yes, at the process level. Flowlight follows each process back to the agent that started it, so a shell tool's
curl or an MCP server's connections are attributed to that agent, and MCP servers are named from Claude Code, Claude
@@ -612,7 +612,7 @@
Un filtro nel kernel scarta ogni altro pacchetto prima che Flowlight lo veda, e il contenuto dei pacchetti non viene mai memorizzato.
macOS permette di leggere i pacchetti solo agli amministratori, quindi la finestra Dai un nome al traffico chiede una volta la tua password. Installa
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, che a ogni avvio dà al gruppo access_bpf l'accesso in lettura a
- /dev/bpf*, lo stesso approccio usato da Wireshark. Puoi rimuoverlo quando vuoi da Acquisizione › Revoca l'accesso all'acquisizione dei pacchetti.
+ /dev/bpf*, lo stesso approccio usato da Wireshark. Puoi rimuoverlo quando vuoi da Origini › Collector › Revoca l'accesso all'acquisizione dei pacchetti.
Identifica i proprietari della rete etichetta il traffico senza nome host con chi gestisce l'indirizzo
(Cloudflare, Inc. · AS13335). È attivo per impostazione predefinita e invia quegli indirizzi IP pubblici (mai quelli privati) al servizio
- DNS di Team Cymru. Disattivalo in Acquisizione.
+ DNS di Team Cymru. Disattivalo in Origini › Collector.
Lingua
Flowlight è tradotto in English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español e
@@ -168,15 +168,13 @@
Le viste
Cronologia
⌘3
Dove è andato il traffico, dal secondo all'anno. Raggruppa per App, Destinazione o IP; passa a Grafici o a Vale un'occhiata; esporta in CSV.
Una mappa stabile delle app e delle destinazioni esatte, con percorsi ponderati, indicatori di direzione in movimento, conteggi delle connessioni e un elenco equivalente.
Opzionale: le richieste decifrate degli agenti che instradi attraverso Flowlight e le chiamate agli strumenti che le hanno prodotte. La ricerca entra nei corpi di richieste e risposte.
Opzionale: le richieste decifrate degli agenti che instradi attraverso Flowlight e le chiamate agli strumenti che le hanno prodotte. La ricerca entra nei corpi di richieste e risposte.
Stato del Collector, canali dei dispositivi e copertura dei nomi in tre schede.
-
Le scorciatoie seguono l'ordine della barra laterale: ⌘0 è il decimo elemento e l'undicesimo resta disponibile senza inventare un tasto.
-
Le scorciatoie seguono l'ordine visibile della barra laterale. Le versioni Developer ID includono Ispeziona su ⌘7; quelle App Store lo omettono, quindi Regole e Origini passano a ⌘7 e ⌘8.
+
In diretta, la schermata con cui Flowlight si apre.
In Cronologia, passa il puntatore su una barra per aprire una scheda scorrevole che segue il cursore e mostra le app che hanno contribuito; le barre non ingrandiscono al clic. Fai doppio clic su una riga per limitare la cronologia a essa.
@@ -475,7 +473,7 @@
Rifiutare le connessioni
rifiuterà anche: la connessione viene interrotta e un avviso registra cosa è stato rifiutato, con Consenti … da ora in poi per aggiungerlo
all'elenco con un clic. Il tentativo successivo dell'agente passa.
Richiede l'estensione di rete. Rifiutare una connessione significa stare sul suo percorso, cosa che il campionatore nettop
- non può fare: Acquisizione lo dice, invece di offrire un interruttore che non fa nulla.
+ non può fare: Origini › Collector lo dice, invece di offrire un interruttore che non fa nulla.
Alcune cose non vengono mai rifiutate, qualunque cosa dica un elenco: la tua rete locale, il DNS, i servizi di Apple e il traffico di Flowlight
stesso. Un Mac bloccato è un esito peggiore di un agente bloccato, quindi nel dubbio la connessione viene consentita e registrata.
L'applicazione decade anche pochi secondi dopo che Flowlight smette di funzionare: un rifiuto che nessuno può vedere è peggio di nessun rifiuto, e il modo
@@ -507,8 +505,8 @@
Protezioni per gli agenti: bloccare uno strumento, un server
Questa non è una sandbox. Uno strumento rifiutato non viene più offerto e non riceve più risposta. Un agente che ha ancora una
shell può fare a mano ciò che avrebbe fatto lo strumento. Flowlight lo registra; non pretende di impedirlo.
-
Acquisizione: motori e origini
-
Flowlight registra il traffico in uno di due modi, da scegliere in Acquisizione. Differiscono per ciò che possono perdere, e vale
+
Origini: Collector e motori
+
Flowlight registra il traffico in uno di due modi, da scegliere in Origini › Collector. Differiscono per ciò che possono perdere, e vale
la pena capirlo prima di affidarsi all'uno o all'altro.
campionatore nettop (predefinito)
estensione di rete
@@ -534,7 +532,7 @@
Acquisizione: motori e origini
e lasciando invariata l'origine che hai scelto. Riprova con l'estensione, sotto Estensione di rete, ricomincia da capo.
Su alcuni Mac non può proprio funzionare. macOS consente un solo filtro di contenuto alla volta, e normalmente lo occupa il software
di sicurezza aziendale — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e simili. Su quelle macchine il filtro di Flowlight si installa e si connette,
- e poi non riceve mai una connessione. Acquisizione elenca quelli che trova e propone di riportarti al campionatore, che
+ e poi non riceve mai una connessione. Origini › Collector elenca quelli che trova e propone di riportarti al campionatore, che
non richiede alcun filtro e convive con loro.
Vedi la guida per sviluppatori per come è costruito.
@@ -604,7 +602,7 @@
Esecuzione in background
hai. La configurazione dei nomi host viene proposta un po' dopo l'avvio e solo mentre una finestra è aperta, invece di accogliere il primo avvio con una
richiesta della password; la proposta ritorna al lancio successivo finché non l'accetti o non la rifiuti.
Chiudere Flowlight ferma il campionatore. Non ferma l'estensione di rete: un'estensione di sistema funziona per conto proprio, quindi il filtro
- continua a ispezionare le connessioni finché non lo disattivi o lo disinstalli in Acquisizione.
+ continua a ispezionare le connessioni finché non lo disattivi o lo disinstalli in Origini › Collector.
Esportazione verso OpenTelemetry o un SIEM
Disattivata finché non la configuri, e non esiste alcun servizio Flowlight a cui inviare. Indichi tu l'endpoint — il tuo
@@ -644,7 +642,7 @@
Esportazione verso OpenTelemetry o un SIEM
I tuoi dati
Tutto si trova in ~/Library/Application Support/Flowlight/traffic.sqlite. Le righe al secondo vengono conservate 6 ore
(regolabile), quelle al minuto 14 giorni, quelle orarie 400 giorni, quelle giornaliere a tempo indeterminato e gli avvisi 90 giorni.
- Acquisizione › Cancella tutti i dati le elimina.
+ Impostazioni › Dati e privacy › Cancella tutti i dati le elimina.
Aggiornamenti
Quando compare una nuova versione, Flowlight te lo dice con una notifica e un contrassegno nella barra laterale, invece di interrompere quello che stai
@@ -663,7 +661,7 @@
Modalità demo
Disinstallazione
-
In Acquisizione, scegli Revoca l'accesso all'acquisizione dei pacchetti (chiede la password) se l'avevi attivato,
+
In Origini › Collector, scegli Revoca l'accesso all'acquisizione dei pacchetti (chiede la password) se l'avevi attivato,
disinstalla il filtro di contenuto se l'avevi installato e disattiva l'ispezione HTTPS in Ispeziona così il suo certificato
esce dal portachiavi. Solo Flowlight stesso può ritirare queste tre cose.
Chiudi Flowlight e spostalo da Applicazioni al Cestino — oppure, se l'hai installato con Homebrew,
@@ -682,18 +680,18 @@
Domande e risposte
di macOS una volta al secondo e registra la variazione, quindi un trasferimento lungo è conteggiato con esattezza — ma una connessione che si apre e si
chiude tra due letture non compare affatto. L'estensione di rete viene chiamata da macOS a ogni connessione stabilita, quindi
anche una richiesta di cinque millisecondi viene registrata. Se stai osservando un agente IA che scatena molte richieste brevi, installa
- l'estensione da Acquisizione. Il confronto completo è qui sopra.
+ l'estensione da Origini › Collector. Il confronto completo è qui sopra.
Ho attivato l'estensione di rete e non compare nulla. Il campionatore funziona bene.
Quasi sempre perché un altro filtro di contenuto occupa già il posto. macOS esegue un solo filtro di contenuto alla volta, e
di solito lo rivendica il software di sicurezza aziendale — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e simili. Il filtro di
- Flowlight si installa, si attiva e si connette comunque, quindi Acquisizione dice Connesso all'estensione filtro, ma macOS non gli consegna mai una
- sola connessione e le schermate restano vuote. Acquisizione elenca i filtri che trova e propone di riportarti al
+ Flowlight si installa, si attiva e si connette comunque, quindi Origini › Collector dice Connesso all'estensione filtro, ma macOS non gli consegna mai una
+ sola connessione e le schermate restano vuote. Origini › Collector elenca i filtri che trova e propone di riportarti al
campionatore, che non usa un filtro e convive con loro. Perdi solo le connessioni molto brevi
(il confronto); tutto il resto viene registrato allo stesso modo.
L'estensione ha smesso di funzionare dopo l'aggiornamento di Flowlight.
Le versioni prima della 0.2.5 avevano questo problema: macOS continua a eseguire la build dell'estensione attivata per ultima, quindi dopo un aggiornamento
l'estensione era la versione vecchia e macOS rifiuta la connessione tra una coppia non corrispondente. Dalla 0.2.5 Flowlight controlla all'avvio
- e riattiva il filtro da sé. Su una versione più vecchia, premi una volta Installa e attiva il filtro in Acquisizione.
+ e riattiva il filtro da sé. Su una versione più vecchia, premi una volta Installa e attiva il filtro in Origini › Collector.
C'è qualcos'altro che non va nell'acquisizione e non so cosa.
Esegui questo e leggi cosa stampa — riporta solo stato e conteggi, mai nulla di ciò che Flowlight ha registrato sul tuo traffico:
Vedi il percorso IA reale: agenti, strumenti attribuiti, gateway configurati, lo stadio proxy osservato da Flowlight e le destinazioni esatte. La larghezza mostra il totale ricevuto e inviato nel periodo selezionato. Con dati dimostrativi.
@@ -135,7 +135,7 @@
Vedi la rete delle tue app. Ca
-
La vista Agenti IA: il provider del modello di ogni agente e tutto il resto con cui ha parlato. Mostrata con dati dimostrativi.
@@ -179,13 +179,13 @@
Cronologia
Dove è finito tutto? Dal secondo all'anno, per app, desti
Avvisi
Cosa non tornava? Avvisi per app, spiegati, con la destinazione e la soglia.
⌘5
-
Regole
Cosa ho rifiutato, e sta funzionando? Ogni regola, che cosa ha bloccato e il flusso di tutte le decisioni.
⌘8
+
Regole
Cosa ho rifiutato, e sta funzionando? Ogni regola, che cosa ha bloccato e il flusso di tutte le decisioni.
⌘8 · Developer ID / ⌘7 · App Store
Chiedi
Domande in linguaggio naturale, con risposte tratte dalla cronologia e sotto l'elenco di tutte le query eseguite.
⌘6
-
-
Dispositivi
Bluetooth, USB e fotocamere: che cosa è abbinato, collegato o attivo e quando è cambiato. Disattivato finché non lo attivi.
⌘9
+
+
Origini
I dati stanno arrivando, quanti hanno un nome e quali canali dei dispositivi sono attivi? Collector, Dispositivi e Copertura in un unico posto.
⌘9 · Developer ID / ⌘8 · App Store
-
Ispeziona
Opzionale. Cosa ha inviato davvero l'agente, e quale chiamata a uno strumento l'ha prodotta? Richieste decifrate, chiamate agli strumenti, risultati.
⌘7
+
Ispeziona
Opzionale. Cosa ha inviato davvero l'agente, e quale chiamata a uno strumento l'ha prodotta? Richieste decifrate, chiamate agli strumenti, risultati.
⌘7 · Developer ID
Connessioni
Che cosa comunica? Una mappa Sankey ingrandibile del traffico delle app e dei percorsi comprovati degli agenti IA, con un elenco esatto equivalente.
⌘4
@@ -405,16 +405,16 @@
Collega le chiamate agli strumenti supportate alle richieste di rete
sul tuo Mac. Avvia un agente da un Terminale ispezionato e il traffico HTTP supportato dell'agente e dei suoi strumenti viene decifrato, con le chiamate agli strumenti
richieste dal modello e i risultati tornati indietro.
-
Dove sono finite le mie note? Il caricamento di curl verso paste.example, risalendo al comando Bash richiesto dal modello, con il
corpo che ha inviato.
-
Ogni strumento che un agente offre al modello. Gli agenti dichiarano i loro strumenti a ogni turno, così Flowlight li elenca tutti, indicando
quelli che il modello ha davvero usato e quelli che non ha mai toccato.
-
Compresi quelli che non vedi passare in rete. Quando un agente chiede al provider di collegarsi a un server MCP, quel traffico
non arriva mai al tuo Mac. La sua richiesta sì, così il server, il suo URL, la sua impostazione di approvazione e i suoi strumenti compaiono comunque.
@@ -460,7 +460,7 @@
Un monitoraggio che non devi monitorare
-
Un agente, tutte le chiamate agli strumenti. Il traffico di git, curl e dei server MCP avviati da Claude Code conta come traffico di Claude Code.
Con l'ispezione HTTPS attiva, il pannello Chiamate agli strumenti mostra che cosa ha chiesto il modello, che cosa è tornato indietro e le richieste fatte da ogni strumento:
@@ -470,10 +470,10 @@
Un monitoraggio che non devi monitorare
-
Cronologia. Zoom dal secondo all'anno, tre raggruppamenti, grafici che restano leggibili con centinaia di app.
-
Avvisi. Ognuno indica l'app, la destinazione e il numero che lo ha fatto scattare.
@@ -523,7 +523,7 @@
In funzione in meno di un minuto
linee di base per le anomalie e regole pensate per gli agenti IA. Convivono bene.
Perché mi chiede la password?
macOS permette di leggere i pacchetti di rete solo agli amministratori. La configurazione iniziale dà al tuo account l'accesso in lettura,
- esattamente come fa Wireshark. Puoi revocarlo quando vuoi dalla schermata Acquisizione.
+ esattamente come fa Wireshark. Puoi revocarlo quando vuoi da Origini › Collector.
Può dire quale server MCP o quale strumento ha fatto una richiesta?
Sì, a livello di processo. Flowlight risale da ogni processo all'agente che lo ha avviato, così il curl di uno strumento shell
o le connessioni di un server MCP vengono attribuite a quell'agente, e i server MCP prendono il nome dalle configurazioni di Claude Code, Claude
@@ -589,7 +589,7 @@
strumento di monitoraggio su macOS può impedirlo e restare al tempo stesso uno strumento che puoi spegnere anche tu.
L'affermazione onesta è più stretta e resta utile: il software che si comporta male ma non sta attivamente sfuggendo a un monitoraggio viene
visto. Il software che vi sta attivamente sfuggendo può non essere visto, e lascerà almeno un buco — un'estensione che si è fermata, un periodo
- senza dati — che la schermata Copertura è lì per mostrare.
I servizi di sistema esenti dai filtri di contenuto. macOS non mostra tutto a un filtro di contenuto; una parte del suo
traffico non arriva mai al nostro.
Un altro filtro di contenuto che occupa il posto. macOS ne esegue uno alla volta. Se ce l'ha una VPN o un agente di
- sicurezza, il filtro di Flowlight si installa, si connette e non gli viene mai chiesto di filtrare nulla: Acquisizione lo dice, invece di
+ sicurezza, il filtro di Flowlight si installa, si connette e non gli viene mai chiesto di filtrare nulla: Origini › Collector lo dice, invece di
mostrare una schermata vuota.
Le connessioni brevi, con il campionatore. Senza l'estensione, Flowlight legge i contatori una volta al secondo: una
connessione che si apre e si chiude tra due letture non viene mai registrata.
@@ -150,7 +150,7 @@
Cosa sfugge all'ispezione
L'ispezione HTTPS legge solo ciò che viene instradato attraverso il proxy locale di Flowlight, e questo lo decide un programma quando parte.
Un'app che ignora le impostazioni proxy, una avviata prima che l'ispezione fosse attivata, o una che applica il pinning dei certificati passa
intatta — deliberatamente, perché rompere una connessione con pinning romperebbe l'app. Nemmeno QUIC viene offerto al proxy.
-
Quindi una schermata Ispeziona vuota significa «qui non è stato instradato nulla», non «non è successo nulla». Copertura dice quale delle due
+
Quindi una schermata Ispeziona vuota significa «qui non è stato instradato nulla», non «non è successo nulla». Origini › Copertura dice quale delle due
cose valga, app per app.
ネットワーク所有者を特定をオンにすると、ホスト名のないトラフィックにアドレスの運用者名が付きます
(Cloudflare, Inc. · AS13335)。デフォルトでオンで、そうしたパブリックな IP アドレス(プライベートなものは決して送りません)を
- Team Cymru の DNS サービスに送信します。キャプチャでオフにできます。
+ Team Cymru の DNS サービスに送信します。ソース › コレクターでオフにできます。
커널의 필터가 나머지 패킷을 Flowlight가 보기 전에 버리며, 패킷 내용은 저장하지 않습니다.
macOS는 관리자만 패킷을 읽게 하므로 트래픽에 이름 붙이기 창이 암호를 한 번 묻습니다. 이때
/Library/LaunchDaemons/com.flowlight.bpf-access.plist를 설치하며, 이것이 부팅마다 access_bpf
- 그룹에 /dev/bpf* 읽기 권한을 줍니다. Wireshark와 같은 방식입니다. 캡처 › 패킷 캡처 권한 제거에서 언제든 되돌릴 수 있습니다.
+ 그룹에 /dev/bpf* 읽기 권한을 줍니다. Wireshark와 같은 방식입니다. 소스 › 컬렉터 › 패킷 캡처 권한 제거에서 언제든 되돌릴 수 있습니다.
네트워크 소유자 확인은 호스트 이름이 없는 트래픽에 그 주소를 운영하는 주체의 이름을 붙입니다
(Cloudflare, Inc. · AS13335). 기본값은 켬이며, 그런 공용 IP 주소만(사설 주소는 절대 보내지 않습니다) Team Cymru의
- DNS 서비스로 보냅니다. 캡처에서 끌 수 있습니다.
단축키는 사이드바 순서를 따릅니다. ⌘0은 열 번째 항목이고, 열한 번째 항목은 억지로 키를 만들지 않아도 계속 사용할 수 있습니다.
-
단축키는 보이는 사이드바 순서를 따릅니다. Developer ID 빌드에는 ⌘7의 검사가 있고, App Store 빌드에는 없으므로 규칙과 소스가 ⌘7과 ⌘8로 이동합니다.
+
실시간, Flowlight가 처음 여는 화면.
기록에서 막대에 포인터를 올리면 포인터를 따라다니는 스크롤 가능한 카드에 기여한 앱이 표시됩니다. 막대를 클릭해 확대하지는 않습니다. 행을 두 번 클릭하면 기록을 그 항목으로 좁힐 수 있습니다.
@@ -470,7 +468,7 @@
연결 거부
알림이 무엇을 거부했는지 기록하며, 클릭 한 번으로 목록에 추가하는 이제부터 … 허용이 함께 붙습니다. 에이전트의
다음 시도는 통과합니다.
네트워크 확장이 필요합니다. 연결을 거부한다는 것은 그 경로에 앉아 있다는 뜻인데, nettop 샘플러는 그럴 수
- 없습니다. 캡처는 아무 일도 하지 않는 스위치를 내놓기보다 그렇다고 알려줍니다.
+ 없습니다. 소스 › 컬렉터는 아무 일도 하지 않는 스위치를 내놓기보다 그렇다고 알려줍니다.
목록에 무엇이 적혀 있든 절대 거부하지 않는 것도 있습니다. 로컬 네트워크와 DNS, Apple 기본 서비스, 그리고 Flowlight 자신의
트래픽입니다. 막힌 Mac은 막힌 에이전트보다 나쁜 결과이므로, 애매할 때는 연결을 허용하고 기록합니다. 또한 Flowlight가 멈추면
몇 초 뒤에 적용이 풀립니다. 아무도 볼 수 없는 거부는 거부가 없는 것보다 나쁘고, 그것을 되돌리는 방법은 앱 안에 있기
@@ -502,8 +500,8 @@
에이전트 가드레일: 도구나 서버, 리소스를
이것은 샌드박스가 아닙니다. 거부된 도구는 더 이상 제공되지도, 응답되지도 않습니다. 하지만 셸이 남아 있는
에이전트는 그 도구가 하던 일을 직접 할 수 있습니다. Flowlight는 그것을 기록합니다. 막아 주는 척하지는 않습니다.
-
캡처: 엔진과 소스
-
Flowlight는 캡처에서 고르는 두 가지 방식 중 하나로 트래픽을 기록합니다. 두 방식은 무엇을 놓칠 수 있는지가
+
소스: 컬렉터와 엔진
+
Flowlight는 소스 › 컬렉터에서 고르는 두 가지 방식 중 하나로 트래픽을 기록합니다. 두 방식은 무엇을 놓칠 수 있는지가
다르므로, 어느 쪽에 의지하기 전에 알아 둘 만합니다.
nettop 샘플러(기본값)
네트워크 확장
@@ -528,7 +526,7 @@
캡처: 엔진과 소스
확장 다시 시도로 처음부터 다시 할 수 있습니다.
어떤 Mac에서는 아예 돌지 못합니다. macOS는 콘텐츠 필터를 한 번에 하나만 허용하고, 보통 기업용 보안
소프트웨어가 그 자리를 차지합니다. Palo Alto Networks GlobalProtect, CrowdStrike Falcon 같은 것들이죠. 그런 Mac에서는
- Flowlight의 필터가 설치되고 연결까지 되지만 연결을 단 하나도 건네받지 못합니다. 캡처는 찾아낸 필터를 나열하고, 필터가 필요
+ Flowlight의 필터가 설치되고 연결까지 되지만 연결을 단 하나도 건네받지 못합니다. 소스 › 컬렉터는 찾아낸 필터를 나열하고, 필터가 필요
없고 그것들과 나란히 동작하는 샘플러로 되돌려 주겠다고 제안합니다.
어떻게 만들었는지는 개발자 가이드를 보세요.
@@ -596,7 +594,7 @@
백그라운드에서 실행
숨지 않게 하고, 저장된 위치가 화면 밖인 창(연결이 빠진 디스플레이)은 지금 있는 화면으로 돌아옵니다. 호스트 이름 설정은 첫
실행을 암호 요청으로 맞이하지 않고, 실행 후 조금 뒤에, 그리고 창이 열려 있을 때만 권합니다. 수락하거나 닫을 때까지 다음
실행에 다시 나타납니다.
-
Flowlight를 종료하면 샘플러가 멈춥니다. 네트워크 확장은 멈추지 않습니다. 시스템 확장은 스스로 돌기 때문에, 캡처에서
+
Flowlight를 종료하면 샘플러가 멈춥니다. 네트워크 확장은 멈추지 않습니다. 시스템 확장은 스스로 돌기 때문에, 소스 › 컬렉터에서
비활성화하거나 제거할 때까지 필터는 계속 연결을 살펴봅니다.
OpenTelemetry나 SIEM으로 내보내기
@@ -634,7 +632,7 @@
OpenTelemetry나 SIEM으로 내보내기
내 데이터
모든 것은 ~/Library/Application Support/Flowlight/traffic.sqlite에 있습니다. 초 단위 데이터는 6시간(조절
가능), 분 단위는 14일, 시간 단위는 400일, 일 단위는 무기한, 알림은 90일 보관합니다.
- 캡처 › 모든 데이터 지우기로 삭제합니다.
+ 설정 › 데이터 및 개인 정보 보호 › 모든 데이터 지우기로 삭제합니다.
업데이트
새 버전이 나오면 Flowlight는 하던 일을 끊지 않고 알림과 사이드바 배지로 알려줍니다. 둘 중 무엇을 클릭해도 업데이트 창이
@@ -654,7 +652,7 @@
소스 › 컬렉터에서, 켜 두었다면 패킷 캡처 권한 제거를 고르고(암호를 묻습니다), 설치했다면 콘텐츠
필터를 제거하고, 검사에서 HTTPS 검사를 꺼서 인증서가 키체인에서 빠지게 하세요. 이 세 가지는 Flowlight만
되돌릴 수 있습니다.
Flowlight를 종료하고 응용 프로그램에서 휴지통으로 옮기세요. Homebrew로 설치했다면
@@ -672,19 +670,19 @@
질문과 답
어떤 캡처 엔진을 쓰는지에 따라 다르고, 그 차이는 작지 않습니다. 기본 샘플러는 macOS의 누적 바이트 카운터를 1초에 한 번
읽어 변화를 기록하므로 긴 전송은 정확히 집계되지만, 두 번의 읽기 사이에 열리고 닫힌 연결은 아예 나타나지 않습니다.
네트워크 확장은 연결이 만들어질 때마다 macOS가 호출하므로 5밀리초짜리 요청도 기록됩니다. 짧은 요청을 많이 내는 AI
- 에이전트를 지켜본다면 캡처에서 확장을 설치하세요. 전체 비교는 위에 있습니다.
거의 항상 다른 콘텐츠 필터가 이미 그 자리를 차지했기 때문입니다. macOS는 콘텐츠 필터를 한 번에 하나만
실행합니다. 보통 기업용 보안 소프트웨어가 그 자리를 가져갑니다. Palo Alto Networks GlobalProtect, CrowdStrike
- Falcon 같은 것들이죠. Flowlight의 필터는 설치되고 활성화되고 연결까지 되므로 캡처에는 Connected to filter
- extension이라고 나오지만, macOS가 연결을 단 하나도 건네주지 않아 화면이 비어 있습니다. 캡처는 찾아낸 필터를
+ Falcon 같은 것들이죠. Flowlight의 필터는 설치되고 활성화되고 연결까지 되므로 소스 › 컬렉터에는 Connected to filter
+ extension이라고 나오지만, macOS가 연결을 단 하나도 건네주지 않아 화면이 비어 있습니다. 소스 › 컬렉터는 찾아낸 필터를
나열하고 필터를 쓰지 않으며 그것들과 나란히 동작하는 샘플러로 되돌려 주겠다고 제안합니다. 이때 잃는 것은 아주
짧은 연결뿐이며(비교 표), 나머지는 똑같이 기록됩니다.
Flowlight를 업데이트한 뒤 확장이 동작하지 않습니다.
0.2.5 이전 버전에 있던 문제입니다. macOS는 마지막으로 활성화된 확장 빌드를 계속 실행하므로, 업데이트 뒤에는 확장이 예전
버전이 되고 macOS는 짝이 맞지 않는 둘 사이의 연결을 거부합니다. 0.2.5부터는 Flowlight가 실행할 때 확인해 필터를 스스로
- 다시 활성화합니다. 그보다 낮은 버전이라면 캡처에서 필터 설치 및 활성화를 한 번 누르세요.
-
캡처에 다른 문제가 있는데 무엇인지 모르겠습니다.
+ 다시 활성화합니다. 그보다 낮은 버전이라면 소스 › 컬렉터에서 필터 설치 및 활성화를 한 번 누르세요.
+
소스 › 컬렉터에 다른 문제가 있는데 무엇인지 모르겠습니다.
이것을 실행하고 출력을 읽어 보세요. 상태와 개수만 보고하며, Flowlight가 트래픽에 대해 기록한 내용은 전혀 담기지 않습니다:
실제 AI 경로를 확인하세요. 에이전트, 귀속된 도구, 구성된 게이트웨이, Flowlight가 관측한 프록시 단계와 정확한 목적지를 표시합니다. 리본 너비는 선택한 기간의 수신량과 송신량 합계입니다. 데모 데이터로 표시했습니다.
@@ -135,7 +135,7 @@
앱이 무엇을 하는지 봅니다.
-
AI 에이전트 뷰: 각 에이전트의 모델 제공업체, 그리고 그 밖에 통신한 모든 곳. 데모 데이터로 표시했습니다.
@@ -179,13 +179,13 @@
기록
다 어디로 갔나? 초에서 연까지, 앱·목적지·IP
알림
무엇이 이상했나? 목적지와 임계값까지 밝히는, 설명되는 앱별 알림.
⌘5
-
규칙
무엇을 거부했고, 실제로 막히고 있나? 모든 규칙과 각 규칙이 막은 것, 그리고 모든 판정의 기록.
⌘8
+
규칙
무엇을 거부했고, 실제로 막히고 있나? 모든 규칙과 각 규칙이 막은 것, 그리고 모든 판정의 기록.
⌘8 · Developer ID / ⌘7 · App Store
질문
평소 쓰는 말로 묻고 기록에서 답을 받습니다. 실행된 질의는 아래에 전부 표시됩니다.
⌘6
-
-
기기
Bluetooth, USB, 카메라: 무엇이 페어링, 연결 또는 사용 중이며 언제 바뀌었나. 직접 켜기 전까지는 끔.
⌘9
+
+
소스
데이터가 들어오는지, 이름이 붙은 비율과 활성 기기 채널은 어떤지. 컬렉터, 기기, 포착 범위를 한곳에서 봅니다.
⌘9 · Developer ID / ⌘8 · App Store
-
검사
선택 사항. 에이전트가 실제로 무엇을 보냈고, 어떤 도구 호출이 그렇게 했나? 복호화된 요청, 도구 호출, 결과.
⌘7
+
검사
선택 사항. 에이전트가 실제로 무엇을 보냈고, 어떤 도구 호출이 그렇게 했나? 복호화된 요청, 도구 호출, 결과.
⌘7 · Developer ID
연결
무엇이 통신하나? 앱 트래픽과 입증된 AI 에이전트 경로를 확대 가능한 Sankey 지도와 동일한 내용의 목록으로 보여 줍니다.
⌘4
@@ -405,16 +405,16 @@
도구 호출과 네트워크 요청을 잇습니다
검사 대상인 터미널에서 에이전트를 실행하면 에이전트와 그 도구의 지원되는 HTTP 트래픽이 복호화되고, 모델이 요청한
도구 호출과 되돌아간 결과가 함께 보입니다.
-
내 메모는 어디로 갔나? curl이 paste.example로 올린 업로드를, 모델이 요청한 Bash 명령까지 거슬러
올라가 보낸 본문과 함께.
-
에이전트가 모델에게 내주는 모든 도구. 에이전트는 매 턴마다 도구를 선언하므로 Flowlight는 그것을 전부
나열하고, 모델이 실제로 쓴 것과 한 번도 건드리지 않은 것을 구분해 보여줍니다.
-
회선에서는 보이지 않는 것까지. 에이전트가 제공업체에게 MCP 서버로 연결해 달라고 하면 그 트래픽은
내 Mac을 거치지 않습니다. 하지만 요청은 거치므로 서버와 URL, 승인 설정, 제공하는 도구는 그대로 드러납니다.
@@ -460,7 +460,7 @@
감시하지 않아도 되는 감시 도구
-
에이전트 하나, 도구 호출 전부. Claude Code가 띄운 git과 curl, MCP 서버의 트래픽은 Claude Code의 것으로
집계됩니다. HTTPS 검사를 켜면 도구 호출 탭에서 모델이 무엇을 요청했고 무엇이 돌아왔으며 각 도구가 어떤 요청을
@@ -470,10 +470,10 @@
감시하지 않아도 되는 감시 도구
-
기록. 초에서 연까지의 확대·축소, 세 가지 묶음, 앱이 수백 개여도 읽히는 차트.
-
알림. 하나하나가 앱과 목적지, 그리고 기준을 넘긴 수치를 밝힙니다.
@@ -523,7 +523,7 @@
1분 안에 돌아갑니다
이상 탐지 기준선, 그리고 AI 에이전트를 위해 만든 규칙. 둘을 나란히 써도 잘 맞습니다.
왜 암호를 묻습니까?
macOS는 관리자만 네트워크 패킷을 읽게 합니다. 한 번만 하는 설정으로 내 계정에 읽기 권한을 주는데, Wireshark도
- 같은 방식입니다. 캡처 화면에서 언제든 되돌릴 수 있습니다.
+ 같은 방식입니다. 소스 › 컬렉터에서 언제든 되돌릴 수 있습니다.
어떤 MCP 서버나 도구가 요청을 냈는지 알 수 있습니까?
프로세스 수준에서는 알 수 있습니다. Flowlight는 각 프로세스를 시작한 에이전트까지 거슬러 올라가므로, 셸 도구의
curl이나 MCP 서버의 연결이 그 에이전트에 귀속되고, MCP 서버의 이름은 Claude Code, Claude Desktop, Cursor, Windsurf,
@@ -589,7 +589,7 @@
root 권한을 가진 소프트웨어는 이것을 끌 수 있습
macOS의 어떤 모니터링 도구도 사용자가 스스로 끌 수 있는 도구로 남아 있으면서 그것을 막을 수는 없습니다.
솔직한 주장은 더 좁고, 그래도 쓸모가 있습니다. 나쁘게 행동하지만 감시를 적극적으로 피하지는 않는 소프트웨어는 보입니다. 적극적으로
피하는 소프트웨어는 보이지 않을 수 있고, 적어도 빈자리는 남깁니다. 멈춘 확장, 데이터가 없는 구간 같은 것들이죠.
- 포착 범위 화면은 바로 그것을 보여주기 위해 있습니다.
콘텐츠 필터 적용에서 빠지는 시스템 서비스. macOS는 콘텐츠 필터에 모든 것을 보여주지 않습니다. macOS 자신의
트래픽 가운데 일부는 우리 필터에 결코 닿지 않습니다.
그 자리를 다른 콘텐츠 필터가 차지한 경우. macOS는 한 번에 하나만 돌립니다. VPN이나 보안 에이전트가 그
- 자리를 갖고 있으면 Flowlight의 필터는 설치되고 연결까지 되지만 무엇을 걸러 달라는 요청은 한 번도 받지 못합니다. 캡처는 빈
+ 자리를 갖고 있으면 Flowlight의 필터는 설치되고 연결까지 되지만 무엇을 걸러 달라는 요청은 한 번도 받지 못합니다. 소스 › 컬렉터는 빈
화면을 보여주는 대신 그렇다고 말합니다.
짧은 연결, 샘플러를 쓸 때. 확장이 없으면 Flowlight는 1초에 한 번 카운터를 읽습니다. 두 번의 읽기 사이에
열리고 닫히는 연결은 결코 기록되지 않습니다.
@@ -151,7 +151,7 @@
검사가 놓치는 것
무시하는 앱, 검사를 켜기 전에 시작된 앱, 인증서를 고정하는 앱은 손대지 않고 그대로 통과합니다. 일부러 그렇게 합니다. 고정된 연결을
깨뜨리면 그 앱이 깨지기 때문입니다. QUIC도 프록시에 건네지지 않습니다.
그래서 검사 화면이 비어 있다는 것은 “여기로 아무것도 지나가지 않았다”는 뜻이고, “아무 일도 없었다”는 뜻이 아닙니다. 둘 중
- 어느 쪽인지는 포착 범위가 앱마다 알려줍니다.
+ 어느 쪽인지는 소스 › 포착 범위가 앱마다 알려줍니다.
차단이 무엇이고 무엇이 아닌지
연결을 거부하는 규칙은 보통 네트워크 확장이 그 경로 안에서, 연결이 만들어지기 전에 실행합니다. HTTPS 검사를 거치는 트래픽은
@@ -221,7 +221,7 @@
diff --git a/docs/llms-full.txt b/docs/llms-full.txt
index 17b95e71..18efdd43 100644
--- a/docs/llms-full.txt
+++ b/docs/llms-full.txt
@@ -62,7 +62,7 @@ Documentation
Using Flowlight
- Everything from the first launch to tuning the agent rules. Flowlight 0.17.2, macOS 15 or later.
+ Everything from the first launch to tuning the agent rules. Flowlight 0.17.3, macOS 15 or later.
On this page
@@ -83,7 +83,7 @@ Documentation
Refusing connectionsGuardrails
Sources
- CaptureCoverageDevices
+ CollectorCoverageDevices
Settings and data
Focus modeBackgroundExport
@@ -125,11 +125,11 @@ open build/Build/Products/Release/Flowlight.app
macOS only lets administrators read packets, so the Name Your Traffic window asks for your password once. It installs
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, which gives the access_bpf group read access to
- /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Capture › Remove Packet Capture Access.
+ /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Sources › Collector › Remove Packet Capture Access.
Identify network owners labels traffic with no hostname by who operates the address
(Cloudflare, Inc. · AS13335). It's on by default and sends those public IP addresses (never private ones) to Team Cymru's
- DNS service. Turn it off in Capture.
+ DNS service. Turn it off in Sources › Collector.
Language
@@ -161,17 +161,15 @@ open build/Build/Products/Release/Flowlight.app
Ask⌘6Questions about your own traffic in plain language, answered from the recorded history by a local or a hosted model.
- Inspect⌘7Optional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
+ Inspect⌘7 · Developer IDOptional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
- Rules⌘8Every allowlist and refusal you have set, what each one covers, and what it has actually stopped.
+ Rules⌘8 · Developer ID
+⌘7 · App StoreEvery allowlist and refusal you have set, what each one covers, and what it has actually stopped.
- Devices⌘9Off until you turn it on: camera activity, Bluetooth, USB and external storage.
+ Sources⌘9 · Developer ID
+⌘8 · App StoreCollector health and recovery, hostname coverage, and opt-in camera, Bluetooth, USB and storage activity in three tabs.
- Coverage⌘0What Flowlight cannot account for — per app, whether its traffic was seen, named, and readable.
-
- Capture—Which engine is recording, the extension's state, hostname learning, and where the database lives.
-
- The shortcuts follow the sidebar's visible order: ⌘0 is the tenth item, and an eleventh remains available without an invented key.
+ The shortcuts follow the visible sidebar order. Developer ID builds include Inspect at ⌘7; App Store builds omit Inspect, so Rules and Sources move to ⌘7 and ⌘8.
Live, the screen Flowlight opens on.
In History, choose 15 min, 1h, 6h, 1d, 1w, 1 mo, 6 mo, 1y, or All. Hover-only bars open a cursor-following, scrollable card with the bucket totals and contributing apps; they never change the selected range. The navigator below the chart starts with Nearby context and can switch to All history: drag the brush to pan the selected window, or drag either edge to resize it. Double-click any breakdown row to narrow History to it.
@@ -201,7 +199,7 @@ open build/Build/Products/Release/Flowlight.app
Active while you're awaymoves 1 MB or more in a minute after you stop using the keyboard and mouse15 minutes
- Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Settings › Detection.
+ Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Alerts › Detection.
Tools & MCP servers
@@ -304,7 +302,7 @@ open build/Build/Products/Release/Flowlight.app
Apple's own apps are left out by default. macOS contacts Apple constantly — Software Update, iCloud,
push, time, Maps tiles — on hosts and ports that are new the first time they appear, and listing all of it buries the one
- line worth reading. Turn it off in Settings › Detection › Rules if you want them. Either way the traffic is still
+ line worth reading. Turn it off in Alerts › Detection › Rules if you want them. Either way the traffic is still
recorded, still appears in Live, History and Ask, and is still subject to every rule, guardrail and allowlist: the setting
decides what is listed, never what is allowed.
@@ -378,7 +376,7 @@ open build/Build/Products/Release/Flowlight.app
allow, and everything else is replaced by its length before anything is stored — recorded requests are kept for as long as you set, and Remove Certificate & Recorded Data deletes the certificate, its trust
setting and everything recorded. Inspection is HTTP/1.1 only (Flowlight asks both sides for it) and not available in demo mode.
- Local risk analysis is separate and off by default. In History or Settings › Detection, you can ask
+ Local risk analysis is separate and off by default. In History or Alerts › Detection, you can ask
Apple’s on-device model to review only meaningful, already-recorded decrypted HTTP candidates after capture. It gets a
bounded redacted description — never request or response bodies, header values, cookies, credentials or tool arguments —
and nothing leaves the Mac. The result is a potential-harm hint, not proof of intent: Flowlight never blocks, changes,
@@ -591,7 +589,7 @@ open build/Build/Products/Release/Flowlight.app
to the list in one click. The agent's next attempt goes through.
It needs the Network Extension. Refusing a connection means sitting in its path, which the nettop sampler
- cannot do — Capture will say so rather than offer a switch that does nothing.
+ cannot do — Sources › Collector will say so rather than offer a switch that does nothing.
Some things are never refused, whatever a list says: your local network, DNS, essential Apple system services, and Flowlight's own
traffic. A blocked Mac is a worse outcome than a blocked agent, so where there is doubt the connection is allowed and recorded.
@@ -633,9 +631,11 @@ open build/Build/Products/Release/Flowlight.app
This is not a sandbox. A refused tool stops being offered and stops being answered. An agent that still has a
shell can do by hand what the tool would have done. Flowlight will record that; it does not pretend to prevent it.
- Capture: engines and sources
+ Sources: collector, coverage and devices
+
+ Sources keeps operational setup in one place. Its health summary shows whether traffic is arriving, how much is named, and which optional device channels are active; any unfinished collector step links directly to Sources › Collector.
- Flowlight records traffic one of two ways, chosen in Capture. They differ in what they can miss, which is worth
+ Flowlight records traffic one of two ways, chosen under Sources › Collector. They differ in what they can miss, which is worth
understanding before you rely on either.
nettop sampler (default)Network Extension
@@ -669,13 +669,13 @@ open build/Build/Products/Release/Flowlight.app
It also can't run at all on some Macs. macOS allows one content filter at a time, and corporate security software
normally holds it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and the like. Flowlight's filter will install and connect on those
- machines and then never be handed a connection. Capture lists any it finds and offers to switch you back to the sampler, which
+ machines and then never be handed a connection. Sources › Collector lists any it finds and offers to switch you back to the sampler, which
needs no filter and works alongside them.
See the developer guide for how it's built.
Coverage: what Flowlight can't account for
- Every other screen answers what happened. Coverage answers what you would not have been told, which is what
+ Sources › Coverage answers what you would not have been told, which is what
decides how much the other screens are worth. It asks three questions per app, because they fail independently.
Was it seen? The Network Extension sees each flow as it opens. The nettop sampler reads counters once a
@@ -698,7 +698,7 @@ open build/Build/Products/Release/Flowlight.app
Devices: camera activity, Bluetooth, USB and external storage
- A Mac sends and receives over more than TCP and UDP. The Devices screen covers the rest, with every channel
+ A Mac sends and receives over more than TCP and UDP. Sources › Devices covers the rest, with every channel
off until you turn it on because watching more of your Mac should be your decision rather than something an update did.
Camera activity shows whether each camera is active and records confirmed start and stop transitions.
@@ -761,7 +761,7 @@ open build/Build/Products/Release/Flowlight.app
request for your password; the offer returns next launch until you take or dismiss it.
Quitting Flowlight stops the sampler. It does not stop the Network Extension: a system extension runs on its own, so the filter
- carries on inspecting connections until you disable or uninstall it in Capture.
+ carries on inspecting connections until you disable or uninstall it in Sources › Collector.
Export to OpenTelemetry or a SIEM
@@ -808,7 +808,7 @@ open build/Build/Products/Release/Flowlight.app
Everything lives in ~/Library/Application Support/Flowlight/traffic.sqlite. Per-second rows are kept 6 hours
(adjustable), minute rows 14 days, hourly rows 400 days, daily rows indefinitely, and alerts 90 days.
- Capture › Clear all data deletes it.
+ Settings › Data & Privacy › Clear All Data deletes it.
Updates
@@ -832,7 +832,7 @@ open build/Build/Products/Release/Flowlight.app
Uninstall
- In Capture, choose Remove Packet Capture Access (asks for your password) if you enabled it,
+ In Sources › Collector, choose Remove Packet Capture Access (asks for your password) if you enabled it,
uninstall the content filter if you installed it, and turn HTTPS inspection off in Inspect so its certificate
leaves your keychain. Only Flowlight itself can withdraw those three.
@@ -852,18 +852,18 @@ open build/Build/Products/Release/Flowlight.app
byte counters once a second and records the change, so a long transfer is counted exactly — but a connection that opens and
closes between two readings never appears at all. The Network Extension is called by macOS as each connection is made, so
even a five-millisecond request is recorded. If you're watching an AI agent that fires many short requests, install the
- extension from Capture. The full comparison is above.
+ extension from Sources › Collector. The full comparison is above.
I turned on the Network Extension and nothing appears. The sampler works fine.
Almost always because another content filter already has the slot. macOS runs one content filter at a time, and
corporate security software usually claims it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar. Flowlight's
- filter still installs, activates and connects, so Capture says Connected to filter extension, but macOS never hands it a
- single connection and the screens stay empty. Capture lists the filters it finds and offers to switch you back to
+ filter still installs, activates and connects, so Sources › Collector says Connected to filter extension, but macOS never hands it a
+ single connection and the screens stay empty. Sources › Collector lists the filters it finds and offers to switch you back to
the sampler, which doesn't use a filter and works alongside them. You lose only the very short connections
(the comparison); everything else is recorded the same way.
The extension stopped working after Flowlight updated.
Versions before 0.2.5 had this: macOS keeps running whichever build of the extension was last activated, so after an update the
extension was the old version and macOS refuses the connection between a mismatched pair. From 0.2.5 Flowlight checks at launch
- and re-activates the filter itself. On an older version, press Install & enable filter in Capture once.
+ and re-activates the filter itself. On an older version, press Install & enable filter in Sources › Collector once.
Something else is wrong with capture and I don't know what.
Run this and read what it prints — it reports state and counts only, never anything Flowlight recorded about your traffic:
curl -fsSL https://raw.githubusercontent.com/xinbetween/flowlight/main/scripts/diagnose.sh | zshCopy
@@ -920,7 +920,7 @@ Understand your AI agents.
brew install --cask xinbetween/tap/flowlightCopy
- v0.17.2macOS 15+UniversalGPL-3.0No telemetry
+ v0.17.3macOS 15+UniversalGPL-3.0No telemetry
connectionslive
@@ -1005,19 +1005,19 @@ What looked wrong? Explainable, per-app alerts with the destination and the thre
Rules
What have I refused, and is it happening? Every rule, what each has blocked, and a feed of every decision.
-⌘8
+⌘8 · Developer ID / ⌘7 · App Store
Ask
Questions in plain language, answered from the history — with every query it ran listed underneath.
⌘6
- Devices
-Bluetooth, USB, and cameras: what's paired, what's attached or active, and when that changed. Off until you turn it on.
-⌘9
+ Sources
+Is data arriving, how much is named, and which device channels are active? Collector, Devices and Coverage in one place.
+⌘9 · Developer ID / ⌘8 · App Store
Inspect
Optional. What did the agent actually send, and which tool call made it? Decrypted requests, tool calls, results.
-⌘7
+⌘7 · Developer ID
Connections
What is communicating? A zoomable Sankey map for app traffic and proved AI-agent paths, with exact list parity.
@@ -1355,7 +1355,7 @@ Questions
Why does it ask for my password?
macOS only lets administrators read network packets. The one-time setup gives your account read access, the
- same way Wireshark does. You can remove it any time from the Capture screen.
+ same way Wireshark does. You can remove it any time from Sources › Collector.
Can it tell which MCP server or tool made a request?
@@ -1618,7 +1618,7 @@ Privacy
Reverse DNSYour configured DNS resolverA lookup of an IP address's registered name, when no hostname was seenAs needed, in the sampler capture mode, which is the default until the Network Extension is running. No off switch: without it the sampler cannot name most connections. The Network Extension names them from the traffic itself and does not do this
- Network owner lookupTeam Cymru, over DNSPublic IP addresses with no known hostname. Private and reserved addresses never leave your MacOn by default. Off switch in Capture › Identify network owners
+ Network owner lookupTeam Cymru, over DNSPublic IP addresses with no known hostname. Private and reserved addresses never leave your MacOn by default. Off switch in Sources › Collector › Identify network owners
Ask with a hosted modelThe provider you select: Anthropic, OpenAI, Google Gemini or a compatible endpointYour question and the results returned by the read-only Flowlight queries selected by the model. The traffic database itself is not uploadedOnly when you select a hosted provider and submit a question. The Ask screen shows the transmitted requests
@@ -1628,7 +1628,7 @@ Privacy
Permissions
- Administrator password, once, for packet-capture access. Removable from the Capture screen.
+ Administrator password, once, for packet-capture access. Removable from Sources › Collector.
Notifications, for warnings. Optional.
@@ -1637,7 +1637,7 @@ Privacy
Retention
Per-second data 6 hours (adjustable), minute data 14 days, hourly data 400 days, daily totals indefinitely, alerts 90 days.
- Capture › Clear all data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
+ Settings › Data & Privacy › Clear All Data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
This website
@@ -1664,9 +1664,20 @@ Releases
Downloads, checksums and full notes for each version are on GitHub Releases.
- 0.17.2
+ 0.17.3
November 4, 2026Latest
+ Keep every input in one operational home. Capture, Devices and Coverage are now Collector, Devices and Coverage tabs inside Sources, with a shared health summary and a step-by-step recovery card when traffic is not arriving.
+
+ Tune alerts where their results appear. Detection controls now live beside the alert list under Alerts › Detection, while database retention, location and deletion live in Settings › Data & Privacy.
+
+ Make independent verification genuinely parallel. Project drift, oldest and newest unit suites, the Store product, the site and prospective-merge compatibility are separate jobs; project generation is checked once and Store validation runs once.
+
+ Skip app work for website-only commits. The deny-first classifier routes Swift, Python and workflow CodeQL independently, and stable Review and CodeQL gates preserve one required status even when an analyzer is intentionally skipped.
+
+ 0.17.2
+November 4, 2026
+
Keep filtered evidence unmistakable. An active Focus now stays visible above every destination with its exact scope and one-click editing, while sidebar shortcuts follow the order shown on screen.
Make warning notifications respond immediately. Turning warnings on now requests macOS authorization in the same action, reports whether access is active, not requested, or denied, and opens System Settings when recovery is needed.
@@ -3324,7 +3335,7 @@ Threat model
The honest claim is narrower and still useful: software that is misbehaving but not actively evading a monitor will be seen.
Software that is actively evading one may not be, and will at least leave a gap — an extension that stopped, a period with no
- data — which the Coverage screen is there to show.
+ data — which Sources › Coverage is there to show.
What capture misses
@@ -3335,7 +3346,7 @@ Threat model
own traffic never reaches ours.
Another content filter holding the slot. macOS runs one at a time. If a VPN or a security agent has it,
- Flowlight's filter installs, connects, and is never asked to filter anything — Capture says so rather than showing an empty
+ Flowlight's filter installs, connects, and is never asked to filter anything — Sources › Collector says so rather than showing an empty
screen.
Short connections, on the sampler. Without the extension, Flowlight reads counters once a second: a
@@ -3350,7 +3361,7 @@ Threat model
that ignores proxy settings, one started before inspection was switched on, or one that pins its certificates is passed through
untouched — deliberately, because breaking a pinned connection would break the app. QUIC is not offered to the proxy either.
- So an empty Inspect screen means "nothing was routed here", not "nothing happened". Coverage says which of the two applies,
+ So an empty Inspect screen means "nothing was routed here", not "nothing happened". Sources › Coverage says which of the two applies,
per app.
What blocking is, and isn't
diff --git a/docs/llms.txt b/docs/llms.txt
index f03cca17..96c8b063 100644
--- a/docs/llms.txt
+++ b/docs/llms.txt
@@ -1,6 +1,6 @@
# Flowlight
-> Free, open-source (GPL-3.0) application-aware network monitor for macOS, with focused visibility into AI agents. It attributes observed TCP and UDP activity to the application that made it and records the destination, protocol and byte counts, keeping local history from second to year. Recognized AI agents are listed by name along with the tools and MCP servers they start, under per-agent allowlists. It can also refuse, once asked: a rule blocks an application, a destination or a URL for as long as you specify, and a guardrail withholds a tool from an agent before its model is offered it. Runs on macOS 15 or later; capture is by a sampler or a Network Extension. Current version: 0.17.2.
+> Free, open-source (GPL-3.0) application-aware network monitor for macOS, with focused visibility into AI agents. It attributes observed TCP and UDP activity to the application that made it and records the destination, protocol and byte counts, keeping local history from second to year. Recognized AI agents are listed by name along with the tools and MCP servers they start, under per-agent allowlists. It can also refuse, once asked: a rule blocks an application, a destination or a URL for as long as you specify, and a guardrail withholds a tool from an agent before its model is offered it. Runs on macOS 15 or later; capture is by a sampler or a Network Extension. Current version: 0.17.3.
- [Download Flowlight.dmg](https://github.com/xinbetween/flowlight/releases/latest/download/Flowlight.dmg)
- [Source code](https://github.com/xinbetween/flowlight)
diff --git a/docs/plugins/index.html b/docs/plugins/index.html
index 79654d16..7ef95b0c 100644
--- a/docs/plugins/index.html
+++ b/docs/plugins/index.html
@@ -212,7 +212,7 @@
A standard HTTPS request to the fixed official feed for a publisher-signed catalog. The server sees your IP address, the Flowlight/<version> user agent, and conditional cache validators; it receives no traffic, pack settings, or device identifier
After startup when due and then at most daily while healthy. On by default; off switch and manual Check Now in Rules › Packs
Reverse DNS
Your configured DNS resolver
A lookup of an IP address's registered name, when no hostname was seen
As needed, in the sampler capture mode, which is the default until the Network Extension is running. No off switch: without it the sampler cannot name most connections. The Network Extension names them from the traffic itself and does not do this
-
Network owner lookup
Team Cymru, over DNS
Public IP addresses with no known hostname. Private and reserved addresses never leave your Mac
On by default. Off switch in Capture › Identify network owners
+
Network owner lookup
Team Cymru, over DNS
Public IP addresses with no known hostname. Private and reserved addresses never leave your Mac
On by default. Off switch in Sources › Collector › Identify network owners
Ask with a hosted model
The provider you select: Anthropic, OpenAI, Google Gemini or a compatible endpoint
Your question and the results returned by the read-only Flowlight queries selected by the model. The traffic database itself is not uploaded
Only when you select a hosted provider and submit a question. The Ask screen shows the transmitted requests
Collector export
The OpenTelemetry or HTTP endpoint you configure
The fields shown in Settings › Export, such as traffic rollups and alerts. Authentication headers are stored in Keychain
Only after you configure an endpoint and enable export
Inspected application traffic
The original destination requested by the inspected application
The application's request, forwarded through Flowlight's local proxy after decryption
Only while HTTPS inspection is enabled and the application is routed through the proxy
@@ -141,14 +141,14 @@
Network requests the app makes
Permissions
-
Administrator password, once, for packet-capture access. Removable from the Capture screen.
+
Administrator password, once, for packet-capture access. Removable from Sources › Collector.
Notifications, for warnings. Optional.
Login item, only if you turn on Launch at login.
Retention
Per-second data 6 hours (adjustable), minute data 14 days, hourly data 400 days, daily totals indefinitely, alerts 90 days.
- Capture › Clear all data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
+ Settings › Data & Privacy › Clear All Data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
This website
This site is a static page hosted on GitHub Pages and served through Cloudflare. It sets no cookies and runs no analytics. GitHub
@@ -196,7 +196,7 @@
Um filtro no núcleo descarta todos os outros pacotes antes de o Flowlight os ver, e o conteúdo dos pacotes nunca é guardado.
O macOS só permite que os administradores leiam pacotes, por isso a janela Dê nome ao seu tráfego pede a sua palavra-passe uma vez. Instala o
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, que dá ao grupo access_bpf acesso de leitura a
- /dev/bpf* em cada arranque, a mesma abordagem que o Wireshark usa. Remova-o quando quiser em Captura › Remover o acesso à captura de pacotes.
+ /dev/bpf* em cada arranque, a mesma abordagem que o Wireshark usa. Remova-o quando quiser em Origens › Coletor › Remover o acesso à captura de pacotes.
Identificar os proprietários da rede etiqueta o tráfego sem nome de anfitrião com quem opera o endereço
(Cloudflare, Inc. · AS13335). Está ativado por predefinição e envia esses endereços IP públicos (nunca os privados) para o serviço
- DNS da Team Cymru. Desative-o em Captura.
+ DNS da Team Cymru. Desative-o em Origens › Coletor.
Idioma
O Flowlight está traduzido em inglês, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español e
@@ -168,15 +168,13 @@
As vistas
Histórico
⌘3
Para onde foi o tráfego, do segundo ao ano. Agrupe por App, Destino ou IP; mude para Gráficos ou Vale a pena ver; exporte em CSV.
Um mapa estável das aplicações e dos destinos exatos, com caminhos ponderados, marcadores de direção em movimento, contagens de ligações e uma lista equivalente.
Opcional: pedidos desencriptados dos agentes que encaminha pelo Flowlight e as chamadas de ferramentas por trás deles. A pesquisa entra nos corpos dos pedidos e das respostas.
Opcional: pedidos desencriptados dos agentes que encaminha pelo Flowlight e as chamadas de ferramentas por trás deles. A pesquisa entra nos corpos dos pedidos e das respostas.
Estado do coletor, canais de dispositivos e cobertura de nomes em três separadores.
-
Os atalhos seguem a ordem da barra lateral: ⌘0 é o décimo item e o décimo primeiro continua disponível sem inventar uma tecla.
-
Os atalhos seguem a ordem visível da barra lateral. As versões Developer ID incluem Inspecionar em ⌘7; as versões App Store omitem-no, por isso Regras e Origens passam para ⌘7 e ⌘8.
+
Em direto, a vista com que o Flowlight abre.
Em Histórico, passe o rato sobre uma barra para abrir um cartão deslocável que segue o ponteiro e mostra as apps que contribuíram; as barras não ampliam ao clicar. Faça duplo clique numa linha para restringir o histórico a essa linha.
@@ -477,7 +475,7 @@
Recusar ligações
vai recusar: a ligação é cortada e um alerta regista o que foi recusado, com Permitir … de agora em diante para o acrescentar
à lista num clique. A tentativa seguinte do agente passa.
Precisa da extensão de rede. Recusar uma ligação significa estar no seu caminho, o que o amostrador nettop
- não consegue fazer — a Captura di-lo, em vez de oferecer um interruptor que não faz nada.
+ não consegue fazer — Origens › Coletor di-lo, em vez de oferecer um interruptor que não faz nada.
Algumas coisas nunca são recusadas, diga a lista o que disser: a sua rede local, o DNS, os serviços da Apple e o tráfego do próprio
Flowlight. Um Mac bloqueado é um resultado pior do que um agente bloqueado, por isso, na dúvida, a ligação é permitida e registada.
A aplicação efetiva também caduca uns segundos depois de o Flowlight deixar de correr — uma recusa que ninguém consegue ver é pior do que nenhuma, e a maneira
@@ -509,8 +507,8 @@
Proteções dos agentes: bloquear uma ferramenta, um servido
Isto não é uma sandbox. Uma ferramenta recusada deixa de ser oferecida e deixa de ser respondida. Um agente que ainda tenha uma
shell pode fazer à mão o que a ferramenta teria feito. O Flowlight vai registá-lo; não finge impedi-lo.
-
Captura: motores e origens
-
O Flowlight regista o tráfego de uma de duas formas, escolhida em Captura. Diferem no que podem deixar escapar, e vale a pena
+
Origens: coletor e motores
+
O Flowlight regista o tráfego de uma de duas formas, escolhida em Origens › Coletor. Diferem no que podem deixar escapar, e vale a pena
entender isso antes de confiar numa delas.
amostrador nettop (predefinição)
extensão de rede
@@ -536,7 +534,7 @@
Captura: motores e origens
e deixando a sua origem escolhida em paz. Tentar a extensão de novo, em Extensão de rede, começa do início.
Também há Macs onde não consegue correr de forma alguma. O macOS permite um filtro de conteúdo de cada vez, e o software de segurança das
empresas normalmente ocupa-o — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e semelhantes. O filtro do Flowlight instala-se e liga-se nessas
- máquinas, mas nunca lhe é entregue uma ligação. A Captura lista os que encontrar e propõe voltar ao amostrador, que
+ máquinas, mas nunca lhe é entregue uma ligação. O Coletor em Origens lista os que encontrar e propõe voltar ao amostrador, que
não precisa de filtro e funciona ao lado deles.
Veja o guia de desenvolvimento para saber como é construído.
@@ -604,7 +602,7 @@
Executar em segundo plano
tem. A configuração dos nomes de anfitrião é proposta um pouco depois da abertura e só enquanto uma janela está aberta, em vez de receber uma primeira execução com um
pedido de palavra-passe; a proposta volta na abertura seguinte até a aceitar ou a rejeitar.
Sair do Flowlight interrompe o amostrador. Não interrompe a extensão de rede: uma extensão de sistema corre por si, por isso o filtro
- continua a inspecionar ligações até a desativar ou desinstalar em Captura.
+ continua a inspecionar ligações até a desativar ou desinstalar em Origens › Coletor.
Exportar para OpenTelemetry ou para um SIEM
Desativado até o configurar, e não existe nenhum serviço Flowlight para onde enviar. É você que nomeia o endpoint — o seu
@@ -640,7 +638,7 @@
Exportar para OpenTelemetry ou para um SIEM
Os seus dados
Tudo fica em ~/Library/Application Support/Flowlight/traffic.sqlite. As linhas por segundo são mantidas 6 horas
(ajustável), as por minuto 14 dias, as horárias 400 dias, as diárias indefinidamente, e os alertas 90 dias.
- Captura › Apagar todos os dados elimina tudo.
+ Definições › Dados e privacidade › Apagar todos os dados elimina tudo.
Atualizações
Quando aparece uma versão nova, o Flowlight avisa-o com uma notificação e um sinal na barra lateral, em vez de interromper o que está a
@@ -659,7 +657,7 @@
Modo de demonstração
Desinstalação
-
Em Captura, escolha Remover o acesso à captura de pacotes (pede a sua palavra-passe) se o tiver ativado,
+
Em Origens › Coletor, escolha Remover o acesso à captura de pacotes (pede a sua palavra-passe) se o tiver ativado,
desinstale o filtro de conteúdo se o tiver instalado, e desative a inspeção HTTPS em Inspecionar para que o seu certificado
saia do porta-chaves. Só o próprio Flowlight pode retirar essas três coisas.
Saia do Flowlight e mova-o da pasta Aplicações para o Lixo — ou, se o instalou com o Homebrew,
@@ -678,18 +676,18 @@
Perguntas e respostas
acumulados do macOS uma vez por segundo e regista a variação, por isso uma transferência longa é contada com exatidão — mas uma ligação que abre e
fecha entre duas leituras nunca aparece. A extensão de rede é chamada pelo macOS a cada ligação que é feita, por isso
até um pedido de cinco milissegundos é registado. Se está a vigiar um agente de IA que dispara muitos pedidos curtos, instale a
- extensão em Captura. A comparação completa está acima.
+ extensão em Origens › Coletor. A comparação completa está acima.
Ativei a extensão de rede e não aparece nada. O amostrador funciona bem.
Quase sempre porque outro filtro de conteúdo já ocupa o lugar. O macOS executa um filtro de conteúdo de cada vez, e o
software de segurança das empresas normalmente reclama-o — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e semelhantes. O filtro do Flowlight
- instala-se, ativa-se e liga-se, por isso a Captura diz Ligado à extensão de filtro, mas o macOS nunca lhe entrega uma
- única ligação e os ecrãs ficam vazios. A Captura lista os filtros que encontra e propõe voltar ao
+ instala-se, ativa-se e liga-se, por isso Origens › Coletor diz Ligado à extensão de filtro, mas o macOS nunca lhe entrega uma
+ única ligação e os ecrãs ficam vazios. O Coletor em Origens lista os filtros que encontra e propõe voltar ao
amostrador, que não usa filtro e funciona ao lado deles. Perde apenas as ligações muito curtas
(a comparação); todo o resto é registado da mesma maneira.
A extensão deixou de funcionar depois de o Flowlight se atualizar.
As versões anteriores à 0.2.5 tinham isto: o macOS continua a executar a versão da extensão que foi ativada por último, por isso, depois de uma atualização, a
extensão era a versão antiga e o macOS recusa a ligação entre um par que não corresponde. A partir da 0.2.5, o Flowlight verifica na abertura
- e volta a ativar o filtro sozinho. Numa versão mais antiga, prima Instalar e ativar o filtro na Captura uma vez.
+ e volta a ativar o filtro sozinho. Numa versão mais antiga, prima Instalar e ativar o filtro em Origens › Coletor uma vez.
Há outra coisa errada com a captura e não sei o que é.
Execute isto e leia o que imprime — comunica apenas estados e contagens, nunca nada do que o Flowlight registou sobre o seu tráfego:
diff --git a/docs/pt-PT/index.html b/docs/pt-PT/index.html
index 80504841..b220806e 100644
--- a/docs/pt-PT/index.html
+++ b/docs/pt-PT/index.html
@@ -48,7 +48,7 @@
-
+
Ir para o conteúdo
@@ -97,7 +97,7 @@
Veja a atividade de rede das suas apps.
brew install --cask xinbetween/tap/flowlight
-
v0.17.2macOS 15+UniversalGPL-3.0Sem telemetria
+
v0.17.3macOS 15+UniversalGPL-3.0Sem telemetria
@@ -127,7 +127,7 @@
Veja a atividade de rede das suas apps.
-
Veja a rota de IA real: agentes, ferramentas atribuídas, gateways configurados, a etapa de proxy observada pelo Flowlight e destinos exatos. A largura mostra o total recebido e enviado no período selecionado. Com dados de demonstração.
@@ -135,7 +135,7 @@
Veja a atividade de rede das suas apps.
-
A vista Agentes de IA: o fornecedor do modelo de cada agente e tudo o mais com que falou. Mostrada com dados de demonstração.
@@ -179,13 +179,13 @@
Histórico
Para onde foi tudo? Do segundo ao ano, agrupado por app, d
Alertas
O que pareceu errado? Alertas por app, explicáveis, com o destino e o limiar.
⌘5
-
Regras
O que recusei e está a acontecer? Todas as regras, o que cada uma bloqueou e um fluxo de todas as decisões.
⌘8
+
Regras
O que recusei e está a acontecer? Todas as regras, o que cada uma bloqueou e um fluxo de todas as decisões.
⌘8 · Developer ID / ⌘7 · App Store
Perguntar
Perguntas em linguagem comum, respondidas a partir do histórico — com todas as consultas que fez listadas abaixo.
⌘6
-
-
Dispositivos
Bluetooth, USB e câmaras: o que está emparelhado, ligado ou ativo e quando isso mudou. Desativado até o ativar.
⌘9
+
+
Origens
Os dados estão a chegar, quanto está identificado e que canais de dispositivos estão ativos? Coletor, Dispositivos e Cobertura num só lugar.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspecionar
Opcional. O que é que o agente enviou de facto, e que chamada de ferramenta o fez? Pedidos desencriptados, chamadas de ferramentas, resultados.
⌘7
+
Inspecionar
Opcional. O que é que o agente enviou de facto, e que chamada de ferramenta o fez? Pedidos desencriptados, chamadas de ferramentas, resultados.
⌘7 · Developer ID
Ligações
O que está a comunicar? Um mapa Sankey ampliável do tráfego das apps e dos percursos comprovados dos agentes de IA, com uma lista exata equivalente.
⌘4
@@ -405,16 +405,16 @@
Relacione as chamadas de ferramentas suportadas com os pedidos de rede
seu Mac. Inicie um agente a partir de um Terminal inspecionado e o tráfego HTTP suportado do agente e das suas ferramentas é desencriptado, com as chamadas de ferramentas que o
modelo pediu e os resultados que voltaram.
-
Para onde foram as minhas notas? O envio do curl para paste.example, seguido até ao comando Bash que o modelo pediu, com o
corpo que enviou.
-
Todas as ferramentas que um agente oferece ao modelo. Os agentes declaram as suas ferramentas em cada turno, por isso o Flowlight lista-as todas, com as
que o modelo usou de facto e as que nunca tocou.
-
Incluindo as que não se veem na rede. Quando um agente pede ao fornecedor que se ligue a um servidor MCP, esse tráfego
nunca passa pelo seu Mac. O pedido passa, por isso o servidor, o seu URL, a sua definição de aprovação e as suas ferramentas aparecem mesmo assim.
@@ -460,7 +460,7 @@
Um monitor que não tem de monitorizar
-
Um agente, todas as chamadas de ferramentas. O tráfego do git, do curl e dos servidores MCP que o Claude Code iniciou conta como tráfego do Claude Code.
Com a inspeção HTTPS ativada, o separador Chamadas de ferramentas mostra o que o modelo pediu, o que voltou e os pedidos que cada ferramenta fez:
@@ -470,10 +470,10 @@
Um monitor que não tem de monitorizar
-
Histórico. Zoom do segundo ao ano, três agrupamentos, gráficos que continuam legíveis com centenas de apps.
-
Alertas. Cada um nomeia a app, o destino e o número que o disparou.
@@ -523,7 +523,7 @@
A funcionar em menos de um minuto
linhas de base para anomalias e regras feitas para agentes de IA. Funcionam bem lado a lado.
Porque é que pede a minha palavra-passe?
O macOS só permite que os administradores leiam pacotes de rede. A configuração inicial dá acesso de leitura à sua conta, da
- mesma forma que o Wireshark faz. Pode removê-lo quando quiser no ecrã Captura.
+ mesma forma que o Wireshark faz. Pode removê-lo quando quiser em Origens › Coletor.
Consegue dizer que servidor MCP ou que ferramenta fez um pedido?
Sim, ao nível do processo. O Flowlight segue cada processo até ao agente que o iniciou, pelo que o curl de uma ferramenta de shell
ou as ligações de um servidor MCP são atribuídos a esse agente, e os servidores MCP recebem o nome das configurações do Claude Code, Claude
@@ -589,7 +589,7 @@
nenhuma ferramenta de monitorização no macOS o consegue impedir e continuar a ser uma ferramenta que também você pode desligar.
A afirmação honesta é mais estreita e continua a ser útil: o software que se porta mal mas não está ativamente a fugir a um monitor será
visto. O software que lhe está ativamente a fugir pode não ser, e deixará pelo menos uma falha — uma extensão que parou, um período sem
- dados — que o ecrã Cobertura está lá para mostrar.
Os serviços de sistema isentos dos filtros de conteúdo. O macOS não mostra tudo a um filtro de conteúdo; parte do seu
próprio tráfego nunca chega ao nosso.
Outro filtro de conteúdo a ocupar o lugar. O macOS executa um de cada vez. Se uma VPN ou um agente de segurança o
- tiver, o filtro do Flowlight instala-se, liga-se, e nunca lhe é pedido que filtre nada — a Captura di-lo, em vez de mostrar um ecrã
+ tiver, o filtro do Flowlight instala-se, liga-se, e nunca lhe é pedido que filtre nada — Origens › Coletor di-lo, em vez de mostrar um ecrã
vazio.
As ligações curtas, com o amostrador. Sem a extensão, o Flowlight lê contadores uma vez por segundo: uma ligação que
abre e fecha entre duas leituras nunca é registada.
@@ -150,7 +150,7 @@
O que escapa à inspeção
A inspeção HTTPS lê apenas o que é encaminhado pelo proxy local do Flowlight, e isso é um programa que o decide quando arranca. Uma app que
ignora as definições de proxy, uma que foi iniciada antes de a inspeção ser ligada, ou uma que fixa os seus certificados passa intacta — de
propósito, porque quebrar uma ligação com o certificado fixado quebraria a app. O QUIC também não é entregue ao proxy.
-
Por isso um ecrã Inspecionar vazio significa «não foi encaminhado nada para aqui», não «não aconteceu nada». A Cobertura diz qual das duas
+
Por isso um ecrã Inspecionar vazio significa «não foi encaminhado nada para aqui», não «não aconteceu nada». Origens › Cobertura diz qual das duas
coisas se aplica, app por app.
Keep every input in one operational home. Capture, Devices and Coverage are now Collector, Devices and Coverage tabs inside Sources, with a shared health summary and a step-by-step recovery card when traffic is not arriving.
+
Tune alerts where their results appear. Detection controls now live beside the alert list under Alerts › Detection, while database retention, location and deletion live in Settings › Data & Privacy.
+
Make independent verification genuinely parallel. Project drift, oldest and newest unit suites, the Store product, the site and prospective-merge compatibility are separate jobs; project generation is checked once and Store validation runs once.
+
Skip app work for website-only commits. The deny-first classifier routes Swift, Python and workflow CodeQL independently, and stable Review and CodeQL gates preserve one required status even when an analyzer is intentionally skipped.
+
+
+
+
+
0.17.2
Keep filtered evidence unmistakable. An active Focus now stays visible above every destination with its exact scope and one-click editing, while sidebar shortcuts follow the order shown on screen.
Make warning notifications respond immediately. Turning warnings on now requests macOS authorization in the same action, reports whether access is active, not requested, or denied, and opens System Settings when recovery is needed.
monitoring tool on macOS can prevent it while remaining a tool you can also turn off yourself.
The honest claim is narrower and still useful: software that is misbehaving but not actively evading a monitor will be seen.
Software that is actively evading one may not be, and will at least leave a gap — an extension that stopped, a period with no
- data — which the Coverage screen is there to show.
System services exempt from content filters. macOS does not show a content filter everything; some of its
own traffic never reaches ours.
Another content filter holding the slot. macOS runs one at a time. If a VPN or a security agent has it,
- Flowlight's filter installs, connects, and is never asked to filter anything — Capture says so rather than showing an empty
+ Flowlight's filter installs, connects, and is never asked to filter anything — Sources › Collector says so rather than showing an empty
screen.
Short connections, on the sampler. Without the extension, Flowlight reads counters once a second: a
connection that opens and closes between two readings is never recorded.
@@ -150,7 +150,7 @@
What inspection misses
HTTPS inspection reads only what is routed through Flowlight's local proxy, and a program decides that when it starts. An app
that ignores proxy settings, one started before inspection was switched on, or one that pins its certificates is passed through
untouched — deliberately, because breaking a pinned connection would break the app. QUIC is not offered to the proxy either.
-
So an empty Inspect screen means "nothing was routed here", not "nothing happened". Coverage says which of the two applies,
+
So an empty Inspect screen means "nothing was routed here", not "nothing happened". Sources › Coverage says which of the two applies,
per app.
]")
TITLE = re.compile(r"([^<]+)", re.I)
META = re.compile(r']+>", " ", cell)
+ text = " ".join(text.split())
+ return [label for label in required if label not in text]
+
+
def problems():
found = []
@@ -257,10 +282,10 @@ def entries(text):
found.append(f"docs/docs/index.html: no #{anchor} section, but the {screen} screen's Help "
f"button opens it — a new screen the documentation never got")
- # 12. A shortcut the documentation gets wrong. The sidebar's order *is* the shortcut — ⌘1 to ⌘0 by
- # position — so inserting a screen silently renumbers every screen after it. The table said Inspect was
- # ⌘5 long after it had become ⌘7, and four screens had been added without ever reaching the table.
+ # 12. A shortcut the documentation gets wrong. Shortcuts follow each product's visible sidebar. Developer ID
+ # includes Inspect; the Store product does not, so Rules and Sources move up by one there.
order = sidebar_order(nav)
+ requirements = shortcut_requirements(order)
titles = dict(HELP_ANCHOR.findall(nav[nav.find("var englishTitle"):nav.find("var title")]))
docs_text = (OUT / "docs/index.html").read_text()
rows = {name.strip(): key for name, key in ROW.findall(docs_text)}
@@ -274,21 +299,41 @@ def entries(text):
found.append(f"docs/docs/index.html: the views table gives {title} \u2318{rows[title]}, "
f"but the sidebar puts it at \u2318{key}")
- # 14. The homepage repeats the same shortcut badges and a compact Devices promise. Both drifted in 0.15.12:
- # Ask and Inspect were swapped, and camera activity shipped without ever reaching the landing-page card.
+ docs_pages = [OUT / "docs/index.html"] + [OUT / lang / "docs/index.html" for lang in LANGS]
+ shortcut_anchors = {
+ "inspect": ("inspection",),
+ "rules": ("rules",),
+ "sources": ("capture", "sources"),
+ }
+ for docs_page in docs_pages:
+ page_text = docs_page.read_text()
+ for screen, anchors in shortcut_anchors.items():
+ anchor_pattern = "|".join(re.escape(anchor) for anchor in anchors)
+ cell_match = re.search(
+ rf'
Ein Filter im Kernel verwirft jedes andere Paket, bevor Flowlight es sieht, und Paketinhalte werden nie gespeichert.
macOS lässt nur Administratoren Pakete lesen, deshalb fragt das Fenster Deinem Datenverkehr Namen geben einmal nach deinem Passwort. Es installiert
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, das der Gruppe access_bpf bei jedem Start Lesezugriff auf
- /dev/bpf* gibt – derselbe Weg, den Wireshark geht. Jederzeit entfernbar über Erfassung › Paketmitschnitt-Zugriff entfernen.
+ /dev/bpf* gibt – derselbe Weg, den Wireshark geht. Jederzeit entfernbar über Quellen › Collector › Paketmitschnitt-Zugriff entfernen.
Netzinhaber bestimmen beschriftet Datenverkehr ohne Hostnamen damit, wer die Adresse betreibt
(Cloudflare, Inc. · AS13335). Es ist standardmäßig ein und sendet diese öffentlichen IP-Adressen (nie private) an den
- DNS-Dienst von Team Cymru. Abschalten kannst du es unter Erfassung.
+ DNS-Dienst von Team Cymru. Abschalten kannst du es unter Quellen › Collector.
Sprache
Flowlight ist übersetzt in English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español und
@@ -99,14 +99,12 @@
Die Ansichten
Verlauf
⌘3
Wohin der Datenverkehr ging, von der Sekunde bis zum Jahr. Gruppiert nach App, Ziel oder IP; umschaltbar auf Diagramme oder Genauer hinsehen; CSV-Export.
Eine stabile Karte der Apps und ihrer genauen Ziele mit gewichteten Pfaden, bewegten Richtungsmarkern, Verbindungszahlen und einer gleichwertigen Liste.
Fragen zu deinem eigenen Datenverkehr in normaler Sprache, beantwortet aus der aufgezeichneten Historie von einem lokalen oder einem gehosteten Modell.
Optional: entschlüsselte Anfragen der Agenten, die du über Flowlight leitest, und die Tool-Aufrufe dahinter. Die Suche reicht in Anfrage- und Antwort-Bodys hinein.
Optional: entschlüsselte Anfragen der Agenten, die du über Flowlight leitest, und die Tool-Aufrufe dahinter. Die Suche reicht in Anfrage- und Antwort-Bodys hinein.
Collector-Zustand, Gerätekanäle und Benennungsabdeckung in drei Tabs.
-
Die Kurzbefehle folgen der Reihenfolge der Seitenleiste: ⌘0 ist das zehnte Element, und das elfte bleibt ohne einen erfundenen Kurzbefehl erreichbar.
+
Die Kurzbefehle folgen der sichtbaren Reihenfolge der Seitenleiste. Developer-ID-Versionen enthalten Inspizieren auf ⌘7; App-Store-Versionen lassen es weg, daher rücken Regeln und Quellen auf ⌘7 und ⌘8.
Live, der Bildschirm, mit dem Flowlight startet.
@@ -410,7 +408,7 @@
Verbindungen verweigern
verweigert: Die Verbindung wird verworfen, und eine Warnung hält fest, was verweigert wurde – mit … ab jetzt erlauben, um es
mit einem Klick in die Liste aufzunehmen. Der nächste Versuch des Agenten geht durch.
Es braucht die Netzwerkerweiterung. Eine Verbindung zu verweigern heißt, in ihrem Weg zu sitzen, und das kann der nettop-Sampler
- nicht – Erfassung sagt das, statt einen Schalter anzubieten, der nichts tut.
+ nicht – Quellen › Collector sagt das, statt einen Schalter anzubieten, der nichts tut.
Manches wird nie verweigert, was auch in einer Liste steht: dein lokales Netzwerk, DNS, Apples eigene Dienste und Flowlights eigener
Datenverkehr. Ein blockierter Mac ist schlimmer als ein blockierter Agent, im Zweifel wird die Verbindung also erlaubt und aufgezeichnet.
Die Durchsetzung endet außerdem wenige Sekunden nachdem Flowlight nicht mehr läuft – eine Verweigerung, die niemand sehen kann, ist schlimmer als keine, und der Weg,
@@ -442,8 +440,8 @@
Schutzregeln für Agenten: ein Tool, einen Server oder eine
Das ist keine Sandbox. Ein verweigertes Tool wird nicht mehr angeboten und nicht mehr beantwortet. Ein Agent, der noch eine
Shell hat, kann von Hand tun, was das Tool getan hätte. Flowlight zeichnet das auf; es tut nicht so, als würde es das verhindern.
-
Erfassung: Engines und Quellen
-
Flowlight zeichnet Datenverkehr auf eine von zwei Weisen auf, wählbar unter Erfassung. Sie unterscheiden sich darin, was sie verpassen können, und das lohnt
+
Quellen: Collector und Engines
+
Flowlight zeichnet Datenverkehr auf eine von zwei Weisen auf, wählbar unter Quellen › Collector. Sie unterscheiden sich darin, was sie verpassen können, und das lohnt
sich zu verstehen, bevor du dich auf eine verlässt.
nettop-Sampler (Standard)
Netzwerkerweiterung
@@ -469,7 +467,7 @@
Erfassung: Engines und Quellen
ohne deine gewählte Quelle zu verändern. Erweiterung erneut versuchen unter Netzwerkerweiterung fängt von vorn an.
Auf manchen Macs kann sie gar nicht laufen. macOS erlaubt nur einen Inhaltsfilter zur Zeit, und normalerweise hält Sicherheitssoftware
aus dem Unternehmen ihn – Palo Alto Networks GlobalProtect, CrowdStrike Falcon und dergleichen. Flowlights Filter installiert sich auf diesen
- Rechnern und verbindet sich auch, bekommt dann aber nie eine Verbindung übergeben. Erfassung listet jeden Filter auf, den es findet, und bietet an, zurück auf den Sampler zu schalten, der
+ Rechnern und verbindet sich auch, bekommt dann aber nie eine Verbindung übergeben. Quellen › Collector listet jeden Filter auf, den es findet, und bietet an, zurück auf den Sampler zu schalten, der
keinen Filter braucht und neben ihnen funktioniert.
Wie es gebaut ist, steht im Entwicklerhandbuch.
@@ -538,7 +536,7 @@
Im Hintergrund laufen
hast. Die Hostnamen-Einrichtung wird etwas nach dem Start angeboten und nur, solange ein Fenster offen ist, statt einen ersten Start mit einer
Passwortfrage zu begrüßen; das Angebot kommt beim nächsten Start wieder, bis du es annimmst oder wegklickst.
Flowlight zu beenden stoppt den Sampler. Es stoppt nicht die Netzwerkerweiterung: Eine Systemerweiterung läuft für sich, der Filter
- prüft Verbindungen also weiter, bis du ihn unter Erfassung deaktivierst oder deinstallierst.
+ prüft Verbindungen also weiter, bis du ihn unter Quellen › Collector deaktivierst oder deinstallierst.
Export an OpenTelemetry oder ein SIEM
Aus, bis du es einrichtest – und es gibt keinen Flowlight-Dienst, an den gesendet würde. Du nennst den Endpunkt – deinen eigenen
@@ -578,7 +576,7 @@
Export an OpenTelemetry oder ein SIEM
Deine Daten
Alles liegt in ~/Library/Application Support/Flowlight/traffic.sqlite. Sekundenzeilen werden 6 Stunden aufbewahrt
(einstellbar), Minutenzeilen 14 Tage, Stundenzeilen 400 Tage, Tageszeilen dauerhaft und Warnungen 90 Tage.
- Erfassung › Alle Daten löschen löscht sie.
Erscheint eine neue Version, sagt Flowlight es mit einer Benachrichtigung und einem Zeichen in der Seitenleiste, statt dich zu unterbrechen;
@@ -597,7 +595,7 @@
Demomodus
Deinstallieren
-
Wähle unter Erfassung den Punkt Paketmitschnitt-Zugriff entfernen (fragt nach deinem Passwort), falls du ihn eingerichtet hast,
+
Wähle unter Quellen › Collector den Punkt Paketmitschnitt-Zugriff entfernen (fragt nach deinem Passwort), falls du ihn eingerichtet hast,
deinstalliere den Inhaltsfilter, falls du ihn installiert hast, und schalte die HTTPS-Inspektion unter Inspizieren aus, damit ihr Zertifikat
deinen Schlüsselbund verlässt. Nur Flowlight selbst kann diese drei zurücknehmen.
Beende Flowlight und lege es aus dem Programme-Ordner in den Papierkorb – oder, wenn du es mit Homebrew installiert hast,
@@ -616,19 +614,19 @@
Fragen & Antworten
Byte-Zähler von macOS einmal pro Sekunde und zeichnet die Veränderung auf – eine lange Übertragung wird also exakt gezählt, aber eine Verbindung, die zwischen
zwei Messungen öffnet und schließt, erscheint überhaupt nicht. Die Netzwerkerweiterung wird von macOS bei jedem Verbindungsaufbau aufgerufen, sodass
selbst eine Anfrage von fünf Millisekunden aufgezeichnet wird. Wenn du einen KI-Agenten beobachtest, der viele kurze Anfragen abfeuert, installiere die
- Erweiterung unter Erfassung. Der vollständige Vergleich steht oben.
+ Erweiterung unter Quellen › Collector. Der vollständige Vergleich steht oben.
Ich habe die Netzwerkerweiterung eingeschaltet und es erscheint nichts. Der Sampler läuft gut.
Fast immer, weil ein anderer Inhaltsfilter den Platz schon hat. macOS führt einen Inhaltsfilter zur Zeit aus, und
Sicherheitssoftware aus dem Unternehmen beansprucht ihn meist – Palo Alto Networks GlobalProtect, CrowdStrike Falcon und Ähnliches. Flowlights
- Filter installiert, aktiviert und verbindet sich trotzdem, Erfassung sagt also Mit Filtererweiterung verbunden, aber macOS übergibt ihm nie eine
- einzige Verbindung und die Bildschirme bleiben leer. Erfassung listet die Filter auf, die es findet, und bietet an, zurück auf den
+ Filter installiert, aktiviert und verbindet sich trotzdem, Quellen › Collector sagt also Mit Filtererweiterung verbunden, aber macOS übergibt ihm nie eine
+ einzige Verbindung und die Bildschirme bleiben leer. Quellen › Collector listet die Filter auf, die es findet, und bietet an, zurück auf den
Sampler zu schalten, der keinen Filter nutzt und neben ihnen funktioniert. Du verlierst nur die ganz kurzen Verbindungen
(der Vergleich); alles andere wird genauso aufgezeichnet.
Die Erweiterung hat nach einem Flowlight-Update aufgehört zu arbeiten.
Versionen vor 0.2.5 hatten das: macOS führt weiter den Build der Erweiterung aus, der zuletzt aktiviert wurde, nach einem Update war die
Erweiterung also die alte Version, und macOS verweigert die Verbindung zwischen einem nicht passenden Paar. Ab 0.2.5 prüft Flowlight beim Start
- und aktiviert den Filter selbst neu. Drücke bei einer älteren Version einmal Filter installieren & aktivieren unter Erfassung.
-
Mit der Erfassung ist etwas anderes nicht in Ordnung und ich weiß nicht, was.
+ und aktiviert den Filter selbst neu. Drücke bei einer älteren Version einmal Filter installieren & aktivieren unter Quellen › Collector.
+
Mit Quellen › Collector stimmt etwas anderes nicht und ich weiß nicht, was.
Führe das aus und lies, was es ausgibt – es meldet nur Zustände und Zähler, nie etwas, das Flowlight über deinen Datenverkehr aufgezeichnet hat:
Es zeigt, welche Erweiterungen installiert sind, ob macOS Flowlights Filter wirklich gestartet hat und wie kürzlich überhaupt etwas aufgezeichnet wurde.
diff --git a/site/pages/de/index.html b/site/pages/de/index.html
index 8777fdf4..ee2744f4 100644
--- a/site/pages/de/index.html
+++ b/site/pages/de/index.html
@@ -110,13 +110,13 @@
Verlauf
Wo ist alles hingegangen? Sekunde bis Jahr, gruppiert nach Ap
Warnungen
Was sah falsch aus? Nachvollziehbare Warnungen pro App, mit Ziel und Schwellenwert.
⌘5
-
Regeln
Was habe ich verweigert – und passiert es? Jede Regel, was sie blockiert hat, und ein Verlauf jeder Entscheidung.
⌘8
+
Regeln
Was habe ich verweigert – und passiert es? Jede Regel, was sie blockiert hat, und ein Verlauf jeder Entscheidung.
⌘8 · Developer ID / ⌘7 · App Store
Fragen
Fragen in normaler Sprache, beantwortet aus dem Verlauf – mit jeder ausgeführten Abfrage darunter.
⌘6
-
-
Geräte
Bluetooth, USB und Kameras: was gekoppelt, angeschlossen oder aktiv ist und wann sich das geändert hat. Aus, bis du es einschaltest.
⌘9
+
+
Quellen
Kommen Daten an, wie viel ist benannt und welche Gerätekanäle sind aktiv? Collector, Geräte und Abdeckung an einem Ort.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspizieren
Optional. Was hat der Agent wirklich gesendet, und welcher Tool-Aufruf hat es ausgelöst? Entschlüsselte Anfragen, Tool-Aufrufe, Ergebnisse.
⌘7
+
Inspizieren
Optional. Was hat der Agent wirklich gesendet, und welcher Tool-Aufruf hat es ausgelöst? Entschlüsselte Anfragen, Tool-Aufrufe, Ergebnisse.
⌘7 · Developer ID
Verbindungen
Was kommuniziert? Eine zoombare Sankey-Karte für App-Verkehr und nachgewiesene KI-Agentenpfade, mit exakter Listenansicht.
⌘4
@@ -454,7 +454,7 @@
In unter einer Minute einsatzbereit
Basislinien für Anomalien und Regeln, die für KI-Agenten gemacht sind. Beides funktioniert gut nebeneinander.
Warum fragt es nach meinem Passwort?
macOS lässt nur Administratoren Netzwerkpakete lesen. Die einmalige Einrichtung gibt deinem Benutzerkonto Lesezugriff – genauso, wie
- Wireshark es tut. Du kannst ihn jederzeit im Bereich Erfassung wieder entfernen.
+ Wireshark es tut. Du kannst ihn jederzeit unter Quellen › Collector wieder entfernen.
Erkennt es, welcher MCP-Server oder welches Tool eine Anfrage gestellt hat?
Ja, auf Prozessebene. Flowlight verfolgt jeden Prozess zurück zu dem Agenten, der ihn gestartet hat – das curl eines Shell-Tools
oder die Verbindungen eines MCP-Servers werden also diesem Agenten zugeordnet, und MCP-Server werden aus den Konfigurationen von Claude Code, Claude
diff --git a/site/pages/de/privacy.html b/site/pages/de/privacy.html
index 2a69d53c..9d1b5e6d 100644
--- a/site/pages/de/privacy.html
+++ b/site/pages/de/privacy.html
@@ -66,7 +66,7 @@
Netzwerkanfragen, die die App stellt
Berechtigungen
-
Administrator-Passwort, ein Mal, für den Zugriff auf den Paketmitschnitt. Entfernbar über den Bildschirm Erfassung.
+
Administrator-Passwort, ein Mal, für den Zugriff auf den Paketmitschnitt. Entfernbar unter Quellen › Collector.
Benachrichtigungen, für Warnungen. Optional.
Anmeldeobjekt, nur wenn du „Beim Anmelden starten“ einschaltest.
verhindert das, und kein Überwachungswerkzeug auf macOS kann es verhindern und dabei ein Werkzeug bleiben, das du auch selbst abschalten kannst.
Die ehrliche Aussage ist schmaler und trotzdem nützlich: Software, die sich schlecht verhält, aber einer Überwachung nicht aktiv ausweicht,
wird gesehen. Software, die ihr aktiv ausweicht, vielleicht nicht – und sie lässt zumindest eine Lücke zurück: eine Erweiterung, die stehen
- geblieben ist, ein Zeitraum ohne Daten. Dafür ist der Bildschirm Abdeckung da.
Systemdienste, die von Inhaltsfiltern ausgenommen sind. macOS zeigt einem Inhaltsfilter nicht alles; ein Teil seines
eigenen Datenverkehrs erreicht unseren nie.
Ein anderer Inhaltsfilter, der den Platz hält. macOS führt einen zur Zeit aus. Hat ihn ein VPN oder ein
- Sicherheitsagent, installiert sich Flowlights Filter, verbindet sich und wird nie gebeten, etwas zu filtern – Erfassung sagt das, statt einen
+ Sicherheitsagent, installiert sich Flowlights Filter, verbindet sich und wird nie gebeten, etwas zu filtern – Quellen › Collector sagt das, statt einen
leeren Bildschirm zu zeigen.
Kurze Verbindungen, beim Sampler. Ohne die Erweiterung liest Flowlight Zähler einmal pro Sekunde: Eine Verbindung, die
zwischen zwei Messungen öffnet und schließt, wird nie aufgezeichnet.
@@ -83,7 +83,7 @@
Was der Inspektion entgeht
Die HTTPS-Inspektion liest nur, was über Flowlights lokalen Proxy geleitet wird, und darüber entscheidet ein Programm beim Start. Eine App,
die Proxy-Einstellungen ignoriert, eine, die vor dem Einschalten der Inspektion gestartet wurde, oder eine, die ihre Zertifikate anpinnt, geht
unberührt durch – absichtlich, denn eine angepinnte Verbindung zu brechen würde die App brechen. QUIC wird dem Proxy ebenfalls nicht angeboten.
-
Ein leerer Bildschirm Inspizieren heißt also „hier wurde nichts durchgeleitet“ und nicht „es ist nichts passiert“. Abdeckung sagt pro App,
+
Ein leerer Bildschirm Inspizieren heißt also „hier wurde nichts durchgeleitet“ und nicht „es ist nichts passiert“. Quellen › Abdeckung sagt pro App,
welches von beidem gilt.
A filter in the kernel drops every other packet before Flowlight sees it, and packet contents are never stored.
macOS only lets administrators read packets, so the Name Your Traffic window asks for your password once. It installs
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, which gives the access_bpf group read access to
- /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Capture › Remove Packet Capture Access.
+ /dev/bpf* at each boot, the same approach Wireshark uses. Remove it any time from Sources › Collector › Remove Packet Capture Access.
Identify network owners labels traffic with no hostname by who operates the address
(Cloudflare, Inc. · AS13335). It's on by default and sends those public IP addresses (never private ones) to Team Cymru's
- DNS service. Turn it off in Capture.
+ DNS service. Turn it off in Sources › Collector.
Language
Flowlight is translated into English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español and
@@ -101,13 +101,11 @@
Optional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
Optional: decrypted requests from the agents you route through Flowlight, and the tool calls behind them. Search reaches into request and response bodies.
Collector health and recovery, hostname coverage, and opt-in camera, Bluetooth, USB and storage activity in three tabs.
-
The shortcuts follow the sidebar's visible order: ⌘0 is the tenth item, and an eleventh remains available without an invented key.
+
The shortcuts follow the visible sidebar order. Developer ID builds include Inspect at ⌘7; App Store builds omit Inspect, so Rules and Sources move to ⌘7 and ⌘8.
Live, the screen Flowlight opens on.
@@ -129,7 +127,7 @@
AI agent rules
Unnamed host
connects to a raw IP with no hostname on an unusual port
On
Active while you're away
moves 1 MB or more in a minute after you stop using the keyboard and mouse
15 minutes
-
Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Settings › Detection.
+
Agents get a 1-hour learning period before new-destination alerts start. Change any of this in Alerts › Detection.
Tools & MCP servers
Agents do much of their work through other processes: a shell tool runs curl, git or npm, and MCP
@@ -213,7 +211,7 @@
Other alerts
Apple's own apps are left out by default. macOS contacts Apple constantly — Software Update, iCloud,
push, time, Maps tiles — on hosts and ports that are new the first time they appear, and listing all of it buries the one
- line worth reading. Turn it off in Settings › Detection › Rules if you want them. Either way the traffic is still
+ line worth reading. Turn it off in Alerts › Detection › Rules if you want them. Either way the traffic is still
recorded, still appears in Live, History and Ask, and is still subject to every rule, guardrail and allowlist: the setting
decides what is listed, never what is allowed.
@@ -273,7 +271,7 @@
HTTPS inspection (optional)
Flowlight certificate; Flowlight notices and passes them through encrypted. By default, header values are kept only when the header is one you
allow, and everything else is replaced by its length before anything is stored — recorded requests are kept for as long as you set, and Remove Certificate & Recorded Data deletes the certificate, its trust
setting and everything recorded. Inspection is HTTP/1.1 only (Flowlight asks both sides for it) and not available in demo mode.
-
Local risk analysis is separate and off by default. In History or Settings › Detection, you can ask
+
Local risk analysis is separate and off by default. In History or Alerts › Detection, you can ask
Apple’s on-device model to review only meaningful, already-recorded decrypted HTTP candidates after capture. It gets a
bounded redacted description — never request or response bodies, header values, cookies, credentials or tool arguments —
and nothing leaves the Mac. The result is a potential-harm hint, not proof of intent: Flowlight never blocks, changes,
@@ -452,7 +450,7 @@
Refusing connections
refuse them: the connection is dropped and an alert records what was refused, with Allow … from Now On to add it
to the list in one click. The agent's next attempt goes through.
It needs the Network Extension. Refusing a connection means sitting in its path, which the nettop sampler
- cannot do — Capture will say so rather than offer a switch that does nothing.
+ cannot do — Sources › Collector will say so rather than offer a switch that does nothing.
Some things are never refused, whatever a list says: your local network, DNS, essential Apple system services, and Flowlight's own
traffic. A blocked Mac is a worse outcome than a blocked agent, so where there is doubt the connection is allowed and recorded.
Enforcement also lapses a few seconds after Flowlight stops running — a refusal nobody can see is worse than none, and the way
@@ -485,8 +483,9 @@
Agent guardrails: block a tool, a server or a resource
This is not a sandbox. A refused tool stops being offered and stops being answered. An agent that still has a
shell can do by hand what the tool would have done. Flowlight will record that; it does not pretend to prevent it.
-
Capture: engines and sources
-
Flowlight records traffic one of two ways, chosen in Capture. They differ in what they can miss, which is worth
+
Sources: collector, coverage and devices
+
Sources keeps operational setup in one place. Its health summary shows whether traffic is arriving, how much is named, and which optional device channels are active; any unfinished collector step links directly to Sources › Collector.
+
Flowlight records traffic one of two ways, chosen under Sources › Collector. They differ in what they can miss, which is worth
understanding before you rely on either.
nettop sampler (default)
Network Extension
@@ -512,12 +511,12 @@
Capture: engines and sources
and leaving your chosen source alone. Try the extension again under Network Extension starts over.
It also can't run at all on some Macs. macOS allows one content filter at a time, and corporate security software
normally holds it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and the like. Flowlight's filter will install and connect on those
- machines and then never be handed a connection. Capture lists any it finds and offers to switch you back to the sampler, which
+ machines and then never be handed a connection. Sources › Collector lists any it finds and offers to switch you back to the sampler, which
needs no filter and works alongside them.
See the developer guide for how it's built.
Coverage: what Flowlight can't account for
-
Every other screen answers what happened. Coverage answers what you would not have been told, which is what
+
Sources › Coverage answers what you would not have been told, which is what
decides how much the other screens are worth. It asks three questions per app, because they fail independently.
Was it seen? The Network Extension sees each flow as it opens. The nettop sampler reads counters once a
second, so a connection that opens and closes between two readings — a DNS lookup, a fast API call, a script that runs curl
@@ -535,7 +534,7 @@
Coverage: what Flowlight can't account for
fact.
Devices: camera activity, Bluetooth, USB and external storage
-
A Mac sends and receives over more than TCP and UDP. The Devices screen covers the rest, with every channel
+
A Mac sends and receives over more than TCP and UDP. Sources › Devices covers the rest, with every channel
off until you turn it on because watching more of your Mac should be your decision rather than something an update did.
Camera activity shows whether each camera is active and records confirmed start and stop transitions.
Flowlight reads the public CoreMediaIO device state; it never opens a capture session, requests camera access, or reads a
@@ -585,7 +584,7 @@
Running in the background
have. Hostname setup is offered a little after launch and only while a window is open, rather than greeting a first run with a
request for your password; the offer returns next launch until you take or dismiss it.
Quitting Flowlight stops the sampler. It does not stop the Network Extension: a system extension runs on its own, so the filter
- carries on inspecting connections until you disable or uninstall it in Capture.
+ carries on inspecting connections until you disable or uninstall it in Sources › Collector.
Export to OpenTelemetry or a SIEM
Off until you configure it, and there is no Flowlight service to send to. You name the endpoint — your own
@@ -624,7 +623,7 @@
Export to OpenTelemetry or a SIEM
Your data
Everything lives in ~/Library/Application Support/Flowlight/traffic.sqlite. Per-second rows are kept 6 hours
(adjustable), minute rows 14 days, hourly rows 400 days, daily rows indefinitely, and alerts 90 days.
- Capture › Clear all data deletes it.
+ Settings › Data & Privacy › Clear All Data deletes it.
Updates
After you quit Flowlight cleanly and launch it again, a newly found version opens the update window. At other times,
@@ -644,7 +643,7 @@
Demo mode
Uninstall
-
In Capture, choose Remove Packet Capture Access (asks for your password) if you enabled it,
+
In Sources › Collector, choose Remove Packet Capture Access (asks for your password) if you enabled it,
uninstall the content filter if you installed it, and turn HTTPS inspection off in Inspect so its certificate
leaves your keychain. Only Flowlight itself can withdraw those three.
Quit Flowlight and move it from Applications to the Trash — or, if you installed it with Homebrew,
@@ -663,18 +662,18 @@
Questions & answers
byte counters once a second and records the change, so a long transfer is counted exactly — but a connection that opens and
closes between two readings never appears at all. The Network Extension is called by macOS as each connection is made, so
even a five-millisecond request is recorded. If you're watching an AI agent that fires many short requests, install the
- extension from Capture. The full comparison is above.
+ extension from Sources › Collector. The full comparison is above.
I turned on the Network Extension and nothing appears. The sampler works fine.
Almost always because another content filter already has the slot. macOS runs one content filter at a time, and
corporate security software usually claims it — Palo Alto Networks GlobalProtect, CrowdStrike Falcon and similar. Flowlight's
- filter still installs, activates and connects, so Capture says Connected to filter extension, but macOS never hands it a
- single connection and the screens stay empty. Capture lists the filters it finds and offers to switch you back to
+ filter still installs, activates and connects, so Sources › Collector says Connected to filter extension, but macOS never hands it a
+ single connection and the screens stay empty. Sources › Collector lists the filters it finds and offers to switch you back to
the sampler, which doesn't use a filter and works alongside them. You lose only the very short connections
(the comparison); everything else is recorded the same way.
The extension stopped working after Flowlight updated.
Versions before 0.2.5 had this: macOS keeps running whichever build of the extension was last activated, so after an update the
extension was the old version and macOS refuses the connection between a mismatched pair. From 0.2.5 Flowlight checks at launch
- and re-activates the filter itself. On an older version, press Install & enable filter in Capture once.
+ and re-activates the filter itself. On an older version, press Install & enable filter in Sources › Collector once.
Something else is wrong with capture and I don't know what.
Run this and read what it prints — it reports state and counts only, never anything Flowlight recorded about your traffic:
Un filtro en el núcleo descarta todos los demás paquetes antes de que Flowlight los vea, y el contenido de los paquetes no se guarda nunca.
macOS solo permite leer paquetes a los administradores, así que la ventana Poner nombre a tu tráfico pide tu contraseña una vez. Instala
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, que da al grupo access_bpf acceso de lectura a
- /dev/bpf* en cada arranque, el mismo método que usa Wireshark. Puedes retirarlo cuando quieras desde Captura › Retirar el acceso a la captura de paquetes.
+ /dev/bpf* en cada arranque, el mismo método que usa Wireshark. Puedes retirarlo cuando quieras desde Fuentes › Colector › Retirar el acceso a la captura de paquetes.
Identificar a los propietarios de la red etiqueta el tráfico sin nombre de host con quién opera la dirección
(Cloudflare, Inc. · AS13335). Está activado por defecto y envía esas direcciones IP públicas (nunca las privadas) al servicio
- DNS de Team Cymru. Desactívalo en Captura.
+ DNS de Team Cymru. Desactívalo en Fuentes › Colector.
Idioma
Flowlight está traducido a English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español y
@@ -99,14 +99,12 @@
Las vistas
Historial
⌘3
Adónde fue el tráfico, del segundo al año. Agrupa por App, Destino o IP; cambia a Gráficos o a Merece un vistazo; exporta a CSV.
Un mapa estable de apps y sus destinos exactos, con rutas ponderadas, marcadores de dirección en movimiento, recuentos de conexiones y una lista equivalente.
Opcional: las peticiones descifradas de los agentes que encamines por Flowlight, y las llamadas de herramientas que hay detrás. La búsqueda llega a los cuerpos de las peticiones y las respuestas.
Opcional: las peticiones descifradas de los agentes que encamines por Flowlight, y las llamadas de herramientas que hay detrás. La búsqueda llega a los cuerpos de las peticiones y las respuestas.
Estado del colector, canales de dispositivos y cobertura de nombres en tres pestañas.
-
Los atajos siguen el orden de la barra lateral: ⌘0 es el décimo elemento y el undécimo sigue disponible sin inventar una tecla.
+
Los atajos siguen el orden visible de la barra lateral. Las versiones Developer ID incluyen Inspeccionar en ⌘7; las de App Store lo omiten, así que Reglas y Fuentes pasan a ⌘7 y ⌘8.
En vivo, la pantalla con la que se abre Flowlight.
@@ -404,7 +402,7 @@
Rechazar conexiones
rechazará: la conexión se descarta y una alerta registra qué se rechazó, con Permitir … a partir de ahora para añadirlo
a la lista con un clic. El siguiente intento del agente pasa.
Necesita la extensión de red. Rechazar una conexión implica situarse en su camino, y eso el muestreador nettop
- no puede hacerlo; Captura lo dirá en vez de ofrecer un interruptor que no hace nada.
+ no puede hacerlo; Fuentes › Colector lo dirá en vez de ofrecer un interruptor que no hace nada.
Hay cosas que nunca se rechazan, diga lo que diga una lista: tu red local, el DNS, los servicios de Apple y el propio tráfico
de Flowlight. Un Mac bloqueado es peor resultado que un agente bloqueado, así que ante la duda la conexión se permite y se registra.
La aplicación de las reglas también caduca unos segundos después de que Flowlight deje de ejecutarse: un rechazo que nadie puede ver es peor que ninguno, y la forma
@@ -436,8 +434,8 @@
Salvaguardas de agente: bloquear una herramienta, un servido
Esto no es un sandbox. Una herramienta rechazada deja de ofrecerse y deja de responderse. Un agente que siga teniendo un
shell puede hacer a mano lo que habría hecho la herramienta. Flowlight lo registrará; no pretende impedirlo.
-
Captura: motores y fuentes
-
Flowlight registra el tráfico de una de dos maneras, que se eligen en Captura. Se diferencian en lo que pueden perderse, y conviene
+
Fuentes: colector y motores
+
Flowlight registra el tráfico de una de dos maneras, que se eligen en Fuentes › Colector. Se diferencian en lo que pueden perderse, y conviene
entenderlo antes de confiar en cualquiera de las dos.
muestreador nettop (predeterminado)
extensión de red
@@ -463,7 +461,7 @@
Captura: motores y fuentes
y sin tocar la fuente que tú elegiste. Volver a intentar la extensión, dentro de Extensión de red, empieza de nuevo.
Y en algunos Mac no puede funcionar en absoluto. macOS permite un filtro de contenido a la vez, y normalmente lo ocupa el software de seguridad
corporativo: Palo Alto Networks GlobalProtect, CrowdStrike Falcon y similares. En esas máquinas el filtro de Flowlight se instalará y se conectará, y
- después nunca recibirá una conexión. Captura lista los que encuentra y te ofrece volver al muestreador, que
+ después nunca recibirá una conexión. Fuentes › Colector lista los que encuentra y te ofrece volver al muestreador, que
no necesita filtro y funciona junto a ellos.
Consulta la guía para desarrolladores para ver cómo está construido.
@@ -532,7 +530,7 @@
Ejecutar en segundo plano
sí tienes. La configuración de los nombres de host se ofrece un rato después del arranque y solo mientras haya una ventana abierta, en lugar de recibir un primer arranque con una
petición de contraseña; la oferta vuelve en el siguiente arranque hasta que la aceptes o la descartes.
Salir de Flowlight detiene el muestreador. No detiene la extensión de red: una extensión del sistema se ejecuta por su cuenta, así que el filtro
- sigue examinando conexiones hasta que la desactives o la desinstales en Captura.
+ sigue examinando conexiones hasta que la desactives o la desinstales en Fuentes › Colector.
Exportar a OpenTelemetry o a un SIEM
Desactivada hasta que la configures, y no hay ningún servicio de Flowlight al que enviar. El endpoint lo pones tú —tu propio
@@ -571,7 +569,7 @@
Exportar a OpenTelemetry o a un SIEM
Tus datos
Todo vive en ~/Library/Application Support/Flowlight/traffic.sqlite. Las filas por segundo se guardan 6 horas
(ajustable), las de minuto 14 días, las horarias 400 días, las diarias indefinidamente, y las alertas 90 días.
- Captura › Borrar todos los datos las elimina.
+ Ajustes › Datos y privacidad › Borrar todos los datos las elimina.
Actualizaciones
Cuando aparece una versión nueva, Flowlight te lo dice con una notificación y un distintivo en la barra lateral en vez de interrumpir lo que estás
@@ -590,7 +588,7 @@
Modo demo
Desinstalación
-
En Captura, elige Retirar el acceso a la captura de paquetes (pide tu contraseña) si lo activaste,
+
En Fuentes › Colector, elige Retirar el acceso a la captura de paquetes (pide tu contraseña) si lo activaste,
desinstala el filtro de contenido si lo instalaste y desactiva la inspección HTTPS en Inspeccionar para que su certificado
salga de tu llavero. Esas tres cosas solo puede retirarlas Flowlight.
Sal de Flowlight y muévelo de Aplicaciones a la papelera; o, si lo instalaste con Homebrew,
@@ -609,18 +607,18 @@
Preguntas y respuestas
acumulados de macOS una vez por segundo y registra el cambio, así que una transferencia larga se cuenta con exactitud; pero una conexión que se abre y se
cierra entre dos lecturas no aparece en absoluto. A la extensión de red la llama macOS cada vez que se hace una conexión, así que
incluso una petición de cinco milisegundos queda registrada. Si vigilas un agente de IA que dispara muchas peticiones cortas, instala la
- extensión desde Captura. La comparación completa está más arriba.
+ extensión desde Fuentes › Colector. La comparación completa está más arriba.
He activado la extensión de red y no aparece nada. El muestreador funciona bien.
Casi siempre es porque otro filtro de contenido ya ocupa la plaza. macOS ejecuta un filtro de contenido a la vez, y
normalmente lo reclama el software de seguridad corporativo: Palo Alto Networks GlobalProtect, CrowdStrike Falcon y similares. El filtro de
- Flowlight se instala, se activa y se conecta, así que Captura dice Conectado a la extensión de filtro, pero macOS no le entrega ni una
- conexión y las pantallas se quedan vacías. Captura lista los filtros que encuentra y te ofrece volver
+ Flowlight se instala, se activa y se conecta, así que Fuentes › Colector dice Conectado a la extensión de filtro, pero macOS no le entrega ni una
+ conexión y las pantallas se quedan vacías. Fuentes › Colector lista los filtros que encuentra y te ofrece volver
al muestreador, que no usa filtro y funciona junto a ellos. Solo pierdes las conexiones muy cortas
(la comparación); todo lo demás se registra igual.
La extensión dejó de funcionar después de actualizar Flowlight.
Las versiones anteriores a la 0.2.5 tenían esto: macOS sigue ejecutando la compilación de la extensión que se activó por última vez, así que tras una actualización la
extensión era la versión antigua y macOS rechaza la conexión entre una pareja que no coincide. Desde la 0.2.5, Flowlight lo comprueba al arrancar
- y reactiva el filtro él mismo. En una versión anterior, pulsa una vez Instalar y activar el filtro en Captura.
+ y reactiva el filtro él mismo. En una versión anterior, pulsa una vez Instalar y activar el filtro en Fuentes › Colector.
Algo más va mal con la captura y no sé qué.
Ejecuta esto y lee lo que imprime: informa solo de estados y recuentos, nunca de nada que Flowlight haya registrado sobre tu tráfico:
¿Adónde ha ido todo? Del segundo al año, agrupado por ap
Alertas
¿Qué ha pintado mal? Alertas por app, explicables, con el destino y el umbral.
⌘5
-
Reglas
¿Qué he rechazado y se está cumpliendo? Cada regla, lo que ha bloqueado y un flujo con todas las decisiones.
⌘8
+
Reglas
¿Qué he rechazado y se está cumpliendo? Cada regla, lo que ha bloqueado y un flujo con todas las decisiones.
⌘8 · Developer ID / ⌘7 · App Store
Preguntar
Preguntas en lenguaje corriente, respondidas con el historial, y debajo cada consulta que ejecutó.
⌘6
-
-
Dispositivos
Bluetooth, USB y cámaras: qué está emparejado, conectado o activo y cuándo cambió. Desactivado hasta que lo actives.
⌘9
+
+
Fuentes
¿Están llegando datos, cuánto tiene nombre y qué canales de dispositivos están activos? Colector, Dispositivos y Cobertura en un solo lugar.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspeccionar
Opcional. ¿Qué envió el agente en realidad y qué llamada de herramienta lo provocó? Peticiones descifradas, llamadas de herramientas, resultados.
⌘7
+
Inspeccionar
Opcional. ¿Qué envió el agente en realidad y qué llamada de herramienta lo provocó? Peticiones descifradas, llamadas de herramientas, resultados.
⌘7 · Developer ID
Conexiones
¿Qué se comunica? Un mapa Sankey ampliable del tráfico de apps y las rutas comprobadas de agentes de IA, con una lista exacta equivalente.
⌘4
@@ -454,7 +454,7 @@
Funcionando en menos de un minuto
líneas base para detectar anomalías y reglas pensadas para los agentes de IA. Conviven bien.
¿Por qué me pide la contraseña?
macOS solo permite leer paquetes de red a los administradores. La configuración inicial da acceso de lectura a tu cuenta, igual
- que hace Wireshark. Puedes retirarlo cuando quieras desde la pantalla Captura.
+ que hace Wireshark. Puedes retirarlo cuando quieras desde Fuentes › Colector.
¿Puede saber qué servidor MCP o qué herramienta hizo una petición?
Sí, a nivel de proceso. Flowlight sigue cada proceso hasta el agente que lo arrancó, así que el curl de una herramienta de shell
o las conexiones de un servidor MCP se atribuyen a ese agente, y los servidores MCP toman su nombre de las configuraciones de Claude Code, Claude
diff --git a/site/pages/es/privacy.html b/site/pages/es/privacy.html
index f4f16c74..3d491fc0 100644
--- a/site/pages/es/privacy.html
+++ b/site/pages/es/privacy.html
@@ -66,7 +66,7 @@
Peticiones de red que hace la app
Permisos
-
Contraseña de administrador, una vez, para el acceso a la captura de paquetes. Se puede retirar desde la pantalla Captura.
+
Contraseña de administrador, una vez, para el acceso a la captura de paquetes. Se puede retirar desde Fuentes › Colector.
Notificaciones, para las advertencias. Opcional.
Ítem de inicio, solo si activas Abrir al iniciar sesión.
cualquier cosa cuyo instalador apruebes— puede descargar esa extensión, detener la app o borrar su base de datos. Nada en el diseño lo impide,
y ninguna herramienta de monitorización en macOS puede impedirlo y seguir siendo una herramienta que también puedas apagar tú.
La afirmación honesta es más estrecha y sigue siendo útil: el software que se porta mal pero no elude activamente un monitor se verá. El
- software que sí lo elude activamente puede no verse, y al menos dejará un hueco —una extensión que se detuvo, un periodo sin datos— que la
- pantalla Cobertura está ahí para mostrar.
+ software que sí lo elude activamente puede no verse, y al menos dejará un hueco —una extensión que se detuvo, un periodo sin datos— que
+ Fuentes › Cobertura está ahí para mostrar.
Lo que la captura se pierde
@@ -69,7 +69,7 @@
Lo que la captura se pierde
Los servicios del sistema exentos de los filtros de contenido. macOS no le muestra todo a un filtro de contenido; parte
de su propio tráfico no llega nunca al nuestro.
Otro filtro de contenido que ocupa el sitio. macOS ejecuta uno a la vez. Si lo tiene una VPN o un agente de seguridad, el
- filtro de Flowlight se instala, se conecta y nunca se le pide filtrar nada: Captura lo dice en vez de mostrar una pantalla vacía.
+ filtro de Flowlight se instala, se conecta y nunca se le pide filtrar nada: Fuentes › Colector lo dice en vez de mostrar una pantalla vacía.
Las conexiones cortas, con el muestreador. Sin la extensión, Flowlight lee contadores una vez por segundo: una conexión
que se abre y se cierra entre dos lecturas no se registra nunca.
Los canales que no son TCP ni UDP. Bluetooth y USB se ven como dispositivos, no como bytes. El servidor MCP local de un
@@ -80,7 +80,7 @@
Lo que la inspección se pierde
La inspección HTTPS lee solo lo que se encamina por el proxy local de Flowlight, y eso lo decide un programa cuando arranca. Una app que
ignora los ajustes de proxy, una que se arrancó antes de activar la inspección, o una que fija sus certificados pasa intacta: a propósito,
porque romper una conexión con certificado fijado rompería la app. QUIC tampoco se le ofrece al proxy.
-
Así que una pantalla Inspeccionar vacía significa «aquí no se ha encaminado nada», no «no ha pasado nada». Cobertura dice cuál de las dos
+
Así que una pantalla Inspeccionar vacía significa «aquí no se ha encaminado nada», no «no ha pasado nada». Fuentes › Cobertura dice cuál de las dos
cosas se aplica, app por app.
Un filtre dans le noyau écarte tous les autres paquets avant que Flowlight les voie, et le contenu des paquets n’est jamais conservé.
macOS ne laisse que les administrateurs lire les paquets : la fenêtre Nommer votre trafic demande donc votre mot de passe une fois. Elle installe
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, qui donne au groupe access_bpf un accès en lecture à
- /dev/bpf* à chaque démarrage, la même approche que celle de Wireshark. Retirez-le à tout moment depuis Capture › Retirer l’accès à la capture de paquets.
+ /dev/bpf* à chaque démarrage, la même approche que celle de Wireshark. Retirez-le à tout moment depuis Sources › Collecteur › Retirer l’accès à la capture de paquets.
Identifier les propriétaires de réseau étiquette le trafic sans nom d’hôte par l’exploitant de l’adresse
(Cloudflare, Inc. · AS13335). C’est activé par défaut et cela envoie ces adresses IP publiques (jamais les privées) au
- service DNS de Team Cymru. Désactivez-le dans Capture.
+ service DNS de Team Cymru. Désactivez-le dans Sources › Collecteur.
Langue
Flowlight est traduit en anglais, 简体中文, 繁體中文, 日本語, 한국어, français, allemand, italien, espagnol et
@@ -99,14 +99,12 @@
Les vues
Historique
⌘3
Où le trafic est parti, de la seconde à l’année. Groupez par App, Destination ou IP ; passez aux Graphiques ou à À regarder de près ; exportez en CSV.
Une carte stable des apps et de leurs destinations exactes, avec des chemins pondérés, des marqueurs de direction animés, le nombre de connexions et une liste équivalente.
Facultatif : les requêtes déchiffrées des agents que vous faites passer par Flowlight, et les appels d’outils qui les ont causées. La recherche va jusque dans les corps de requête et de réponse.
Facultatif : les requêtes déchiffrées des agents que vous faites passer par Flowlight, et les appels d’outils qui les ont causées. La recherche va jusque dans les corps de requête et de réponse.
La santé et la récupération du collecteur, la couverture des noms d’hôte, ainsi que l’activité facultative des caméras, du Bluetooth, de l’USB et du stockage dans trois onglets.
-
Les raccourcis suivent l’ordre de la barre latérale : ⌘0 est le dixième élément et le onzième reste accessible sans inventer de touche.
+
Les raccourcis suivent l’ordre visible de la barre latérale. Les versions Developer ID incluent Inspecter en ⌘7 ; les versions App Store l’omettent, donc Règles et Sources passent à ⌘7 et ⌘8.
En direct, l’écran sur lequel Flowlight s’ouvre.
@@ -126,7 +124,7 @@
Règles pour les agents IA
Hôte sans nom
se connecte à une IP brute sans nom d’hôte, sur un port inhabituel
Activé
Actif pendant votre absence
déplace 1 MB ou plus en une minute après que vous avez cessé d’utiliser le clavier et la souris
15 minutes
-
Les agents bénéficient d’une période d’apprentissage d’1 heure avant les premières alertes de nouvelle destination. Modifiez tout cela dans Réglages › Détection.
+
Les agents bénéficient d’une période d’apprentissage d’1 heure avant les premières alertes de nouvelle destination. Modifiez tout cela dans Alertes › Détection.
Outils & serveurs MCP
Les agents font une grande part de leur travail via d’autres processus : un outil shell lance curl, git ou npm, et les serveurs
@@ -408,7 +406,7 @@
Refuser des connexions
refusera aussi : la connexion est abandonnée et une alerte consigne ce qui a été refusé, avec Autoriser … désormais pour l’ajouter
à la liste en un clic. La tentative suivante de l’agent passe.
Cela nécessite l’extension réseau. Refuser une connexion suppose de se trouver sur son chemin, ce que l’échantillonneur nettop
- ne peut pas faire — Capture le dira plutôt que de proposer un interrupteur qui ne fait rien.
+ ne peut pas faire — Sources › Collecteur le dira plutôt que de proposer un interrupteur qui ne fait rien.
Certaines choses ne sont jamais refusées, quoi qu’en dise une liste : votre réseau local, le DNS, les services d’Apple et le trafic de
Flowlight lui-même. Un Mac bloqué est un pire résultat qu’un agent bloqué : en cas de doute, la connexion est donc autorisée et enregistrée.
L’application des refus cesse aussi quelques secondes après l’arrêt de Flowlight — un refus que personne ne peut voir est pire que pas de refus, et le moyen
@@ -440,8 +438,9 @@
Garde-fous des agents : bloquer un outil, un serveur ou
Ce n’est pas un bac à sable. Un outil refusé cesse d’être proposé et cesse d’obtenir une réponse. Un agent qui a encore un
shell peut faire à la main ce que l’outil aurait fait. Flowlight l’enregistrera ; il ne prétend pas l’empêcher.
-
Capture : moteurs et sources
-
Flowlight enregistre le trafic de deux façons, au choix dans Capture. Elles diffèrent par ce qu’elles peuvent manquer, ce qu’il vaut la peine de
+
Sources : collecteur, couverture et appareils
+
Sources réunit la configuration opérationnelle. Son résumé de santé indique si le trafic arrive, quelle part est nommée et quels canaux d’appareils facultatifs sont actifs ; toute étape inachevée mène directement à Sources › Collecteur.
+
Flowlight enregistre le trafic de deux façons, au choix dans Sources › Collecteur. Elles diffèrent par ce qu’elles peuvent manquer, ce qu’il vaut la peine de
comprendre avant de compter sur l’une ou l’autre.
échantillonneur nettop (par défaut)
Extension réseau
@@ -467,12 +466,12 @@
Capture : moteurs et sources
Réessayer l’extension, sous Extension réseau, reprend tout à zéro.
Elle ne peut pas non plus fonctionner du tout sur certains Mac. macOS n’autorise qu’un filtre de contenu à la fois, et les logiciels de sécurité
d’entreprise le détiennent d’ordinaire — Palo Alto Networks GlobalProtect, CrowdStrike Falcon et compagnie. Le filtre de Flowlight s’installera et se connectera sur ces
- machines, puis ne recevra jamais une seule connexion. Capture liste ceux qu’il trouve et propose de vous ramener à l’échantillonneur, qui
+ machines, puis ne recevra jamais une seule connexion. Sources › Collecteur liste ceux qu’il trouve et propose de vous ramener à l’échantillonneur, qui
n’a besoin d’aucun filtre et fonctionne à côté d’eux.
Voyez le guide du développeur pour la façon dont c’est construit.
Couverture : ce dont Flowlight ne peut pas rendre compte
-
Tous les autres écrans répondent à ce qui s’est passé. Couverture répond à ce qu’on ne vous aurait pas dit, et c’est cela
+
Sources › Couverture répond à ce qu’on ne vous aurait pas dit, et c’est cela
qui décide de ce que valent les autres écrans. Elle pose trois questions par app, parce qu’elles échouent indépendamment.
Est-ce que ça a été vu ? L’extension réseau voit chaque flux à son ouverture. L’échantillonneur nettop lit des compteurs
une fois par seconde : une connexion qui s’ouvre et se ferme entre deux relevés — une recherche DNS, un appel d’API bref, un script qui
@@ -491,7 +490,7 @@
Couverture : ce dont Flowlight ne peut pas rendre compte<
réconfort et non un fait.
Appareils : Bluetooth, USB et stockage externe
-
Un Mac émet et reçoit par plus que TCP et UDP. L’écran Appareils couvre le reste, et il est désactivé
+
Un Mac émet et reçoit par plus que TCP et UDP. Sources › Appareils couvre le reste, et chaque canal est désactivé
jusqu’à ce que vous l’activiez — non parce qu’il demanderait une autorisation que Flowlight n’a pas déjà, mais parce que surveiller davantage de
votre Mac devrait être votre décision plutôt que le fait d’une mise à jour.
Bluetooth montre quels appareils sont appairés, lesquels sont connectés, et quand cela a changé, lu depuis le système
@@ -537,7 +536,7 @@
Fonctionner en arrière-plan
avez. La configuration des noms d’hôte est proposée un peu après le lancement et seulement tant qu’une fenêtre est ouverte, plutôt que d’accueillir un premier lancement par une
demande de mot de passe ; la proposition revient au lancement suivant jusqu’à ce que vous l’acceptiez ou l’écartiez.
Quitter Flowlight arrête l’échantillonneur. Cela n’arrête pas l’extension réseau : une extension système tourne pour son compte, donc le filtre
- continue d’inspecter les connexions jusqu’à ce que vous le désactiviez ou le désinstalliez dans Capture.
+ continue d’inspecter les connexions jusqu’à ce que vous le désactiviez ou le désinstalliez dans Sources › Collecteur.
Exporter vers OpenTelemetry ou un SIEM
Désactivé tant que vous ne l’avez pas configuré, et il n’existe aucun service Flowlight vers lequel envoyer. C’est vous qui nommez le point de terminaison — votre propre
@@ -577,7 +576,7 @@
Exporter vers OpenTelemetry ou un SIEM
Vos données
Tout vit dans ~/Library/Application Support/Flowlight/traffic.sqlite. Les lignes par seconde sont conservées 6 heures
(réglable), les lignes à la minute 14 jours, les lignes horaires 400 jours, les lignes quotidiennes indéfiniment, et les alertes 90 jours.
- Capture › Effacer toutes les données les supprime.
+ Réglages › Données et confidentialité › Effacer toutes les données les supprime.
Mises à jour
Quand une nouvelle version paraît, Flowlight vous le signale par une notification et un badge dans la barre latérale plutôt qu’en interrompant ce que vous
@@ -596,7 +595,7 @@
Mode démo
Désinstallation
-
Dans Capture, choisissez Retirer l’accès à la capture de paquets (demande votre mot de passe) si vous l’aviez activé,
+
Dans Sources › Collecteur, choisissez Retirer l’accès à la capture de paquets (demande votre mot de passe) si vous l’aviez activé,
désinstallez le filtre de contenu si vous l’aviez installé, et désactivez l’inspection HTTPS dans Inspecter pour que son certificat
quitte votre trousseau. Flowlight seul peut retirer ces trois choses.
Quittez Flowlight et déplacez-le d’Applications vers la Corbeille — ou, si vous l’avez installé avec Homebrew,
@@ -615,18 +614,18 @@
Questions & réponses
cumulés de macOS une fois par seconde et enregistre l’écart : un transfert long est donc compté exactement — mais une connexion qui s’ouvre et
se ferme entre deux relevés n’apparaît pas du tout. L’extension réseau est appelée par macOS à chaque connexion établie, donc
même une requête de cinq millisecondes est enregistrée. Si vous surveillez un agent IA qui déclenche beaucoup de requêtes brèves, installez
- l’extension depuis Capture. La comparaison complète est plus haut.
+ l’extension depuis Sources › Collecteur. La comparaison complète est plus haut.
J’ai activé l’extension réseau et rien n’apparaît. L’échantillonneur fonctionne très bien.
Presque toujours parce qu’un autre filtre de contenu occupe déjà la place. macOS n’exécute qu’un filtre de contenu à la fois, et les
logiciels de sécurité d’entreprise se l’accaparent d’ordinaire — Palo Alto Networks GlobalProtect, CrowdStrike Falcon et similaires. Le filtre de Flowlight
- s’installe, s’active et se connecte quand même, donc Capture affiche Connecté à l’extension de filtrage, mais macOS ne lui remet jamais une
- seule connexion et les écrans restent vides. Capture liste les filtres qu’il trouve et propose de vous ramener à
+ s’installe, s’active et se connecte quand même, donc Sources › Collecteur affiche Connecté à l’extension de filtrage, mais macOS ne lui remet jamais une
+ seule connexion et les écrans restent vides. Sources › Collecteur liste les filtres qu’il trouve et propose de vous ramener à
l’échantillonneur, qui n’utilise pas de filtre et fonctionne à côté d’eux. Vous ne perdez que les connexions très brèves
(la comparaison) ; tout le reste est enregistré de la même façon.
L’extension a cessé de fonctionner après une mise à jour de Flowlight.
Les versions antérieures à 0.2.5 avaient ce défaut : macOS continue d’exécuter la version de l’extension activée en dernier, donc après une mise à jour
l’extension était l’ancienne version, et macOS refuse la connexion entre une paire dépareillée. À partir de 0.2.5, Flowlight vérifie au lancement
- et réactive le filtre lui-même. Sur une version plus ancienne, appuyez une fois sur Installer & activer le filtre dans Capture.
+ et réactive le filtre lui-même. Sur une version plus ancienne, appuyez une fois sur Installer & activer le filtre dans Sources › Collecteur.
Autre chose ne va pas avec la capture et je ne sais pas quoi.
Lancez ceci et lisez ce qui s’affiche — cela ne rapporte que des états et des comptes, jamais rien de ce que Flowlight a enregistré sur votre trafic :
Qu’est-ce qui clochait ? Des alertes explicables, par app, avec la destination et le seuil.
⌘5
-
Règles
Qu’ai-je refusé, et est-ce bien appliqué ? Chaque règle, ce qu’elle a bloqué, et le flux de toutes les décisions.
⌘8
+
Règles
Qu’ai-je refusé, et est-ce bien appliqué ? Chaque règle, ce qu’elle a bloqué, et le flux de toutes les décisions.
⌘8 · Developer ID / ⌘7 · App Store
Demander
Des questions en langage courant, auxquelles l’historique répond — avec la liste des requêtes exécutées juste en dessous.
⌘6
-
-
Appareils
Bluetooth, USB et caméras : ce qui est appairé, branché ou actif, et quand cela a changé. Désactivé jusqu’à ce que vous l’activiez.
⌘9
+
+
Sources
Les données arrivent-elles, quelle part est nommée et quels canaux d’appareils sont actifs ? Collecteur, Appareils et Couverture au même endroit.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspecter
Facultatif. Qu’a réellement envoyé l’agent, et quel appel d’outil en est la cause ? Requêtes déchiffrées, appels d’outils, résultats.
⌘7
+
Inspecter
Facultatif. Qu’a réellement envoyé l’agent, et quel appel d’outil en est la cause ? Requêtes déchiffrées, appels d’outils, résultats.
⌘7 · Developer ID
Connexions
Qui communique ? Une carte Sankey zoomable du trafic des apps et des chemins attestés des agents IA, avec une liste exacte équivalente.
⌘4
@@ -454,7 +454,7 @@
En marche en moins d’une minute
des références pour détecter les anomalies, et des règles conçues pour les agents IA. Les deux cohabitent très bien.
Pourquoi demande-t-il mon mot de passe ?
macOS ne laisse que les administrateurs lire les paquets réseau. La configuration unique donne à votre compte un accès en lecture, exactement
- comme le fait Wireshark. Vous pouvez la retirer à tout moment depuis l’écran Capture.
+ comme le fait Wireshark. Vous pouvez la retirer à tout moment depuis Sources › Collecteur.
Peut-il dire quel serveur MCP ou quel outil a émis une requête ?
Oui, au niveau du processus. Flowlight remonte chaque processus jusqu’à l’agent qui l’a lancé, de sorte que le curl d’un outil
shell ou les connexions d’un serveur MCP sont attribués à cet agent, et les serveurs MCP sont nommés d’après les configurations de Claude Code, Claude
diff --git a/site/pages/fr/privacy.html b/site/pages/fr/privacy.html
index b338aae8..34ae0a0b 100644
--- a/site/pages/fr/privacy.html
+++ b/site/pages/fr/privacy.html
@@ -58,7 +58,7 @@
Les requêtes réseau que fait l’app
Téléchargement de mise à jour
github.com
L’image disque et son fichier de somme de contrôle
Seulement quand vous cliquez sur Télécharger & ouvrir
Mise à jour du pack de règles officiel
flowlight.xinbetween.com
Une requête HTTPS standard vers le flux officiel fixe. Le serveur voit votre adresse IP, l’agent utilisateur Flowlight/<version> et les validateurs conditionnels du cache ; il ne reçoit ni trafic, ni réglages des packs, ni identifiant d’appareil
Après le démarrage, lorsqu’une vérification est due, puis au maximum une fois par jour tant que le service fonctionne normalement. Activée par défaut ; interrupteur de désactivation et option manuelle Rechercher maintenant dans Règles › Packs
DNS inverse
Le résolveur DNS que vous avez configuré
Une recherche du nom enregistré d’une adresse IP, quand aucun nom d’hôte n’a été observé
Au besoin, dans le mode de capture par échantillonnage, qui est celui par défaut jusqu’à ce que l’extension réseau tourne. Pas d’interrupteur d’arrêt : sans elle, l’échantillonneur ne peut pas nommer la plupart des connexions. L’extension réseau les nomme à partir du trafic lui-même et ne fait pas cette recherche
-
Recherche du propriétaire de réseau
Team Cymru, par DNS
Des adresses IP publiques sans nom d’hôte connu. Les adresses privées et réservées ne quittent jamais votre Mac
Activé par défaut. Interrupteur d’arrêt dans Capture › Identifier les propriétaires de réseau
+
Recherche du propriétaire de réseau
Team Cymru, par DNS
Des adresses IP publiques sans nom d’hôte connu. Les adresses privées et réservées ne quittent jamais votre Mac
Activé par défaut. Interrupteur d’arrêt dans Sources › Collecteur › Identifier les propriétaires de réseau
Demander avec un modèle hébergé
Le fournisseur que vous choisissez : Anthropic, OpenAI, Google Gemini ou un point de terminaison compatible
Votre question et les résultats renvoyés par les requêtes Flowlight en lecture seule choisies par le modèle. La base de données de trafic elle-même n’est pas envoyée
Seulement quand vous choisissez un fournisseur hébergé et soumettez une question. L’écran Demander montre les requêtes transmises
Exportation vers un collecteur
Le point de terminaison OpenTelemetry ou HTTP que vous configurez
Les champs indiqués dans Réglages › Exportation, comme les agrégats de trafic et les alertes. Les en-têtes d’authentification sont stockés dans le trousseau
Seulement après que vous avez configuré un point de terminaison et activé l’exportation
Trafic d’une application inspectée
La destination d’origine demandée par l’application inspectée
La requête de l’application, transmise par le proxy local de Flowlight après déchiffrement
Seulement tant que l’inspection HTTPS est activée et que l’application est acheminée par le proxy
@@ -66,14 +66,14 @@
Les requêtes réseau que fait l’app
Autorisations
-
Mot de passe administrateur, une fois, pour l’accès à la capture de paquets. Retirable depuis l’écran Capture.
+
Mot de passe administrateur, une fois, pour l’accès à la capture de paquets. Retirable depuis Sources › Collecteur.
Notifications, pour les avertissements. Facultatif.
Élément d’ouverture, seulement si vous activez Lancer à l’ouverture de session.
Conservation
Les données par seconde 6 heures (réglable), les données à la minute 14 jours, les données horaires 400 jours, les totaux quotidiens indéfiniment, les alertes 90 jours.
- Capture › Effacer toutes les données supprime tout, et retirer ~/Library/Application Support/Flowlight fait de même.
+ Réglages › Données et confidentialité › Effacer toutes les données supprime tout, et retirer ~/Library/Application Support/Flowlight fait de même.
Ce site
Ce site est une page statique hébergée sur GitHub Pages et servie via Cloudflare. Il ne dépose aucun cookie et n’exécute aucune analytique. GitHub
diff --git a/site/pages/fr/threat-model.html b/site/pages/fr/threat-model.html
index fca0d46c..ac7d4c71 100644
--- a/site/pages/fr/threat-model.html
+++ b/site/pages/fr/threat-model.html
@@ -62,7 +62,7 @@
Un logiciel avec root peut l’éteindre
et aucun outil de surveillance sur macOS ne peut l’empêcher tout en restant un outil que vous pouvez aussi éteindre vous-même.
L’affirmation honnête est plus étroite et reste utile : un logiciel qui se comporte mal sans chercher activement à échapper à une
surveillance sera vu. Un logiciel qui y échappe activement, peut-être pas — et il laissera au moins un trou : une extension qui s’est
- arrêtée, une période sans données. C’est ce que l’écran Couverture est là pour montrer.
+ arrêtée, une période sans données. C’est ce que Sources › Couverture est là pour montrer.
Ce que la capture manque
@@ -71,7 +71,7 @@
Ce que la capture manque
Les services système dispensés des filtres de contenu. macOS ne montre pas tout à un filtre de contenu ; une partie
de son propre trafic n’atteint jamais le nôtre.
Un autre filtre de contenu qui détient la place. macOS n’en exécute qu’un à la fois. Si un VPN ou un agent de sécurité le
- détient, le filtre de Flowlight s’installe, se connecte, et on ne lui demande jamais de filtrer quoi que ce soit — Capture le dit plutôt que
+ détient, le filtre de Flowlight s’installe, se connecte, et on ne lui demande jamais de filtrer quoi que ce soit — Sources › Collecteur le dit plutôt que
de montrer un écran vide.
Les connexions brèves, avec l’échantillonneur. Sans l’extension, Flowlight lit des compteurs une fois par seconde :
une connexion qui s’ouvre et se ferme entre deux relevés n’est jamais enregistrée.
@@ -83,7 +83,7 @@
Ce que l’inspection manque
L’inspection HTTPS ne lit que ce qui est acheminé par le proxy local de Flowlight, et c’est un programme qui en décide à son démarrage. Une
app qui ignore les réglages de proxy, une app lancée avant l’activation de l’inspection, ou une app qui épingle ses certificats passe sans être
touchée — délibérément, parce que casser une connexion épinglée casserait l’app. QUIC n’est pas proposé au proxy non plus.
-
Un écran Inspecter vide signifie donc « rien n’a été acheminé ici », pas « rien ne s’est passé ». Couverture dit laquelle
+
Un écran Inspecter vide signifie donc « rien n’a été acheminé ici », pas « rien ne s’est passé ». Sources › Couverture dit laquelle
des deux s’applique, app par app.
Where did it all go? From 15 minutes through all history, gro
Alerts
What looked wrong? Explainable, per-app alerts with the destination and the threshold.
⌘5
-
Rules
What have I refused, and is it happening? Every rule, what each has blocked, and a feed of every decision.
⌘8
+
Rules
What have I refused, and is it happening? Every rule, what each has blocked, and a feed of every decision.
⌘8 · Developer ID / ⌘7 · App Store
Ask
Questions in plain language, answered from the history — with every query it ran listed underneath.
⌘6
-
-
Devices
Bluetooth, USB, and cameras: what's paired, what's attached or active, and when that changed. Off until you turn it on.
⌘9
+
+
Sources
Is data arriving, how much is named, and which device channels are active? Collector, Devices and Coverage in one place.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspect
Optional. What did the agent actually send, and which tool call made it? Decrypted requests, tool calls, results.
⌘7
+
Inspect
Optional. What did the agent actually send, and which tool call made it? Decrypted requests, tool calls, results.
⌘7 · Developer ID
Connections
What is communicating? A zoomable Sankey map for app traffic and proved AI-agent paths, with exact list parity.
⌘4
@@ -477,7 +477,7 @@
Running in under a minute
anomaly baselines, and rules built for AI agents. They work well side by side.
Why does it ask for my password?
macOS only lets administrators read network packets. The one-time setup gives your account read access, the
- same way Wireshark does. You can remove it any time from the Capture screen.
+ same way Wireshark does. You can remove it any time from Sources › Collector.
Can it tell which MCP server or tool made a request?
Yes, at the process level. Flowlight follows each process back to the agent that started it, so a shell tool's
curl or an MCP server's connections are attributed to that agent, and MCP servers are named from Claude Code, Claude
diff --git a/site/pages/it/docs.html b/site/pages/it/docs.html
index 756b30c6..ede0992a 100644
--- a/site/pages/it/docs.html
+++ b/site/pages/it/docs.html
@@ -35,7 +35,7 @@
Un filtro nel kernel scarta ogni altro pacchetto prima che Flowlight lo veda, e il contenuto dei pacchetti non viene mai memorizzato.
macOS permette di leggere i pacchetti solo agli amministratori, quindi la finestra Dai un nome al traffico chiede una volta la tua password. Installa
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, che a ogni avvio dà al gruppo access_bpf l'accesso in lettura a
- /dev/bpf*, lo stesso approccio usato da Wireshark. Puoi rimuoverlo quando vuoi da Acquisizione › Revoca l'accesso all'acquisizione dei pacchetti.
+ /dev/bpf*, lo stesso approccio usato da Wireshark. Puoi rimuoverlo quando vuoi da Origini › Collector › Revoca l'accesso all'acquisizione dei pacchetti.
Identifica i proprietari della rete etichetta il traffico senza nome host con chi gestisce l'indirizzo
(Cloudflare, Inc. · AS13335). È attivo per impostazione predefinita e invia quegli indirizzi IP pubblici (mai quelli privati) al servizio
- DNS di Team Cymru. Disattivalo in Acquisizione.
+ DNS di Team Cymru. Disattivalo in Origini › Collector.
Lingua
Flowlight è tradotto in English, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español e
@@ -99,14 +99,12 @@
Le viste
Cronologia
⌘3
Dove è andato il traffico, dal secondo all'anno. Raggruppa per App, Destinazione o IP; passa a Grafici o a Vale un'occhiata; esporta in CSV.
Una mappa stabile delle app e delle destinazioni esatte, con percorsi ponderati, indicatori di direzione in movimento, conteggi delle connessioni e un elenco equivalente.
Opzionale: le richieste decifrate degli agenti che instradi attraverso Flowlight e le chiamate agli strumenti che le hanno prodotte. La ricerca entra nei corpi di richieste e risposte.
Opzionale: le richieste decifrate degli agenti che instradi attraverso Flowlight e le chiamate agli strumenti che le hanno prodotte. La ricerca entra nei corpi di richieste e risposte.
Stato del Collector, canali dei dispositivi e copertura dei nomi in tre schede.
-
Le scorciatoie seguono l'ordine della barra laterale: ⌘0 è il decimo elemento e l'undicesimo resta disponibile senza inventare un tasto.
+
Le scorciatoie seguono l'ordine visibile della barra laterale. Le versioni Developer ID includono Ispeziona su ⌘7; quelle App Store lo omettono, quindi Regole e Origini passano a ⌘7 e ⌘8.
In diretta, la schermata con cui Flowlight si apre.
@@ -406,7 +404,7 @@
Rifiutare le connessioni
rifiuterà anche: la connessione viene interrotta e un avviso registra cosa è stato rifiutato, con Consenti … da ora in poi per aggiungerlo
all'elenco con un clic. Il tentativo successivo dell'agente passa.
Richiede l'estensione di rete. Rifiutare una connessione significa stare sul suo percorso, cosa che il campionatore nettop
- non può fare: Acquisizione lo dice, invece di offrire un interruttore che non fa nulla.
+ non può fare: Origini › Collector lo dice, invece di offrire un interruttore che non fa nulla.
Alcune cose non vengono mai rifiutate, qualunque cosa dica un elenco: la tua rete locale, il DNS, i servizi di Apple e il traffico di Flowlight
stesso. Un Mac bloccato è un esito peggiore di un agente bloccato, quindi nel dubbio la connessione viene consentita e registrata.
L'applicazione decade anche pochi secondi dopo che Flowlight smette di funzionare: un rifiuto che nessuno può vedere è peggio di nessun rifiuto, e il modo
@@ -438,8 +436,8 @@
Protezioni per gli agenti: bloccare uno strumento, un server
Questa non è una sandbox. Uno strumento rifiutato non viene più offerto e non riceve più risposta. Un agente che ha ancora una
shell può fare a mano ciò che avrebbe fatto lo strumento. Flowlight lo registra; non pretende di impedirlo.
-
Acquisizione: motori e origini
-
Flowlight registra il traffico in uno di due modi, da scegliere in Acquisizione. Differiscono per ciò che possono perdere, e vale
+
Origini: Collector e motori
+
Flowlight registra il traffico in uno di due modi, da scegliere in Origini › Collector. Differiscono per ciò che possono perdere, e vale
la pena capirlo prima di affidarsi all'uno o all'altro.
campionatore nettop (predefinito)
estensione di rete
@@ -465,7 +463,7 @@
Acquisizione: motori e origini
e lasciando invariata l'origine che hai scelto. Riprova con l'estensione, sotto Estensione di rete, ricomincia da capo.
Su alcuni Mac non può proprio funzionare. macOS consente un solo filtro di contenuto alla volta, e normalmente lo occupa il software
di sicurezza aziendale — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e simili. Su quelle macchine il filtro di Flowlight si installa e si connette,
- e poi non riceve mai una connessione. Acquisizione elenca quelli che trova e propone di riportarti al campionatore, che
+ e poi non riceve mai una connessione. Origini › Collector elenca quelli che trova e propone di riportarti al campionatore, che
non richiede alcun filtro e convive con loro.
Vedi la guida per sviluppatori per come è costruito.
@@ -535,7 +533,7 @@
Esecuzione in background
hai. La configurazione dei nomi host viene proposta un po' dopo l'avvio e solo mentre una finestra è aperta, invece di accogliere il primo avvio con una
richiesta della password; la proposta ritorna al lancio successivo finché non l'accetti o non la rifiuti.
Chiudere Flowlight ferma il campionatore. Non ferma l'estensione di rete: un'estensione di sistema funziona per conto proprio, quindi il filtro
- continua a ispezionare le connessioni finché non lo disattivi o lo disinstalli in Acquisizione.
+ continua a ispezionare le connessioni finché non lo disattivi o lo disinstalli in Origini › Collector.
Esportazione verso OpenTelemetry o un SIEM
Disattivata finché non la configuri, e non esiste alcun servizio Flowlight a cui inviare. Indichi tu l'endpoint — il tuo
@@ -575,7 +573,7 @@
Esportazione verso OpenTelemetry o un SIEM
I tuoi dati
Tutto si trova in ~/Library/Application Support/Flowlight/traffic.sqlite. Le righe al secondo vengono conservate 6 ore
(regolabile), quelle al minuto 14 giorni, quelle orarie 400 giorni, quelle giornaliere a tempo indeterminato e gli avvisi 90 giorni.
- Acquisizione › Cancella tutti i dati le elimina.
+ Impostazioni › Dati e privacy › Cancella tutti i dati le elimina.
Aggiornamenti
Quando compare una nuova versione, Flowlight te lo dice con una notifica e un contrassegno nella barra laterale, invece di interrompere quello che stai
@@ -594,7 +592,7 @@
Modalità demo
Disinstallazione
-
In Acquisizione, scegli Revoca l'accesso all'acquisizione dei pacchetti (chiede la password) se l'avevi attivato,
+
In Origini › Collector, scegli Revoca l'accesso all'acquisizione dei pacchetti (chiede la password) se l'avevi attivato,
disinstalla il filtro di contenuto se l'avevi installato e disattiva l'ispezione HTTPS in Ispeziona così il suo certificato
esce dal portachiavi. Solo Flowlight stesso può ritirare queste tre cose.
Chiudi Flowlight e spostalo da Applicazioni al Cestino — oppure, se l'hai installato con Homebrew,
@@ -613,18 +611,18 @@
Domande e risposte
di macOS una volta al secondo e registra la variazione, quindi un trasferimento lungo è conteggiato con esattezza — ma una connessione che si apre e si
chiude tra due letture non compare affatto. L'estensione di rete viene chiamata da macOS a ogni connessione stabilita, quindi
anche una richiesta di cinque millisecondi viene registrata. Se stai osservando un agente IA che scatena molte richieste brevi, installa
- l'estensione da Acquisizione. Il confronto completo è qui sopra.
+ l'estensione da Origini › Collector. Il confronto completo è qui sopra.
Ho attivato l'estensione di rete e non compare nulla. Il campionatore funziona bene.
Quasi sempre perché un altro filtro di contenuto occupa già il posto. macOS esegue un solo filtro di contenuto alla volta, e
di solito lo rivendica il software di sicurezza aziendale — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e simili. Il filtro di
- Flowlight si installa, si attiva e si connette comunque, quindi Acquisizione dice Connesso all'estensione filtro, ma macOS non gli consegna mai una
- sola connessione e le schermate restano vuote. Acquisizione elenca i filtri che trova e propone di riportarti al
+ Flowlight si installa, si attiva e si connette comunque, quindi Origini › Collector dice Connesso all'estensione filtro, ma macOS non gli consegna mai una
+ sola connessione e le schermate restano vuote. Origini › Collector elenca i filtri che trova e propone di riportarti al
campionatore, che non usa un filtro e convive con loro. Perdi solo le connessioni molto brevi
(il confronto); tutto il resto viene registrato allo stesso modo.
L'estensione ha smesso di funzionare dopo l'aggiornamento di Flowlight.
Le versioni prima della 0.2.5 avevano questo problema: macOS continua a eseguire la build dell'estensione attivata per ultima, quindi dopo un aggiornamento
l'estensione era la versione vecchia e macOS rifiuta la connessione tra una coppia non corrispondente. Dalla 0.2.5 Flowlight controlla all'avvio
- e riattiva il filtro da sé. Su una versione più vecchia, premi una volta Installa e attiva il filtro in Acquisizione.
+ e riattiva il filtro da sé. Su una versione più vecchia, premi una volta Installa e attiva il filtro in Origini › Collector.
C'è qualcos'altro che non va nell'acquisizione e non so cosa.
Esegui questo e leggi cosa stampa — riporta solo stato e conteggi, mai nulla di ciò che Flowlight ha registrato sul tuo traffico:
Dove è finito tutto? Dal secondo all'anno, per app, desti
Avvisi
Cosa non tornava? Avvisi per app, spiegati, con la destinazione e la soglia.
⌘5
-
Regole
Cosa ho rifiutato, e sta funzionando? Ogni regola, che cosa ha bloccato e il flusso di tutte le decisioni.
⌘8
+
Regole
Cosa ho rifiutato, e sta funzionando? Ogni regola, che cosa ha bloccato e il flusso di tutte le decisioni.
⌘8 · Developer ID / ⌘7 · App Store
Chiedi
Domande in linguaggio naturale, con risposte tratte dalla cronologia e sotto l'elenco di tutte le query eseguite.
⌘6
-
-
Dispositivi
Bluetooth, USB e fotocamere: che cosa è abbinato, collegato o attivo e quando è cambiato. Disattivato finché non lo attivi.
⌘9
+
+
Origini
I dati stanno arrivando, quanti hanno un nome e quali canali dei dispositivi sono attivi? Collector, Dispositivi e Copertura in un unico posto.
⌘9 · Developer ID / ⌘8 · App Store
-
Ispeziona
Opzionale. Cosa ha inviato davvero l'agente, e quale chiamata a uno strumento l'ha prodotta? Richieste decifrate, chiamate agli strumenti, risultati.
⌘7
+
Ispeziona
Opzionale. Cosa ha inviato davvero l'agente, e quale chiamata a uno strumento l'ha prodotta? Richieste decifrate, chiamate agli strumenti, risultati.
⌘7 · Developer ID
Connessioni
Che cosa comunica? Una mappa Sankey ingrandibile del traffico delle app e dei percorsi comprovati degli agenti IA, con un elenco esatto equivalente.
⌘4
@@ -454,7 +454,7 @@
In funzione in meno di un minuto
linee di base per le anomalie e regole pensate per gli agenti IA. Convivono bene.
Perché mi chiede la password?
macOS permette di leggere i pacchetti di rete solo agli amministratori. La configurazione iniziale dà al tuo account l'accesso in lettura,
- esattamente come fa Wireshark. Puoi revocarlo quando vuoi dalla schermata Acquisizione.
+ esattamente come fa Wireshark. Puoi revocarlo quando vuoi da Origini › Collector.
Può dire quale server MCP o quale strumento ha fatto una richiesta?
Sì, a livello di processo. Flowlight risale da ogni processo all'agente che lo ha avviato, così il curl di uno strumento shell
o le connessioni di un server MCP vengono attribuite a quell'agente, e i server MCP prendono il nome dalle configurazioni di Claude Code, Claude
diff --git a/site/pages/it/privacy.html b/site/pages/it/privacy.html
index 11985fb3..7dc7a416 100644
--- a/site/pages/it/privacy.html
+++ b/site/pages/it/privacy.html
@@ -66,7 +66,7 @@
Richieste di rete che fa l'app
Permessi
-
Password di amministratore, una volta, per l'accesso all'acquisizione dei pacchetti. Revocabile dalla schermata Acquisizione.
+
Password di amministratore, una volta, per l'accesso all'acquisizione dei pacchetti. Revocabile da Origini › Collector.
Notifiche, per gli avvisi. Facoltative.
Elemento di login, solo se attivi Avvia all'accesso.
strumento di monitoraggio su macOS può impedirlo e restare al tempo stesso uno strumento che puoi spegnere anche tu.
L'affermazione onesta è più stretta e resta utile: il software che si comporta male ma non sta attivamente sfuggendo a un monitoraggio viene
visto. Il software che vi sta attivamente sfuggendo può non essere visto, e lascerà almeno un buco — un'estensione che si è fermata, un periodo
- senza dati — che la schermata Copertura è lì per mostrare.
I servizi di sistema esenti dai filtri di contenuto. macOS non mostra tutto a un filtro di contenuto; una parte del suo
traffico non arriva mai al nostro.
Un altro filtro di contenuto che occupa il posto. macOS ne esegue uno alla volta. Se ce l'ha una VPN o un agente di
- sicurezza, il filtro di Flowlight si installa, si connette e non gli viene mai chiesto di filtrare nulla: Acquisizione lo dice, invece di
+ sicurezza, il filtro di Flowlight si installa, si connette e non gli viene mai chiesto di filtrare nulla: Origini › Collector lo dice, invece di
mostrare una schermata vuota.
Le connessioni brevi, con il campionatore. Senza l'estensione, Flowlight legge i contatori una volta al secondo: una
connessione che si apre e si chiude tra due letture non viene mai registrata.
@@ -82,7 +82,7 @@
Cosa sfugge all'ispezione
L'ispezione HTTPS legge solo ciò che viene instradato attraverso il proxy locale di Flowlight, e questo lo decide un programma quando parte.
Un'app che ignora le impostazioni proxy, una avviata prima che l'ispezione fosse attivata, o una che applica il pinning dei certificati passa
intatta — deliberatamente, perché rompere una connessione con pinning romperebbe l'app. Nemmeno QUIC viene offerto al proxy.
-
Quindi una schermata Ispeziona vuota significa «qui non è stato instradato nulla», non «non è successo nulla». Copertura dice quale delle due
+
Quindi una schermata Ispeziona vuota significa «qui non è stato instradato nulla», non «non è successo nulla». Origini › Copertura dice quale delle due
cose valga, app per app.
ネットワーク所有者を特定をオンにすると、ホスト名のないトラフィックにアドレスの運用者名が付きます
(Cloudflare, Inc. · AS13335)。デフォルトでオンで、そうしたパブリックな IP アドレス(プライベートなものは決して送りません)を
- Team Cymru の DNS サービスに送信します。キャプチャでオフにできます。
+ Team Cymru の DNS サービスに送信します。ソース › コレクターでオフにできます。
커널의 필터가 나머지 패킷을 Flowlight가 보기 전에 버리며, 패킷 내용은 저장하지 않습니다.
macOS는 관리자만 패킷을 읽게 하므로 트래픽에 이름 붙이기 창이 암호를 한 번 묻습니다. 이때
/Library/LaunchDaemons/com.flowlight.bpf-access.plist를 설치하며, 이것이 부팅마다 access_bpf
- 그룹에 /dev/bpf* 읽기 권한을 줍니다. Wireshark와 같은 방식입니다. 캡처 › 패킷 캡처 권한 제거에서 언제든 되돌릴 수 있습니다.
+ 그룹에 /dev/bpf* 읽기 권한을 줍니다. Wireshark와 같은 방식입니다. 소스 › 컬렉터 › 패킷 캡처 권한 제거에서 언제든 되돌릴 수 있습니다.
네트워크 소유자 확인은 호스트 이름이 없는 트래픽에 그 주소를 운영하는 주체의 이름을 붙입니다
(Cloudflare, Inc. · AS13335). 기본값은 켬이며, 그런 공용 IP 주소만(사설 주소는 절대 보내지 않습니다) Team Cymru의
- DNS 서비스로 보냅니다. 캡처에서 끌 수 있습니다.
단축키는 사이드바 순서를 따릅니다. ⌘0은 열 번째 항목이고, 열한 번째 항목은 억지로 키를 만들지 않아도 계속 사용할 수 있습니다.
+
단축키는 보이는 사이드바 순서를 따릅니다. Developer ID 빌드에는 ⌘7의 검사가 있고, App Store 빌드에는 없으므로 규칙과 소스가 ⌘7과 ⌘8로 이동합니다.
실시간, Flowlight가 처음 여는 화면.
@@ -401,7 +399,7 @@
연결 거부
알림이 무엇을 거부했는지 기록하며, 클릭 한 번으로 목록에 추가하는 이제부터 … 허용이 함께 붙습니다. 에이전트의
다음 시도는 통과합니다.
네트워크 확장이 필요합니다. 연결을 거부한다는 것은 그 경로에 앉아 있다는 뜻인데, nettop 샘플러는 그럴 수
- 없습니다. 캡처는 아무 일도 하지 않는 스위치를 내놓기보다 그렇다고 알려줍니다.
+ 없습니다. 소스 › 컬렉터는 아무 일도 하지 않는 스위치를 내놓기보다 그렇다고 알려줍니다.
목록에 무엇이 적혀 있든 절대 거부하지 않는 것도 있습니다. 로컬 네트워크와 DNS, Apple 기본 서비스, 그리고 Flowlight 자신의
트래픽입니다. 막힌 Mac은 막힌 에이전트보다 나쁜 결과이므로, 애매할 때는 연결을 허용하고 기록합니다. 또한 Flowlight가 멈추면
몇 초 뒤에 적용이 풀립니다. 아무도 볼 수 없는 거부는 거부가 없는 것보다 나쁘고, 그것을 되돌리는 방법은 앱 안에 있기
@@ -433,8 +431,8 @@
에이전트 가드레일: 도구나 서버, 리소스를
이것은 샌드박스가 아닙니다. 거부된 도구는 더 이상 제공되지도, 응답되지도 않습니다. 하지만 셸이 남아 있는
에이전트는 그 도구가 하던 일을 직접 할 수 있습니다. Flowlight는 그것을 기록합니다. 막아 주는 척하지는 않습니다.
-
캡처: 엔진과 소스
-
Flowlight는 캡처에서 고르는 두 가지 방식 중 하나로 트래픽을 기록합니다. 두 방식은 무엇을 놓칠 수 있는지가
+
소스: 컬렉터와 엔진
+
Flowlight는 소스 › 컬렉터에서 고르는 두 가지 방식 중 하나로 트래픽을 기록합니다. 두 방식은 무엇을 놓칠 수 있는지가
다르므로, 어느 쪽에 의지하기 전에 알아 둘 만합니다.
nettop 샘플러(기본값)
네트워크 확장
@@ -459,7 +457,7 @@
캡처: 엔진과 소스
확장 다시 시도로 처음부터 다시 할 수 있습니다.
어떤 Mac에서는 아예 돌지 못합니다. macOS는 콘텐츠 필터를 한 번에 하나만 허용하고, 보통 기업용 보안
소프트웨어가 그 자리를 차지합니다. Palo Alto Networks GlobalProtect, CrowdStrike Falcon 같은 것들이죠. 그런 Mac에서는
- Flowlight의 필터가 설치되고 연결까지 되지만 연결을 단 하나도 건네받지 못합니다. 캡처는 찾아낸 필터를 나열하고, 필터가 필요
+ Flowlight의 필터가 설치되고 연결까지 되지만 연결을 단 하나도 건네받지 못합니다. 소스 › 컬렉터는 찾아낸 필터를 나열하고, 필터가 필요
없고 그것들과 나란히 동작하는 샘플러로 되돌려 주겠다고 제안합니다.
어떻게 만들었는지는 개발자 가이드를 보세요.
@@ -527,7 +525,7 @@
백그라운드에서 실행
숨지 않게 하고, 저장된 위치가 화면 밖인 창(연결이 빠진 디스플레이)은 지금 있는 화면으로 돌아옵니다. 호스트 이름 설정은 첫
실행을 암호 요청으로 맞이하지 않고, 실행 후 조금 뒤에, 그리고 창이 열려 있을 때만 권합니다. 수락하거나 닫을 때까지 다음
실행에 다시 나타납니다.
-
Flowlight를 종료하면 샘플러가 멈춥니다. 네트워크 확장은 멈추지 않습니다. 시스템 확장은 스스로 돌기 때문에, 캡처에서
+
Flowlight를 종료하면 샘플러가 멈춥니다. 네트워크 확장은 멈추지 않습니다. 시스템 확장은 스스로 돌기 때문에, 소스 › 컬렉터에서
비활성화하거나 제거할 때까지 필터는 계속 연결을 살펴봅니다.
OpenTelemetry나 SIEM으로 내보내기
@@ -565,7 +563,7 @@
OpenTelemetry나 SIEM으로 내보내기
내 데이터
모든 것은 ~/Library/Application Support/Flowlight/traffic.sqlite에 있습니다. 초 단위 데이터는 6시간(조절
가능), 분 단위는 14일, 시간 단위는 400일, 일 단위는 무기한, 알림은 90일 보관합니다.
- 캡처 › 모든 데이터 지우기로 삭제합니다.
+ 설정 › 데이터 및 개인 정보 보호 › 모든 데이터 지우기로 삭제합니다.
업데이트
새 버전이 나오면 Flowlight는 하던 일을 끊지 않고 알림과 사이드바 배지로 알려줍니다. 둘 중 무엇을 클릭해도 업데이트 창이
@@ -585,7 +583,7 @@
소스 › 컬렉터에서, 켜 두었다면 패킷 캡처 권한 제거를 고르고(암호를 묻습니다), 설치했다면 콘텐츠
필터를 제거하고, 검사에서 HTTPS 검사를 꺼서 인증서가 키체인에서 빠지게 하세요. 이 세 가지는 Flowlight만
되돌릴 수 있습니다.
Flowlight를 종료하고 응용 프로그램에서 휴지통으로 옮기세요. Homebrew로 설치했다면
@@ -603,19 +601,19 @@
질문과 답
어떤 캡처 엔진을 쓰는지에 따라 다르고, 그 차이는 작지 않습니다. 기본 샘플러는 macOS의 누적 바이트 카운터를 1초에 한 번
읽어 변화를 기록하므로 긴 전송은 정확히 집계되지만, 두 번의 읽기 사이에 열리고 닫힌 연결은 아예 나타나지 않습니다.
네트워크 확장은 연결이 만들어질 때마다 macOS가 호출하므로 5밀리초짜리 요청도 기록됩니다. 짧은 요청을 많이 내는 AI
- 에이전트를 지켜본다면 캡처에서 확장을 설치하세요. 전체 비교는 위에 있습니다.
거의 항상 다른 콘텐츠 필터가 이미 그 자리를 차지했기 때문입니다. macOS는 콘텐츠 필터를 한 번에 하나만
실행합니다. 보통 기업용 보안 소프트웨어가 그 자리를 가져갑니다. Palo Alto Networks GlobalProtect, CrowdStrike
- Falcon 같은 것들이죠. Flowlight의 필터는 설치되고 활성화되고 연결까지 되므로 캡처에는 Connected to filter
- extension이라고 나오지만, macOS가 연결을 단 하나도 건네주지 않아 화면이 비어 있습니다. 캡처는 찾아낸 필터를
+ Falcon 같은 것들이죠. Flowlight의 필터는 설치되고 활성화되고 연결까지 되므로 소스 › 컬렉터에는 Connected to filter
+ extension이라고 나오지만, macOS가 연결을 단 하나도 건네주지 않아 화면이 비어 있습니다. 소스 › 컬렉터는 찾아낸 필터를
나열하고 필터를 쓰지 않으며 그것들과 나란히 동작하는 샘플러로 되돌려 주겠다고 제안합니다. 이때 잃는 것은 아주
짧은 연결뿐이며(비교 표), 나머지는 똑같이 기록됩니다.
Flowlight를 업데이트한 뒤 확장이 동작하지 않습니다.
0.2.5 이전 버전에 있던 문제입니다. macOS는 마지막으로 활성화된 확장 빌드를 계속 실행하므로, 업데이트 뒤에는 확장이 예전
버전이 되고 macOS는 짝이 맞지 않는 둘 사이의 연결을 거부합니다. 0.2.5부터는 Flowlight가 실행할 때 확인해 필터를 스스로
- 다시 활성화합니다. 그보다 낮은 버전이라면 캡처에서 필터 설치 및 활성화를 한 번 누르세요.
-
캡처에 다른 문제가 있는데 무엇인지 모르겠습니다.
+ 다시 활성화합니다. 그보다 낮은 버전이라면 소스 › 컬렉터에서 필터 설치 및 활성화를 한 번 누르세요.
+
소스 › 컬렉터에 다른 문제가 있는데 무엇인지 모르겠습니다.
이것을 실행하고 출력을 읽어 보세요. 상태와 개수만 보고하며, Flowlight가 트래픽에 대해 기록한 내용은 전혀 담기지 않습니다:
무엇을 거부했고, 실제로 막히고 있나? 모든 규칙과 각 규칙이 막은 것, 그리고 모든 판정의 기록.
⌘8
+
규칙
무엇을 거부했고, 실제로 막히고 있나? 모든 규칙과 각 규칙이 막은 것, 그리고 모든 판정의 기록.
⌘8 · Developer ID / ⌘7 · App Store
질문
평소 쓰는 말로 묻고 기록에서 답을 받습니다. 실행된 질의는 아래에 전부 표시됩니다.
⌘6
-
-
기기
Bluetooth, USB, 카메라: 무엇이 페어링, 연결 또는 사용 중이며 언제 바뀌었나. 직접 켜기 전까지는 끔.
⌘9
+
+
소스
데이터가 들어오는지, 이름이 붙은 비율과 활성 기기 채널은 어떤지. 컬렉터, 기기, 포착 범위를 한곳에서 봅니다.
⌘9 · Developer ID / ⌘8 · App Store
-
검사
선택 사항. 에이전트가 실제로 무엇을 보냈고, 어떤 도구 호출이 그렇게 했나? 복호화된 요청, 도구 호출, 결과.
⌘7
+
검사
선택 사항. 에이전트가 실제로 무엇을 보냈고, 어떤 도구 호출이 그렇게 했나? 복호화된 요청, 도구 호출, 결과.
⌘7 · Developer ID
연결
무엇이 통신하나? 앱 트래픽과 입증된 AI 에이전트 경로를 확대 가능한 Sankey 지도와 동일한 내용의 목록으로 보여 줍니다.
⌘4
@@ -454,7 +454,7 @@
1분 안에 돌아갑니다
이상 탐지 기준선, 그리고 AI 에이전트를 위해 만든 규칙. 둘을 나란히 써도 잘 맞습니다.
왜 암호를 묻습니까?
macOS는 관리자만 네트워크 패킷을 읽게 합니다. 한 번만 하는 설정으로 내 계정에 읽기 권한을 주는데, Wireshark도
- 같은 방식입니다. 캡처 화면에서 언제든 되돌릴 수 있습니다.
+ 같은 방식입니다. 소스 › 컬렉터에서 언제든 되돌릴 수 있습니다.
어떤 MCP 서버나 도구가 요청을 냈는지 알 수 있습니까?
프로세스 수준에서는 알 수 있습니다. Flowlight는 각 프로세스를 시작한 에이전트까지 거슬러 올라가므로, 셸 도구의
curl이나 MCP 서버의 연결이 그 에이전트에 귀속되고, MCP 서버의 이름은 Claude Code, Claude Desktop, Cursor, Windsurf,
diff --git a/site/pages/ko/privacy.html b/site/pages/ko/privacy.html
index 39982ae1..379a8988 100644
--- a/site/pages/ko/privacy.html
+++ b/site/pages/ko/privacy.html
@@ -67,7 +67,7 @@
root 권한을 가진 소프트웨어는 이것을 끌 수 있습
macOS의 어떤 모니터링 도구도 사용자가 스스로 끌 수 있는 도구로 남아 있으면서 그것을 막을 수는 없습니다.
솔직한 주장은 더 좁고, 그래도 쓸모가 있습니다. 나쁘게 행동하지만 감시를 적극적으로 피하지는 않는 소프트웨어는 보입니다. 적극적으로
피하는 소프트웨어는 보이지 않을 수 있고, 적어도 빈자리는 남깁니다. 멈춘 확장, 데이터가 없는 구간 같은 것들이죠.
- 포착 범위 화면은 바로 그것을 보여주기 위해 있습니다.
콘텐츠 필터 적용에서 빠지는 시스템 서비스. macOS는 콘텐츠 필터에 모든 것을 보여주지 않습니다. macOS 자신의
트래픽 가운데 일부는 우리 필터에 결코 닿지 않습니다.
그 자리를 다른 콘텐츠 필터가 차지한 경우. macOS는 한 번에 하나만 돌립니다. VPN이나 보안 에이전트가 그
- 자리를 갖고 있으면 Flowlight의 필터는 설치되고 연결까지 되지만 무엇을 걸러 달라는 요청은 한 번도 받지 못합니다. 캡처는 빈
+ 자리를 갖고 있으면 Flowlight의 필터는 설치되고 연결까지 되지만 무엇을 걸러 달라는 요청은 한 번도 받지 못합니다. 소스 › 컬렉터는 빈
화면을 보여주는 대신 그렇다고 말합니다.
짧은 연결, 샘플러를 쓸 때. 확장이 없으면 Flowlight는 1초에 한 번 카운터를 읽습니다. 두 번의 읽기 사이에
열리고 닫히는 연결은 결코 기록되지 않습니다.
@@ -83,7 +83,7 @@
검사가 놓치는 것
무시하는 앱, 검사를 켜기 전에 시작된 앱, 인증서를 고정하는 앱은 손대지 않고 그대로 통과합니다. 일부러 그렇게 합니다. 고정된 연결을
깨뜨리면 그 앱이 깨지기 때문입니다. QUIC도 프록시에 건네지지 않습니다.
그래서 검사 화면이 비어 있다는 것은 “여기로 아무것도 지나가지 않았다”는 뜻이고, “아무 일도 없었다”는 뜻이 아닙니다. 둘 중
- 어느 쪽인지는 포착 범위가 앱마다 알려줍니다.
+ 어느 쪽인지는 소스 › 포착 범위가 앱마다 알려줍니다.
차단이 무엇이고 무엇이 아닌지
연결을 거부하는 규칙은 보통 네트워크 확장이 그 경로 안에서, 연결이 만들어지기 전에 실행합니다. HTTPS 검사를 거치는 트래픽은
diff --git a/site/pages/privacy.html b/site/pages/privacy.html
index 49244612..e123ca8d 100644
--- a/site/pages/privacy.html
+++ b/site/pages/privacy.html
@@ -65,7 +65,7 @@
Network requests the app makes
Update download
github.com
The disk image and its checksum file
Only when you click Download & Open
Official rule-pack update
flowlight.xinbetween.com
A standard HTTPS request to the fixed official feed for a publisher-signed catalog. The server sees your IP address, the Flowlight/<version> user agent, and conditional cache validators; it receives no traffic, pack settings, or device identifier
After startup when due and then at most daily while healthy. On by default; off switch and manual Check Now in Rules › Packs
Reverse DNS
Your configured DNS resolver
A lookup of an IP address's registered name, when no hostname was seen
As needed, in the sampler capture mode, which is the default until the Network Extension is running. No off switch: without it the sampler cannot name most connections. The Network Extension names them from the traffic itself and does not do this
-
Network owner lookup
Team Cymru, over DNS
Public IP addresses with no known hostname. Private and reserved addresses never leave your Mac
On by default. Off switch in Capture › Identify network owners
+
Network owner lookup
Team Cymru, over DNS
Public IP addresses with no known hostname. Private and reserved addresses never leave your Mac
On by default. Off switch in Sources › Collector › Identify network owners
Ask with a hosted model
The provider you select: Anthropic, OpenAI, Google Gemini or a compatible endpoint
Your question and the results returned by the read-only Flowlight queries selected by the model. The traffic database itself is not uploaded
Only when you select a hosted provider and submit a question. The Ask screen shows the transmitted requests
Collector export
The OpenTelemetry or HTTP endpoint you configure
The fields shown in Settings › Export, such as traffic rollups and alerts. Authentication headers are stored in Keychain
Only after you configure an endpoint and enable export
Inspected application traffic
The original destination requested by the inspected application
The application's request, forwarded through Flowlight's local proxy after decryption
Only while HTTPS inspection is enabled and the application is routed through the proxy
@@ -73,14 +73,14 @@
Network requests the app makes
Permissions
-
Administrator password, once, for packet-capture access. Removable from the Capture screen.
+
Administrator password, once, for packet-capture access. Removable from Sources › Collector.
Notifications, for warnings. Optional.
Login item, only if you turn on Launch at login.
Retention
Per-second data 6 hours (adjustable), minute data 14 days, hourly data 400 days, daily totals indefinitely, alerts 90 days.
- Capture › Clear all data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
+ Settings › Data & Privacy › Clear All Data deletes everything, and removing ~/Library/Application Support/Flowlight does the same.
This website
This site is a static page hosted on GitHub Pages and served through Cloudflare. It sets no cookies and runs no analytics. GitHub
diff --git a/site/pages/pt-PT/docs.html b/site/pages/pt-PT/docs.html
index 2f89fc44..ef6724b9 100644
--- a/site/pages/pt-PT/docs.html
+++ b/site/pages/pt-PT/docs.html
@@ -35,7 +35,7 @@
Um filtro no núcleo descarta todos os outros pacotes antes de o Flowlight os ver, e o conteúdo dos pacotes nunca é guardado.
O macOS só permite que os administradores leiam pacotes, por isso a janela Dê nome ao seu tráfego pede a sua palavra-passe uma vez. Instala o
/Library/LaunchDaemons/com.flowlight.bpf-access.plist, que dá ao grupo access_bpf acesso de leitura a
- /dev/bpf* em cada arranque, a mesma abordagem que o Wireshark usa. Remova-o quando quiser em Captura › Remover o acesso à captura de pacotes.
+ /dev/bpf* em cada arranque, a mesma abordagem que o Wireshark usa. Remova-o quando quiser em Origens › Coletor › Remover o acesso à captura de pacotes.
Identificar os proprietários da rede etiqueta o tráfego sem nome de anfitrião com quem opera o endereço
(Cloudflare, Inc. · AS13335). Está ativado por predefinição e envia esses endereços IP públicos (nunca os privados) para o serviço
- DNS da Team Cymru. Desative-o em Captura.
+ DNS da Team Cymru. Desative-o em Origens › Coletor.
Idioma
O Flowlight está traduzido em inglês, 简体中文, 繁體中文, 日本語, 한국어, Français, Deutsch, Italiano, Español e
@@ -99,14 +99,12 @@
As vistas
Histórico
⌘3
Para onde foi o tráfego, do segundo ao ano. Agrupe por App, Destino ou IP; mude para Gráficos ou Vale a pena ver; exporte em CSV.
Um mapa estável das aplicações e dos destinos exatos, com caminhos ponderados, marcadores de direção em movimento, contagens de ligações e uma lista equivalente.
Opcional: pedidos desencriptados dos agentes que encaminha pelo Flowlight e as chamadas de ferramentas por trás deles. A pesquisa entra nos corpos dos pedidos e das respostas.
Opcional: pedidos desencriptados dos agentes que encaminha pelo Flowlight e as chamadas de ferramentas por trás deles. A pesquisa entra nos corpos dos pedidos e das respostas.
Estado do coletor, canais de dispositivos e cobertura de nomes em três separadores.
-
Os atalhos seguem a ordem da barra lateral: ⌘0 é o décimo item e o décimo primeiro continua disponível sem inventar uma tecla.
+
Os atalhos seguem a ordem visível da barra lateral. As versões Developer ID incluem Inspecionar em ⌘7; as versões App Store omitem-no, por isso Regras e Origens passam para ⌘7 e ⌘8.
Em direto, a vista com que o Flowlight abre.
@@ -408,7 +406,7 @@
Recusar ligações
vai recusar: a ligação é cortada e um alerta regista o que foi recusado, com Permitir … de agora em diante para o acrescentar
à lista num clique. A tentativa seguinte do agente passa.
Precisa da extensão de rede. Recusar uma ligação significa estar no seu caminho, o que o amostrador nettop
- não consegue fazer — a Captura di-lo, em vez de oferecer um interruptor que não faz nada.
+ não consegue fazer — Origens › Coletor di-lo, em vez de oferecer um interruptor que não faz nada.
Algumas coisas nunca são recusadas, diga a lista o que disser: a sua rede local, o DNS, os serviços da Apple e o tráfego do próprio
Flowlight. Um Mac bloqueado é um resultado pior do que um agente bloqueado, por isso, na dúvida, a ligação é permitida e registada.
A aplicação efetiva também caduca uns segundos depois de o Flowlight deixar de correr — uma recusa que ninguém consegue ver é pior do que nenhuma, e a maneira
@@ -440,8 +438,8 @@
Proteções dos agentes: bloquear uma ferramenta, um servido
Isto não é uma sandbox. Uma ferramenta recusada deixa de ser oferecida e deixa de ser respondida. Um agente que ainda tenha uma
shell pode fazer à mão o que a ferramenta teria feito. O Flowlight vai registá-lo; não finge impedi-lo.
-
Captura: motores e origens
-
O Flowlight regista o tráfego de uma de duas formas, escolhida em Captura. Diferem no que podem deixar escapar, e vale a pena
+
Origens: coletor e motores
+
O Flowlight regista o tráfego de uma de duas formas, escolhida em Origens › Coletor. Diferem no que podem deixar escapar, e vale a pena
entender isso antes de confiar numa delas.
amostrador nettop (predefinição)
extensão de rede
@@ -467,7 +465,7 @@
Captura: motores e origens
e deixando a sua origem escolhida em paz. Tentar a extensão de novo, em Extensão de rede, começa do início.
Também há Macs onde não consegue correr de forma alguma. O macOS permite um filtro de conteúdo de cada vez, e o software de segurança das
empresas normalmente ocupa-o — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e semelhantes. O filtro do Flowlight instala-se e liga-se nessas
- máquinas, mas nunca lhe é entregue uma ligação. A Captura lista os que encontrar e propõe voltar ao amostrador, que
+ máquinas, mas nunca lhe é entregue uma ligação. O Coletor em Origens lista os que encontrar e propõe voltar ao amostrador, que
não precisa de filtro e funciona ao lado deles.
Veja o guia de desenvolvimento para saber como é construído.
@@ -535,7 +533,7 @@
Executar em segundo plano
tem. A configuração dos nomes de anfitrião é proposta um pouco depois da abertura e só enquanto uma janela está aberta, em vez de receber uma primeira execução com um
pedido de palavra-passe; a proposta volta na abertura seguinte até a aceitar ou a rejeitar.
Sair do Flowlight interrompe o amostrador. Não interrompe a extensão de rede: uma extensão de sistema corre por si, por isso o filtro
- continua a inspecionar ligações até a desativar ou desinstalar em Captura.
+ continua a inspecionar ligações até a desativar ou desinstalar em Origens › Coletor.
Exportar para OpenTelemetry ou para um SIEM
Desativado até o configurar, e não existe nenhum serviço Flowlight para onde enviar. É você que nomeia o endpoint — o seu
@@ -571,7 +569,7 @@
Exportar para OpenTelemetry ou para um SIEM
Os seus dados
Tudo fica em ~/Library/Application Support/Flowlight/traffic.sqlite. As linhas por segundo são mantidas 6 horas
(ajustável), as por minuto 14 dias, as horárias 400 dias, as diárias indefinidamente, e os alertas 90 dias.
- Captura › Apagar todos os dados elimina tudo.
+ Definições › Dados e privacidade › Apagar todos os dados elimina tudo.
Atualizações
Quando aparece uma versão nova, o Flowlight avisa-o com uma notificação e um sinal na barra lateral, em vez de interromper o que está a
@@ -590,7 +588,7 @@
Modo de demonstração
Desinstalação
-
Em Captura, escolha Remover o acesso à captura de pacotes (pede a sua palavra-passe) se o tiver ativado,
+
Em Origens › Coletor, escolha Remover o acesso à captura de pacotes (pede a sua palavra-passe) se o tiver ativado,
desinstale o filtro de conteúdo se o tiver instalado, e desative a inspeção HTTPS em Inspecionar para que o seu certificado
saia do porta-chaves. Só o próprio Flowlight pode retirar essas três coisas.
Saia do Flowlight e mova-o da pasta Aplicações para o Lixo — ou, se o instalou com o Homebrew,
@@ -609,18 +607,18 @@
Perguntas e respostas
acumulados do macOS uma vez por segundo e regista a variação, por isso uma transferência longa é contada com exatidão — mas uma ligação que abre e
fecha entre duas leituras nunca aparece. A extensão de rede é chamada pelo macOS a cada ligação que é feita, por isso
até um pedido de cinco milissegundos é registado. Se está a vigiar um agente de IA que dispara muitos pedidos curtos, instale a
- extensão em Captura. A comparação completa está acima.
+ extensão em Origens › Coletor. A comparação completa está acima.
Ativei a extensão de rede e não aparece nada. O amostrador funciona bem.
Quase sempre porque outro filtro de conteúdo já ocupa o lugar. O macOS executa um filtro de conteúdo de cada vez, e o
software de segurança das empresas normalmente reclama-o — Palo Alto Networks GlobalProtect, CrowdStrike Falcon e semelhantes. O filtro do Flowlight
- instala-se, ativa-se e liga-se, por isso a Captura diz Ligado à extensão de filtro, mas o macOS nunca lhe entrega uma
- única ligação e os ecrãs ficam vazios. A Captura lista os filtros que encontra e propõe voltar ao
+ instala-se, ativa-se e liga-se, por isso Origens › Coletor diz Ligado à extensão de filtro, mas o macOS nunca lhe entrega uma
+ única ligação e os ecrãs ficam vazios. O Coletor em Origens lista os filtros que encontra e propõe voltar ao
amostrador, que não usa filtro e funciona ao lado deles. Perde apenas as ligações muito curtas
(a comparação); todo o resto é registado da mesma maneira.
A extensão deixou de funcionar depois de o Flowlight se atualizar.
As versões anteriores à 0.2.5 tinham isto: o macOS continua a executar a versão da extensão que foi ativada por último, por isso, depois de uma atualização, a
extensão era a versão antiga e o macOS recusa a ligação entre um par que não corresponde. A partir da 0.2.5, o Flowlight verifica na abertura
- e volta a ativar o filtro sozinho. Numa versão mais antiga, prima Instalar e ativar o filtro na Captura uma vez.
+ e volta a ativar o filtro sozinho. Numa versão mais antiga, prima Instalar e ativar o filtro em Origens › Coletor uma vez.
Há outra coisa errada com a captura e não sei o que é.
Execute isto e leia o que imprime — comunica apenas estados e contagens, nunca nada do que o Flowlight registou sobre o seu tráfego:
Para onde foi tudo? Do segundo ao ano, agrupado por app, d
Alertas
O que pareceu errado? Alertas por app, explicáveis, com o destino e o limiar.
⌘5
-
Regras
O que recusei e está a acontecer? Todas as regras, o que cada uma bloqueou e um fluxo de todas as decisões.
⌘8
+
Regras
O que recusei e está a acontecer? Todas as regras, o que cada uma bloqueou e um fluxo de todas as decisões.
⌘8 · Developer ID / ⌘7 · App Store
Perguntar
Perguntas em linguagem comum, respondidas a partir do histórico — com todas as consultas que fez listadas abaixo.
⌘6
-
-
Dispositivos
Bluetooth, USB e câmaras: o que está emparelhado, ligado ou ativo e quando isso mudou. Desativado até o ativar.
⌘9
+
+
Origens
Os dados estão a chegar, quanto está identificado e que canais de dispositivos estão ativos? Coletor, Dispositivos e Cobertura num só lugar.
⌘9 · Developer ID / ⌘8 · App Store
-
Inspecionar
Opcional. O que é que o agente enviou de facto, e que chamada de ferramenta o fez? Pedidos desencriptados, chamadas de ferramentas, resultados.
⌘7
+
Inspecionar
Opcional. O que é que o agente enviou de facto, e que chamada de ferramenta o fez? Pedidos desencriptados, chamadas de ferramentas, resultados.
⌘7 · Developer ID
Ligações
O que está a comunicar? Um mapa Sankey ampliável do tráfego das apps e dos percursos comprovados dos agentes de IA, com uma lista exata equivalente.
⌘4
@@ -454,7 +454,7 @@
A funcionar em menos de um minuto
linhas de base para anomalias e regras feitas para agentes de IA. Funcionam bem lado a lado.
Porque é que pede a minha palavra-passe?
O macOS só permite que os administradores leiam pacotes de rede. A configuração inicial dá acesso de leitura à sua conta, da
- mesma forma que o Wireshark faz. Pode removê-lo quando quiser no ecrã Captura.
+ mesma forma que o Wireshark faz. Pode removê-lo quando quiser em Origens › Coletor.
Consegue dizer que servidor MCP ou que ferramenta fez um pedido?
Sim, ao nível do processo. O Flowlight segue cada processo até ao agente que o iniciou, pelo que o curl de uma ferramenta de shell
ou as ligações de um servidor MCP são atribuídos a esse agente, e os servidores MCP recebem o nome das configurações do Claude Code, Claude
diff --git a/site/pages/pt-PT/privacy.html b/site/pages/pt-PT/privacy.html
index 44189239..5395ff78 100644
--- a/site/pages/pt-PT/privacy.html
+++ b/site/pages/pt-PT/privacy.html
@@ -66,7 +66,7 @@
Pedidos de rede que a app faz
Permissões
-
Palavra-passe de administrador, uma vez, para o acesso à captura de pacotes. Removível no ecrã Captura.
+
Palavra-passe de administrador, uma vez, para o acesso à captura de pacotes. Removível em Origens › Coletor.
Notificações, para os avisos. Opcional.
Item de início de sessão, só se ativar Abrir ao iniciar sessão.
nenhuma ferramenta de monitorização no macOS o consegue impedir e continuar a ser uma ferramenta que também você pode desligar.
A afirmação honesta é mais estreita e continua a ser útil: o software que se porta mal mas não está ativamente a fugir a um monitor será
visto. O software que lhe está ativamente a fugir pode não ser, e deixará pelo menos uma falha — uma extensão que parou, um período sem
- dados — que o ecrã Cobertura está lá para mostrar.
Os serviços de sistema isentos dos filtros de conteúdo. O macOS não mostra tudo a um filtro de conteúdo; parte do seu
próprio tráfego nunca chega ao nosso.
Outro filtro de conteúdo a ocupar o lugar. O macOS executa um de cada vez. Se uma VPN ou um agente de segurança o
- tiver, o filtro do Flowlight instala-se, liga-se, e nunca lhe é pedido que filtre nada — a Captura di-lo, em vez de mostrar um ecrã
+ tiver, o filtro do Flowlight instala-se, liga-se, e nunca lhe é pedido que filtre nada — Origens › Coletor di-lo, em vez de mostrar um ecrã
vazio.
As ligações curtas, com o amostrador. Sem a extensão, o Flowlight lê contadores uma vez por segundo: uma ligação que
abre e fecha entre duas leituras nunca é registada.
@@ -82,7 +82,7 @@
O que escapa à inspeção
A inspeção HTTPS lê apenas o que é encaminhado pelo proxy local do Flowlight, e isso é um programa que o decide quando arranca. Uma app que
ignora as definições de proxy, uma que foi iniciada antes de a inspeção ser ligada, ou uma que fixa os seus certificados passa intacta — de
propósito, porque quebrar uma ligação com o certificado fixado quebraria a app. O QUIC também não é entregue ao proxy.
-
Por isso um ecrã Inspecionar vazio significa «não foi encaminhado nada para aqui», não «não aconteceu nada». A Cobertura diz qual das duas
+
Por isso um ecrã Inspecionar vazio significa «não foi encaminhado nada para aqui», não «não aconteceu nada». Origens › Cobertura diz qual das duas
coisas se aplica, app por app.
Keep every input in one operational home. Capture, Devices and Coverage are now Collector, Devices and Coverage tabs inside Sources, with a shared health summary and a step-by-step recovery card when traffic is not arriving.
+
Tune alerts where their results appear. Detection controls now live beside the alert list under Alerts › Detection, while database retention, location and deletion live in Settings › Data & Privacy.
+
Make independent verification genuinely parallel. Project drift, oldest and newest unit suites, the Store product, the site and prospective-merge compatibility are separate jobs; project generation is checked once and Store validation runs once.
+
Skip app work for website-only commits. The deny-first classifier routes Swift, Python and workflow CodeQL independently, and stable Review and CodeQL gates preserve one required status even when an analyzer is intentionally skipped.
+
+
+
+
+
0.17.2
Keep filtered evidence unmistakable. An active Focus now stays visible above every destination with its exact scope and one-click editing, while sidebar shortcuts follow the order shown on screen.
Make warning notifications respond immediately. Turning warnings on now requests macOS authorization in the same action, reports whether access is active, not requested, or denied, and opens System Settings when recovery is needed.
monitoring tool on macOS can prevent it while remaining a tool you can also turn off yourself.
The honest claim is narrower and still useful: software that is misbehaving but not actively evading a monitor will be seen.
Software that is actively evading one may not be, and will at least leave a gap — an extension that stopped, a period with no
- data — which the Coverage screen is there to show.
System services exempt from content filters. macOS does not show a content filter everything; some of its
own traffic never reaches ours.
Another content filter holding the slot. macOS runs one at a time. If a VPN or a security agent has it,
- Flowlight's filter installs, connects, and is never asked to filter anything — Capture says so rather than showing an empty
+ Flowlight's filter installs, connects, and is never asked to filter anything — Sources › Collector says so rather than showing an empty
screen.
Short connections, on the sampler. Without the extension, Flowlight reads counters once a second: a
connection that opens and closes between two readings is never recorded.
@@ -82,7 +82,7 @@
What inspection misses
HTTPS inspection reads only what is routed through Flowlight's local proxy, and a program decides that when it starts. An app
that ignores proxy settings, one started before inspection was switched on, or one that pins its certificates is passed through
untouched — deliberately, because breaking a pinned connection would break the app. QUIC is not offered to the proxy either.
-
So an empty Inspect screen means "nothing was routed here", not "nothing happened". Coverage says which of the two applies,
+
So an empty Inspect screen means "nothing was routed here", not "nothing happened". Sources › Coverage says which of the two applies,
per app.