Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

LarkFS

Mount Lark/Feishu as a local filesystem — FUSE & WebDAV

CIReleaseLicensePlatform


将飞书/Lark 的资源映射为本地可读写的文件目录。核心路径覆盖 Drive、Wiki、IM、Calendar、Tasks、Mail、Meetings,并通过控制节点提供 Application、Apps、Approval、Attendance、Base、Contact、Docs、Event、Markdown、Mindnotes、Minutes、Note、OKR、Sheets、Slides、VC、Whiteboard、_system 等命令型能力;_system 也暴露 skills list/read,用于读取当前 lark-cli 内嵌技能文档。

Why

  • cat /mnt/lark/wiki/产品文档/PRD.md — 直接用终端 / 编辑器读写飞书文档
  • ls /mnt/lark/im/团队群/ — 浏览消息、发送文本
  • echo "明天 10:00 周会" > /mnt/lark/calendar/_create.md — 创建日历事件
  • 在 Finder / Nautilus 中拖拽文件到飞书云空间

Features

能力说明
FUSE 挂载POSIX 风格语义,像本地目录一样 ls / cat / vim / cp
WebDAV 模式无需内核模块,Finder / 文件管理器直连
macOS Desktop app(预览)SwiftUI 宿主 app,汇总认证/挂载/健康状态,并开始接入 File Provider 原生挂载
多类型文档docx → Markdown, sheet → 目录/CSV, bitable → 目录/JSONL, file → 原样下载
多域映射Drive · Wiki · IM · Calendar · Tasks · Mail · Meetings · Application · Apps · Approval · Attendance · Base · Contact · Docs · Event · Markdown · Mindnotes · Minutes · Note · OKR · Sheets · Slides · VC · Whiteboard · _system
同名冲突解决自动 name~token 后缀,持久化映射保证路径稳定
三级缓存in-memory → 磁盘 LRU ContentCache → 远程拉取,TTL 自动过期
重试 & 认证恢复API 限流自动指数退避,token 过期自动刷新
清晰错误语义FUSE/WebDAV 会区分只读、未找到、不支持等错误,避免客户端只看到泛化 I/O error
守护进程后台运行、PID 管理、优雅关闭、stale mount 自动清理
跨平台macOS (macFUSE / Fuse-T) + Linux (FUSE3)
CI/CDGitHub Actions + GoReleaser 自动发布多平台二进制

Quick Start

Prerequisites

  • lark-clinpm install -g @larksuite/cli@latest(控制节点按 @larksuite/cli 1.0.86 命令面维护)
  • FUSE (仅 FUSE 模式需要):
    • macOS: brew install macfusebrew install macos-fuse-t/homebrew-cask/fuse-t
    • Linux: apt install fuse3

Install

# Go install
go install github.com/IchenDEV/larkfs/cmd/larkfs@latest
# 或从 Releases 下载预编译二进制# https://github.com/IchenDEV/larkfs/releases

Setup

# 一键初始化:检测 lark-cli → 配置应用 → OAuth 登录
larkfs init

larkfs init 会自动引导完成以下步骤:

  1. 检查 lark-cli 是否安装
  2. 若未配置,运行 lark-cli config init --new 创建应用
  3. 若未登录,运行 lark-cli auth login --domain all 获取授权

Usage

# 检查环境(lark-cli 配置、认证、连通性、FUSE)
larkfs doctor
# WebDAV 模式(推荐,无需 FUSE)
larkfs serve --port 8080
# 挂载(前台)
larkfs mount ~/lark
# 挂载(后台守护进程)
larkfs mount ~/lark -d
# 只读模式
larkfs mount ~/lark --read-only
# 指定域
larkfs mount ~/lark --domains drive,wiki,calendar
# 查看状态
larkfs status
# 卸载
larkfs unmount ~/lark
# 卸载全部
larkfs unmount --all

Desktop App Preview

macOS 仓库内现在带了一个 SwiftUI 宿主 app,用来读取 larkfs 的 JSON 状态输出,并承接后续 File Provider 原生挂载方案:

./script/build_and_run.sh

仓库里也已经有 File Provider 的起步代码:larkfs native item/list/fetch 提供只读 bridge,apps/LarkFSDesktop/FileProviderExtension 提供可编译的 NSFileProviderReplicatedExtension。脚本会优先用 Xcode project 构建带 .appex 的 app;要让 Finder 接受插件,需要本机有 Apple Development / Developer ID 签名身份:

LARKFS_DEVELOPMENT_TEAM=<TEAM_ID> ./script/build_and_run.sh

更多设计说明见 docs/macos-native-mount.md

Directory Layout

~/lark/
├── drive/ # 云空间
│ ├── 项目文档.md # docx → Markdown (读写)
│ ├── 数据表.sheet/ # spreadsheet → 目录
│ │ ├── _meta.json
│ │ └── Sheet1.csv # 每个 sheet → CSV (读写)
│ ├── 多维表格.base/ # bitable → 目录
│ │ ├── _meta.json
│ │ └── 表1.jsonl # 每张表 → JSONL (读写)
│ └── 设计稿.sketch # 普通文件 → 原样下载
├── wiki/ # 知识库
│ └── 产品空间/
│ ├── PRD.md # wiki node → docx → Markdown
│ └── 数据看板.sheet/
├── im/ # 即时消息
│ └── 产品群/
│ ├── latest.md # 最新消息 (只读)
│ ├── _send.md # 写入即发送
│ └── files/ # 群文件
├── calendar/ # 日历
│ ├── 周一站会.md # 事件详情 (只读)
│ └── _create.md # 写入即创建事件
├── tasks/ # 任务
│ ├── 完成设计评审.md # 任务详情
│ └── _create.md # 写入即创建任务
├── mail/ # 邮箱
│ ├── INBOX/
│ │ └── 2026-04-07_张三_会议通知.md
│ ├── _compose.md # 写入即发送
│ └── _send.md
└── meetings/ # 会议
└── 2026-04-07/
└── 产品评审/
├── _meta.json # 会议元数据
├── summary.md # AI 摘要
├── todos.md # 待办提取
├── transcript.md # 逐字稿
└── recording.mp4 # 录制文件

Architecture

┌─────────────┐ ┌─────────────┐
│ FUSE mount │ │ WebDAV srv │ ← mount layer (pkg/mount)
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬────────┘
│
┌──────┴──────┐
│ VFS + Tree │ ← virtual fs (pkg/vfs)
└──────┬──────┘
│
┌───────────┼───────────┐
│ Domain Adapters │ ← adapters (pkg/adapter)
│ drive wiki im cal │
│ task mail meeting │
└───────────┬───────────┘
│
┌──────┴──────┐
│ DocType │ ← type handlers (pkg/doctype)
│ Registry │ docx/sheet/bitable/file/folder
└──────┬──────┘
│
┌──────┴──────┐
│ CLI Exec │ ← lark-cli wrapper (pkg/cli)
│ + Retry │ with middleware, retry, auth
└─────────────┘

Key packages:

PackageResponsibility
cmd/larkfsCLI entry — mount, unmount, serve, status, doctor, init
pkg/clilark-cli subprocess wrapper, JSON param builder, error classification
pkg/doctypePer-type read/write handlers: docx, sheet, bitable, file, folder, readonly
pkg/adapterDomain adapters: drive, wiki, im, calendar, task, mail, meeting
pkg/vfsVirtual tree + operations routing
pkg/mountFUSE server (go-fuse/v2), WebDAV server (x/net/webdav)
pkg/cacheMetadata TTL cache + LRU disk content cache
pkg/namingName conflict resolution with ~token suffix + persistent mapping
pkg/daemonPID file, fork, health check, stale mount cleanup
pkg/errorsRetry with exponential backoff, auth recovery, CLI error to errno helpers
pkg/configMount/Serve config structs, path resolution

Filesystem Semantics

  • FUSE 和 WebDAV 写入都会先按文件句柄缓冲,正确处理 editor-style 的 offset write、truncate、append,并在 flush/close 时提交到 VFS。
  • 普通二进制文件支持下载,以及“新建后首次写入即上传”;普通路径上的再次覆盖写入仍会返回 unsupported,避免静默变成“删了再传一份”。
  • 如果你明确要替换已有 Drive 普通文件,请写 /_ops/replace.request.json:指定 target_path,再提供 flags.file_pathdata.content_base64 / data.content,结果里会返回新旧 token。
  • 目录里也会为普通 Drive 文件生成就近入口,比如 blob.bin._replace.request.json;这条路径已经带好目标文件,直接写替换请求就行。
  • CRUD 只会作用在真实资源节点上;_meta/_ops/_queries/_views/ 是控制面路径,不能被当成 Drive 文件夹误创建。
  • FUSE 会把 VFS 错误映射成更可消费的 errno:read-only → EROFS,not found → ENOENT,unsupported → ENOTSUP,未知错误才回退到 EIO
  • Rename 不会做本地假成功:如果没有明确映射到远端 CLI 命令,操作会返回 unsupported,而不是只改内存里的名字等待下次刷新回滚。

Development

# Build
make build
# Run tests
make test# Unit coverage across production packages
make test-cover
# Lint
make lint
# Dev mount (foreground, debug log)
make dev-mount
# Dev unmount
make dev-unmount
# Clean
make clean

Tests live under each module's test/ subdirectory, so they do not sit flat beside implementation files. make test-cover runs the full suite and reports coverage for the pure unit-testable production packages; CLI subprocess and mount boundary behavior is still tested, but cmd/larkfs and pkg/mount are not included in the unit coverage denominator to avoid test-only hooks or same-package white-box tests.

Release

Releases are automated via GitHub Actions + GoReleaser on version tags:

git tag v0.1.0
git push origin v0.1.0

Produces multi-platform binaries (linux/darwin × amd64/arm64).

Configuration

All runtime state is stored in ~/.larkfs/:

~/.larkfs/
├── cache/ # LRU content cache (default 500MB)
├── mounts/ # PID files for active mounts
├── namemap.json # Persistent name → token mappings
└── larkfs.log # Log file

CLI Flags

FlagDefaultDescription
--daemon, -dfalseRun as background daemon
--cache-dir~/.larkfs/cacheCache directory
--cache-size500MBDisk content cache size limit
--metadata-ttl60Metadata cache TTL (seconds)
--read-onlyfalseMount in read-only mode
--domainsall supported domainsComma-separated enabled domains
--lark-cliauto-detectPath to lark-cli binary
--log-levelinfoLog level (debug/info/warn/error)

License

MIT

About

LarkFS - 将飞书/Lark 映射为本地可读写的文件目录。像操作本地文件一样操作云端资源。

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages