Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
runs-on: macos-latest # 与 release 同款 runner,自带 Xcode / Swift 工具链与 Node
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: '1.23'

- name: 编译 debug(首次会拉取 Swifter / Sparkle)
run: swift build
Expand Down Expand Up @@ -70,6 +73,18 @@ jobs:
- name: 网页逐请求语言(Accept-Language)
run: ./tools/smoke-accept-language.sh

- name: 远程访问只读策略
run: ./tools/smoke-remote-readonly.sh

- name: 远程访问完整链路
run: ./tools/smoke-remote-e2e.sh

- name: Release 模式远程访问完整链路
run: |
swift build -c release
BIN=.build/release/LocalShare ./tools/smoke-remote-readonly.sh
CLIENT_BIN=.build/release/LocalShare ./tools/smoke-remote-e2e.sh

- name: 传递文本(/ls/text + 转义 + 虚拟根文本行)
run: ./tools/smoke-text.sh

Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ Release flow:
- **Threading model**: Swifter callbacks run on socket threads, while `AppState` is `@MainActor`. Shared mutable server state is protected by one `NSLock`: `share`, `token`, `uploadEnabled`, `lastSeen`, `nameCache`, and `nameLookupInFlight`.
- **Share changes do not restart the server** when the port is unchanged, but they rotate tokens immediately. Change the key before changing content.
- **`.raw` has no keep-alive and unknown body length**, so file responses must write `Content-Length`.
- **Remote mount prefix**: generated HTML must use relative navigation/heartbeat endpoints so it works under both `/`
and `/share/<token>/`; remote requests must carry the registered `share_id`, and the Client must reject stale IDs
before forwarding to `FileServer`.

## Design Constraint

Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[简体中文](README_CN.md) | English

A small macOS app that moves files and text between your Mac and other devices (phone, tablet…) over WiFi — the other end just uses a browser, with no client to install.
A small macOS app that moves files and text between your Mac and other devices (phone, tablet…) over WiFi, with optional browser-only remote sharing — the other end just uses a browser, with no client to install.

- Pick a file or folder, scan the QR code that appears (or just open the link), and browse the files in your phone's browser (HTML, PDF, Markdown, images…)
- Two-way text transfer — type some text and share it via a QR code, or send text back from the phone to the Mac
Expand All @@ -22,6 +22,7 @@ A small macOS app that moves files and text between your Mac and other devices (
- After you share, the other end can send files and text back
- Shows who's currently viewing
- `localshare` command line: bring up the window to share, or `--headless` to print the link and QR code in the terminal
- Optional browser-only remote access through a self-hosted LocalShare Server; remote shares are read-only

## Why this app exists

Expand All @@ -40,6 +41,10 @@ The QR code points to something like `http://192.168.x.x:8080/?t=<random-token>`

> ⚠️ Traffic is plain HTTP (unencrypted). Best avoided on public networks like airports and cafés.

### Remote browser sharing

Run the self-contained [`localshare-server`](server/README.md), create a one-time Enrollment Key, then enter the Server address and key in Settings. After pairing, the app remembers the device credential in Keychain; active shares use Connect/Disconnect and the receiving device only needs a browser. See the [remote-sharing plan](docs/REMOTE_SHARING_PLAN.md).

## Terminal usage

In Settings → Command-Line Tool, click "Install". After that you can share from the terminal in one command:
Expand Down
7 changes: 6 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

简体中文 | [English](README.md)

一个 macOS 小工具,在本机和手机等设备之间通过 WiFi 互通文件和文本,对端使用浏览器,无须安装客户端。
一个 macOS 小工具,在本机和手机等设备之间通过 WiFi 互通文件和文本,也支持可选的纯浏览器跨网络分享,对端无须安装客户端。

- 选中文件或文件夹,相机扫描出现的二维码,或直接打开链接,在手机浏览器里浏览这些文件(HTML、PDF、Markdown、图片……)
- 支持双向传送文本,编辑文字通过二维码分享后传输,并可从手机端发送文本回 Mac
Expand All @@ -22,6 +22,7 @@
- 支持分享后,由对端反向传输文件、文本
- 显示当前在线访客
- 命令行 `localshare` 命令:唤起窗口分享,或 `--headless` 在终端显示链接和二维码
- 可选通过自托管 LocalShare Server 远程访问浏览器;远程分享只读

## 为什么有这个 app

Expand All @@ -40,6 +41,10 @@

> ⚠️ 传输是明文 HTTP(没有加密)。机场咖啡厅等公共网络下最好不要使用。

### 远程浏览器分享

运行自包含的 [`localshare-server`](server/README.md),生成一次性 Enrollment Key,在「设置」里填写 Server 地址和 key。配对后设备凭据会保存到 Keychain;正在分享时只需点击 Connect/Disconnect,对端设备只需浏览器。详见[远程分享计划](docs/REMOTE_SHARING_PLAN.md)。

## 终端用法

在「设置 → 命令行工具」里点「安装」,之后可以在终端一键分享:
Expand Down
4 changes: 4 additions & 0 deletions Sources/LocalShare/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
NSApp.activate(ignoringOtherApps: true)
}

func applicationWillTerminate(_ notification: Notification) {
AppState.shared?.stop()
}

// 关窗不退出:菜单栏图标常驻,服务继续广播;退出走菜单栏「退出」或 ⌘Q。
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
false
Expand Down
Loading
Loading