Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
175e0a2
Annotate SonarCloud security hotspots with NOSONAR justifications
JE-Chen Apr 21, 2026
132264a
Add Traditional and Simplified Chinese Sphinx docs
JE-Chen Apr 21, 2026
18f4162
Add rate limiter and circuit breaker primitives
JE-Chen Apr 22, 2026
94cd5db
Add cross-platform advisory file lock
JE-Chen Apr 22, 2026
a09abd6
Add SQLite-backed distributed lock with TTL
JE-Chen Apr 22, 2026
0762be0
Add persistent SQLite-backed action queue with dead-letter handling
JE-Chen Apr 22, 2026
deac32b
Add SHA-256 content-addressable store
JE-Chen Apr 22, 2026
a187059
Add MIME detection and Jinja2-with-stdlib-fallback template rendering
JE-Chen Apr 22, 2026
4d8c988
Add directory and text file diff + patch application
JE-Chen Apr 22, 2026
8f710c1
Add file versioning and recoverable trash helpers
JE-Chen Apr 22, 2026
926d591
Add archive format auto-detect with 7z and RAR readers
JE-Chen Apr 22, 2026
3dbc58a
Add WebDAV client with PROPFIND listing and SSRF opt-in
JE-Chen Apr 22, 2026
4f06a47
Add SMB/CIFS client over smbprotocol
JE-Chen Apr 22, 2026
acc29b2
Add fsspec bridge over unified filesystem spec
JE-Chen Apr 22, 2026
37ca776
Add healthz/readyz/openapi and WebSocket progress stream to HTTP server
JE-Chen Apr 22, 2026
6325a69
Add HTMX-powered Web UI server over stdlib HTTP
JE-Chen Apr 22, 2026
1bf442e
Add MCP server bridge exposing action registry as JSON-RPC tools
JE-Chen Apr 22, 2026
c4d3ff3
Add Sphinx automodule entries for recent core/local/remote/server mod…
JE-Chen Apr 22, 2026
c3207c3
Document WebDAV, SMB, fsspec, HTTP observability, Web UI, MCP in READMEs
JE-Chen Apr 22, 2026
458d90c
Add automation_file_mcp console script and mcp CLI subcommand
JE-Chen Apr 22, 2026
803888d
Add examples/mcp/ with launcher and Claude Desktop sample config
JE-Chen Apr 22, 2026
42c5883
Fix template autoescape, CAS single-return, and WebSocket SHA-1 harde…
JE-Chen Apr 22, 2026
982ac57
Harden archive / WebDAV / FTP ingest paths
JE-Chen Apr 22, 2026
ee0452c
Extract Bearer and octet-stream constants
JE-Chen Apr 22, 2026
8292287
Quiet lint noise on dispatcher and CLI-shaped signatures
JE-Chen Apr 22, 2026
e14fc05
Clean up test fixtures and route loopback URLs through insecure_fixtures
JE-Chen Apr 22, 2026
ec0290a
De-flake test_refresh_extends_lease on slower CI runners
JE-Chen Apr 22, 2026
47566b8
Bump cryptography, prometheus-client, and sphinx floors
JE-Chen Apr 22, 2026
1cd5d30
Address remaining Codacy + SonarCloud suppressions
JE-Chen Apr 22, 2026
57bf4b7
Use plain NOSONAR syntax accepted by Sonar Python parser
JE-Chen Apr 22, 2026
915533e
Shorten suppression comments and exclude docs from Codacy
JE-Chen Apr 22, 2026
80d85b9
Route Jinja autoescape through a callable, not a literal bool
JE-Chen Apr 22, 2026
c352c48
Always run Jinja with autoescape=True, opt-out via Markup wrapping
JE-Chen Apr 22, 2026
500a3a6
Render Jinja templates in a sandbox to clear SSTI BLOCKER
JE-Chen Apr 22, 2026
400d2c3
Mark reviewed SSTI + SHA-1 lines with NOSONAR on owning line
JE-Chen Apr 22, 2026
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
7 changes: 7 additions & 0 deletions .codacy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
exclude_paths:
- 'docs/**'
- 'docs/requirements.txt'
- '**/source.zh-TW/conf.py'
- '**/source/conf.py'
- 'examples/**'
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ facade.
- **HTTPActionClient SDK** — typed Python client for the HTTP action server with shared-secret auth, loopback guard, and OPTIONS-based ping
- **AES-256-GCM file encryption** — `encrypt_file` / `decrypt_file` with `generate_key()` / `key_from_password()` (PBKDF2-HMAC-SHA256); JSON actions `FA_encrypt_file` / `FA_decrypt_file`
- **Prometheus metrics exporter** — `start_metrics_server()` exposes `automation_file_actions_total{action,status}` counters and `automation_file_action_duration_seconds{action}` histograms
- **WebDAV backend** — `WebDAVClient` with `exists` / `upload` / `download` / `delete` / `mkcol` / `list_dir` on any RFC 4918 server; rejects private / loopback targets unless `allow_private_hosts=True`
- **SMB / CIFS backend** — `SMBClient` over `smbprotocol`'s high-level `smbclient` API; UNC-based, encrypted sessions by default
- **fsspec bridge** — drive any `fsspec`-backed filesystem (memory, local, s3, gcs, abfs, …) through the action registry with `get_fs` / `fsspec_upload` / `fsspec_download` / `fsspec_list_dir` etc.
- **HTTP server observability** — `GET /healthz` / `GET /readyz` probes, `GET /openapi.json` spec, and `GET /progress` WebSocket stream of live transfer snapshots
- **HTMX Web UI** — `start_web_ui()` serves a read-only dashboard (health, progress, registry) that polls HTML fragments; stdlib-only HTTP plus one CDN script with SRI
- **MCP (Model Context Protocol) server** — `MCPServer` bridges the registry to any MCP host (Claude Desktop, MCP CLIs) over newline-delimited JSON-RPC 2.0 on stdio; every `FA_*` action becomes an MCP tool with an auto-generated input schema
- PySide6 GUI (`python -m automation_file ui`) with a tab per backend, the JSON-action runner, and dedicated tabs for Triggers, Scheduler, and live Progress
- Rich CLI with one-shot subcommands plus legacy JSON-batch flags
- Project scaffolding (`ProjectBuilder`) for executor-based automations
Expand Down Expand Up @@ -624,6 +630,77 @@ Exports `automation_file_actions_total{action,status}` and
`automation_file_action_duration_seconds{action}`. Non-loopback binds
require `allow_non_loopback=True` explicitly.

### WebDAV, SMB/CIFS, fsspec
Extra remote backends alongside the first-class S3 / Azure / Dropbox / SFTP:

```python
from automation_file import WebDAVClient, SMBClient, fsspec_upload

# RFC 4918 WebDAV — loopback/private targets require opt-in.
dav = WebDAVClient("https://files.example.com/remote.php/dav",
username="alice", password="s3cr3t")
dav.upload("/local/report.csv", "team/reports/report.csv")

# SMB / CIFS via smbprotocol's high-level smbclient API.
with SMBClient("fileserver", "share", "alice", "s3cr3t") as smb:
smb.upload("/local/report.csv", "reports/report.csv")

# Anything fsspec can address — memory, gcs, abfs, local, …
fsspec_upload("/local/report.csv", "memory://reports/report.csv")
```

### HTTP server observability
`start_http_action_server()` additionally exposes liveness / readiness probes,
an OpenAPI 3.0 spec, and a WebSocket stream of progress snapshots:

```bash
curl http://127.0.0.1:9944/healthz # {"status": "ok"}
curl http://127.0.0.1:9944/readyz # 200 when registry non-empty, 503 otherwise
curl http://127.0.0.1:9944/openapi.json # OpenAPI 3.0 spec
# Connect a WebSocket to ws://127.0.0.1:9944/progress for live progress frames.
```

### HTMX Web UI
A read-only observability dashboard built on stdlib HTTP + HTMX (loaded from
a pinned CDN URL with SRI). Loopback-only by default; optional shared secret:

```python
from automation_file import start_web_ui

server = start_web_ui(host="127.0.0.1", port=9955, shared_secret="s3cr3t")
# Browse http://127.0.0.1:9955/ — health, progress, and registry fragments
# auto-poll every few seconds. Write operations stay on the action servers.
```

### MCP (Model Context Protocol) server
Expose every registered `FA_*` action to an MCP host (Claude Desktop, MCP
CLIs) over JSON-RPC 2.0 on stdio:

```python
from automation_file import MCPServer

MCPServer().serve_stdio() # reads JSON-RPC from stdin, writes to stdout
```

`pip install` exposes an `automation_file_mcp` console script (via
`[project.scripts]`) so MCP hosts can launch the bridge without any Python
glue. Three equivalent launch styles:

```bash
automation_file_mcp # installed console script
python -m automation_file mcp # CLI subcommand
python examples/mcp/run_mcp.py # standalone launcher
```

All three accept `--name`, `--version`, and `--allowed-actions` (comma-
separated whitelist — strongly recommended since the default registry
includes high-privilege actions like `FA_run_shell`). See
[`examples/mcp/`](examples/mcp) for ready-to-copy Claude Desktop config.

Tool descriptors are generated on the fly by introspecting each action's
signature — parameter names and types become a JSON schema, so hosts can
render fields without any manual wiring.

### DAG action executor
Run actions in dependency order; independent branches fan out across a
thread pool. Each node is `{"id": ..., "action": [...], "depends_on":
Expand Down Expand Up @@ -709,6 +786,8 @@ python -m automation_file create-file hello.txt --content "hi"
python -m automation_file server --host 127.0.0.1 --port 9943
python -m automation_file http-server --host 127.0.0.1 --port 9944
python -m automation_file drive-upload my.txt --token token.json --credentials creds.json
python -m automation_file mcp --allowed-actions FA_file_checksum,FA_fast_find
automation_file_mcp --allowed-actions FA_file_checksum,FA_fast_find # installed console script

# Legacy flags (JSON action lists)
python -m automation_file --execute_file actions.json
Expand Down
76 changes: 76 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ TCP / HTTP 服务器执行的 JSON 驱动动作。内附 PySide6 GUI,每个功
- **HTTPActionClient SDK** — HTTP 动作服务器的类型化 Python 客户端,具 shared-secret 认证、loopback 守护与 OPTIONS ping
- **AES-256-GCM 文件加密** — `encrypt_file` / `decrypt_file` 搭配 `generate_key()` / `key_from_password()`(PBKDF2-HMAC-SHA256);JSON 动作 `FA_encrypt_file` / `FA_decrypt_file`
- **Prometheus metrics 导出器** — `start_metrics_server()` 提供 `automation_file_actions_total{action,status}` 计数器与 `automation_file_action_duration_seconds{action}` 直方图
- **WebDAV 后端** — `WebDAVClient` 提供 `exists` / `upload` / `download` / `delete` / `mkcol` / `list_dir`,适用于任何 RFC 4918 服务器;除非显式传入 `allow_private_hosts=True`,否则拒绝私有 / loopback 目标
- **SMB / CIFS 后端** — `SMBClient` 基于 `smbprotocol` 的高阶 `smbclient` API;采用 UNC 路径,默认启用加密会话
- **fsspec 桥接** — 通过 `get_fs` / `fsspec_upload` / `fsspec_download` / `fsspec_list_dir` 等函数,驱动任何 `fsspec` 支持的文件系统(memory、local、s3、gcs、abfs、…)
- **HTTP 服务器观测端点** — `GET /healthz` / `GET /readyz` 探针、`GET /openapi.json` 规格,以及 `GET /progress`(通过 WebSocket 推送实时传输快照)
- **HTMX Web UI** — `start_web_ui()` 启动只读观测仪表板(health、progress、registry),通过 HTML 片段轮询;仅用标准库 HTTP,搭配一个带 SRI 的 CDN 脚本
- **MCP(Model Context Protocol)服务器** — `MCPServer` 通过 stdio 上的 JSON-RPC 2.0(换行分隔 JSON)将注册表桥接到任意 MCP 主机(Claude Desktop、MCP CLI);每个 `FA_*` 动作都会自动生成输入 schema 并成为 MCP 工具
- PySide6 GUI(`python -m automation_file ui`)每个后端一个页签,含 JSON 动作执行器,另有 Triggers、Scheduler、实时 Progress 专属页签
- 功能丰富的 CLI,包含一次性子命令与旧式 JSON 批量标志
- 项目脚手架(`ProjectBuilder`)协助构建以 executor 为核心的自动化项目
Expand Down Expand Up @@ -611,6 +617,74 @@ server = start_metrics_server(host="127.0.0.1", port=9945)
`automation_file_action_duration_seconds{action}`。若要绑定非 loopback
地址必须显式传入 `allow_non_loopback=True`。

### WebDAV、SMB/CIFS、fsspec
在一等公民的 S3 / Azure / Dropbox / SFTP 之外,额外的远程后端:

```python
from automation_file import WebDAVClient, SMBClient, fsspec_upload

# RFC 4918 WebDAV —— loopback / 私有目标需要显式开关。
dav = WebDAVClient("https://files.example.com/remote.php/dav",
username="alice", password="s3cr3t")
dav.upload("/local/report.csv", "team/reports/report.csv")

# 通过 smbprotocol 的高阶 smbclient API 操作 SMB / CIFS。
with SMBClient("fileserver", "share", "alice", "s3cr3t") as smb:
smb.upload("/local/report.csv", "reports/report.csv")

# 任何 fsspec 能寻址的目标 —— memory、gcs、abfs、local、…
fsspec_upload("/local/report.csv", "memory://reports/report.csv")
```

### HTTP 服务器观测端点
`start_http_action_server()` 额外提供 liveness / readiness 探针、OpenAPI 3.0
规格,以及实时进度快照的 WebSocket 流:

```bash
curl http://127.0.0.1:9944/healthz # {"status": "ok"}
curl http://127.0.0.1:9944/readyz # 注册表非空时 200,否则 503
curl http://127.0.0.1:9944/openapi.json # OpenAPI 3.0 规格
# 使用 WebSocket 连接 ws://127.0.0.1:9944/progress 获取实时进度帧。
```

### HTMX Web UI
基于标准库 HTTP + HTMX(以带 SRI 的固定 CDN URL 加载)构建的只读观测仪表板。
默认仅允许 loopback,可选 shared-secret:

```python
from automation_file import start_web_ui

server = start_web_ui(host="127.0.0.1", port=9955, shared_secret="s3cr3t")
# 浏览 http://127.0.0.1:9955/ —— health、progress、registry 片段每几秒
# 自动轮询一次;写入操作仍然保留在动作服务器。
```

### MCP(Model Context Protocol)服务器
通过 stdio 上的 JSON-RPC 2.0 把每个已注册的 `FA_*` 动作暴露给 MCP 主机
(Claude Desktop、MCP CLI):

```python
from automation_file import MCPServer

MCPServer().serve_stdio() # 从 stdin 读取 JSON-RPC,写入 stdout
```

`pip install` 后,`[project.scripts]` 会提供 `automation_file_mcp` console
script,MCP 主机无需编写 Python glue 即可启动桥接器。三种等价的启动方式:

```bash
automation_file_mcp # 已安装的 console script
python -m automation_file mcp # CLI 子命令
python examples/mcp/run_mcp.py # 独立启动脚本
```

三者都支持 `--name`、`--version`、`--allowed-actions`(逗号分隔白名单——
强烈建议使用,因为默认注册表包含 `FA_run_shell` 等高权限动作)。可直接复制的
Claude Desktop 示例配置请见 [`examples/mcp/`](examples/mcp)。

工具描述符在运行时由动作签名自动生成——参数名称与类型会转换为 JSON schema,
主机无需任何手动配置即可渲染字段。

### DAG 动作执行器
按依赖顺序执行动作;独立分支通过线程池并行展开。每个节点的形式为
`{"id": ..., "action": [...], "depends_on": [...]}`:
Expand Down Expand Up @@ -693,6 +767,8 @@ python -m automation_file create-file hello.txt --content "hi"
python -m automation_file server --host 127.0.0.1 --port 9943
python -m automation_file http-server --host 127.0.0.1 --port 9944
python -m automation_file drive-upload my.txt --token token.json --credentials creds.json
python -m automation_file mcp --allowed-actions FA_file_checksum,FA_fast_find
automation_file_mcp --allowed-actions FA_file_checksum,FA_fast_find # 已安装的 console script

# 旧式标志(JSON 动作清单)
python -m automation_file --execute_file actions.json
Expand Down
76 changes: 76 additions & 0 deletions README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ TCP / HTTP 伺服器執行的 JSON 驅動動作。內附 PySide6 GUI,每個功
- **HTTPActionClient SDK** — HTTP 動作伺服器的型別化 Python 客戶端,具 shared-secret 驗證、loopback 防護與 OPTIONS ping
- **AES-256-GCM 檔案加密** — `encrypt_file` / `decrypt_file` 搭配 `generate_key()` / `key_from_password()`(PBKDF2-HMAC-SHA256);JSON 動作 `FA_encrypt_file` / `FA_decrypt_file`
- **Prometheus metrics 匯出器** — `start_metrics_server()` 提供 `automation_file_actions_total{action,status}` 計數器與 `automation_file_action_duration_seconds{action}` 直方圖
- **WebDAV 後端** — `WebDAVClient` 提供 `exists` / `upload` / `download` / `delete` / `mkcol` / `list_dir`,適用於任何 RFC 4918 伺服器;除非顯式傳入 `allow_private_hosts=True`,否則拒絕私有 / loopback 目標
- **SMB / CIFS 後端** — `SMBClient` 建構於 `smbprotocol` 的高階 `smbclient` API;採用 UNC 路徑,預設啟用加密連線
- **fsspec 橋接** — 透過 `get_fs` / `fsspec_upload` / `fsspec_download` / `fsspec_list_dir` 等函式,驅動任何 `fsspec` 支援的檔案系統(memory、local、s3、gcs、abfs、…)
- **HTTP 伺服器觀測端點** — `GET /healthz` / `GET /readyz` 探針、`GET /openapi.json` 規格、以及 `GET /progress`(以 WebSocket 推送即時傳輸快照)
- **HTMX Web UI** — `start_web_ui()` 啟動唯讀觀測儀表板(health、progress、registry),以 HTML 片段輪詢;僅用標準函式庫 HTTP,搭配一支帶 SRI 的 CDN 腳本
- **MCP(Model Context Protocol)伺服器** — `MCPServer` 透過 stdio 上的 JSON-RPC 2.0(行分隔 JSON)將登錄表橋接到任何 MCP 主機(Claude Desktop、MCP CLI);每個 `FA_*` 動作都會自動生成輸入 schema 並成為 MCP 工具
- PySide6 GUI(`python -m automation_file ui`)每個後端一個分頁,含 JSON 動作執行器,另有 Triggers、Scheduler、即時 Progress 專屬分頁
- 功能豐富的 CLI,包含一次性子指令與舊式 JSON 批次旗標
- 專案鷹架(`ProjectBuilder`)協助建立以 executor 為核心的自動化專案
Expand Down Expand Up @@ -611,6 +617,74 @@ server = start_metrics_server(host="127.0.0.1", port=9945)
`automation_file_action_duration_seconds{action}`。若要綁定非 loopback
位址必須明確傳入 `allow_non_loopback=True`。

### WebDAV、SMB/CIFS、fsspec
在一等公民的 S3 / Azure / Dropbox / SFTP 之外,另有額外的遠端後端:

```python
from automation_file import WebDAVClient, SMBClient, fsspec_upload

# RFC 4918 WebDAV —— loopback / 私有目標需要顯式開關。
dav = WebDAVClient("https://files.example.com/remote.php/dav",
username="alice", password="s3cr3t")
dav.upload("/local/report.csv", "team/reports/report.csv")

# 透過 smbprotocol 的高階 smbclient API 操作 SMB / CIFS。
with SMBClient("fileserver", "share", "alice", "s3cr3t") as smb:
smb.upload("/local/report.csv", "reports/report.csv")

# 任何 fsspec 能定址的目標 —— memory、gcs、abfs、local、…
fsspec_upload("/local/report.csv", "memory://reports/report.csv")
```

### HTTP 伺服器觀測端點
`start_http_action_server()` 額外提供 liveness / readiness 探針、OpenAPI 3.0
規格,以及即時進度快照的 WebSocket 串流:

```bash
curl http://127.0.0.1:9944/healthz # {"status": "ok"}
curl http://127.0.0.1:9944/readyz # 登錄表非空時 200,否則 503
curl http://127.0.0.1:9944/openapi.json # OpenAPI 3.0 規格
# 以 WebSocket 連線 ws://127.0.0.1:9944/progress 取得即時進度訊框。
```

### HTMX Web UI
建構於標準函式庫 HTTP + HTMX(以帶 SRI 的固定 CDN URL 載入)之上的唯讀觀測
儀表板。預設僅允許 loopback,可選 shared-secret:

```python
from automation_file import start_web_ui

server = start_web_ui(host="127.0.0.1", port=9955, shared_secret="s3cr3t")
# 瀏覽 http://127.0.0.1:9955/ —— health、progress、registry 片段每數秒
# 自動輪詢;寫入操作仍保留在動作伺服器。
```

### MCP(Model Context Protocol)伺服器
透過 stdio 上的 JSON-RPC 2.0 將登錄的每個 `FA_*` 動作暴露給 MCP 主機
(Claude Desktop、MCP CLI):

```python
from automation_file import MCPServer

MCPServer().serve_stdio() # 從 stdin 讀取 JSON-RPC,寫入 stdout
```

`pip install` 後,`[project.scripts]` 會提供 `automation_file_mcp` console
script,MCP 主機不需要寫任何 Python glue 也能啟動橋接器。三種等價的啟動方式:

```bash
automation_file_mcp # 已安裝的 console script
python -m automation_file mcp # CLI 子指令
python examples/mcp/run_mcp.py # 獨立啟動腳本
```

三者皆支援 `--name`、`--version`、`--allowed-actions`(逗號分隔白名單——
強烈建議使用,因為預設登錄表包含 `FA_run_shell` 等高權限動作)。可直接複製的
Claude Desktop 範例設定請見 [`examples/mcp/`](examples/mcp)。

工具描述在執行時由動作簽章自動生成——參數名稱與型別會轉換為 JSON schema,
主機無需任何手動設定即可渲染欄位。

### DAG 動作執行器
依相依關係執行動作;獨立分支會透過執行緒池平行展開。每個節點形式為
`{"id": ..., "action": [...], "depends_on": [...]}`:
Expand Down Expand Up @@ -693,6 +767,8 @@ python -m automation_file create-file hello.txt --content "hi"
python -m automation_file server --host 127.0.0.1 --port 9943
python -m automation_file http-server --host 127.0.0.1 --port 9944
python -m automation_file drive-upload my.txt --token token.json --credentials creds.json
python -m automation_file mcp --allowed-actions FA_file_checksum,FA_fast_find
automation_file_mcp --allowed-actions FA_file_checksum,FA_fast_find # 已安裝的 console script

# 舊式旗標(JSON 動作清單)
python -m automation_file --execute_file actions.json
Expand Down
Loading
Loading