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: 9 additions & 6 deletions .claude-plugin/marketplace.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This file provides guidance to Claude Code when working with code in this reposi

**macdoc** 是一個原生 macOS 文件處理工具集,專注於文件格式解析、轉換和 OCR 功能。整個專案使用 Swift 開發,充分利用 Apple 平台的原生能力。

本 repo 同時是 **Claude Code plugin marketplace**(`.claude-plugin/marketplace.json` + `plugins/`,2026-07 起,#112):發布 `che-word-mcp`、`che-pdf-mcp`、`che-pptx-mcp`、`macdoc` 四個 plugins,使用者以 `claude plugin marketplace add PsychQuant/macdoc` 安裝。注意 `plugins/`(plugin shells,正常入版控)與 `packages/`(gitignored 本地套件)的差異;MCP shells 的 wrapper 從各 binary repo 的 GitHub Releases 自動下載 binary,安裝前強制驗證 sha256 + Developer ID 簽章鏈(requirement-based codesign,Team `6W377FS7BS`)。發布新版時同步 bump `plugins/<name>/.claude-plugin/plugin.json` 與 `.claude-plugin/marketplace.json` 兩處版本。
本 repo 同時是 **Claude Code plugin marketplace**(`.claude-plugin/marketplace.json` + `plugins/`,2026-07 起,#112):發布 `che-word-mcp`、`che-pdf-mcp`、`che-pptx-mcp`、`macdoc` 四個 plugins,使用者以 `claude plugin marketplace add PsychQuant/macdoc` 安裝。注意 `plugins/`(plugin shells,正常入版控)與 `packages/`(gitignored 本地套件)的差異;MCP shells 的 wrapper 從各 binary repo 的 GitHub Releases 自動下載 binary,安裝前強制驗證 sha256 + Developer ID 簽章鏈(requirement-based codesign,Team `6W377FS7BS`)。發布新版時同步 bump `plugins/<name>/.claude-plugin/plugin.json` 與 `.claude-plugin/marketplace.json` 兩處版本;**binary-backed plugin 的 `binary_version` 只在 binary repo 發新 release 後才改**(shell-only 變更 bump `version` 即可,#116 解耦契約)

## Project Structure

Expand Down
3 changes: 2 additions & 1 deletion plugins/che-pdf-mcp/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "che-pdf-mcp",
"description": "PDF 文件處理 MCP server — PDFKit 解析與文字提取、Vision OCR(原生 macOS)、圖片/區域擷取、亂碼區域偵測。 v0.1.0: 首次 marketplace 發布。",
"version": "0.1.0",
"version": "0.1.1",
"binary_version": "0.1.0",
"author": {
"name": "Che Cheng"
}
Expand Down
6 changes: 6 additions & 0 deletions plugins/che-pdf-mcp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to the che-pdf-mcp plugin shell will be documented in this f

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [0.1.1] - 2026-07-02

### Changed

- shell/binary 版本解耦(PsychQuant/macdoc#116):新增 `binary_version` 欄位(=0.1.0);wrapper 改為 binary_version-first 解析,key 存在但空值 fail-closed,key 缺席才 fallback `version`(backward compat)。

## [0.1.0] - 2026-07-02

### Added
Expand Down
19 changes: 16 additions & 3 deletions plugins/che-pdf-mcp/bin/che-pdf-mcp-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,24 @@ run_existing_or_die() {
exit 1
}

# Read desired version from plugin.json (empty string on any failure → latest).
# Read desired BINARY version from plugin.json. Since #116 the shell version
# ("version") and the binary release tag ("binary_version") are decoupled —
# shell-only changes bump "version" freely. Prefer "binary_version"; fall back
# to "version" ONLY when the key is absent entirely (plugin.json predates the
# field — backward compat). A binary_version key that exists but is empty or
# malformed fails closed instead of silently chasing the shell version tag.
DESIRED_VERSION=""
if [[ -f "$PLUGIN_JSON" ]]; then
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if grep -qE '"binary_version"[[:space:]]*:' "$PLUGIN_JSON" 2>/dev/null; then
DESIRED_VERSION=$(grep -oE '"binary_version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if [[ -z "$DESIRED_VERSION" ]]; then
run_existing_or_die "binary_version present in plugin.json but empty/malformed — refusing to guess a release tag"
fi
else
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
fi
if [[ -z "$DESIRED_VERSION" ]]; then
# plugin.json exists but version unparseable — fail closed rather than
# silently degrading to the unpinned latest channel (#112 verify R2).
Expand Down
3 changes: 2 additions & 1 deletion plugins/che-pptx-mcp/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "che-pptx-mcp",
"description": "PowerPoint (.pptx) MCP server — PresentationML 解析與生成:slides、shapes、tables、notes、theme、markdown 匯出。 v0.1.0: 首次 marketplace 發布。",
"version": "0.1.0",
"version": "0.1.1",
"binary_version": "0.1.0",
"author": {
"name": "Che Cheng"
}
Expand Down
6 changes: 6 additions & 0 deletions plugins/che-pptx-mcp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to the che-pptx-mcp plugin shell will be documented in this

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [0.1.1] - 2026-07-02

### Changed

- shell/binary 版本解耦(PsychQuant/macdoc#116):新增 `binary_version` 欄位(=0.1.0);wrapper 改為 binary_version-first 解析,key 存在但空值 fail-closed,key 缺席才 fallback `version`(backward compat)。

## [0.1.0] - 2026-07-02

### Added
Expand Down
19 changes: 16 additions & 3 deletions plugins/che-pptx-mcp/bin/che-pptx-mcp-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,24 @@ run_existing_or_die() {
exit 1
}

# Read desired version from plugin.json (empty string on any failure → latest).
# Read desired BINARY version from plugin.json. Since #116 the shell version
# ("version") and the binary release tag ("binary_version") are decoupled —
# shell-only changes bump "version" freely. Prefer "binary_version"; fall back
# to "version" ONLY when the key is absent entirely (plugin.json predates the
# field — backward compat). A binary_version key that exists but is empty or
# malformed fails closed instead of silently chasing the shell version tag.
DESIRED_VERSION=""
if [[ -f "$PLUGIN_JSON" ]]; then
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if grep -qE '"binary_version"[[:space:]]*:' "$PLUGIN_JSON" 2>/dev/null; then
DESIRED_VERSION=$(grep -oE '"binary_version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if [[ -z "$DESIRED_VERSION" ]]; then
run_existing_or_die "binary_version present in plugin.json but empty/malformed — refusing to guess a release tag"
fi
else
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
fi
if [[ -z "$DESIRED_VERSION" ]]; then
# plugin.json exists but version unparseable — fail closed rather than
# silently degrading to the unpinned latest channel (#112 verify R2).
Expand Down
5 changes: 3 additions & 2 deletions plugins/che-word-mcp/.claude-plugin/plugin.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions plugins/che-word-mcp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
> `plugin.json` description field. Section categorization is best-effort —
> review and refine `Added` / `Changed` / `Fixed` etc. as needed.

## [Unreleased — macdoc marketplace shell]
## [3.20.1] - 2026-07-02

### Security

- Wrapper 改用硬化模板(同 che-pdf-mcp / che-pptx-mcp v0.1.0):強制 sha256 + requirement-based codesign(Team OU 6W377FS7BS)+ pinned version 不 fallback latest(PsychQuant/macdoc#112 verify R1 HIGH-2)。**版本刻意不 bump**:wrapper 以 plugin.json version 挑 binary release tag(v3.20.0),bump 會使下載目標指向不存在的 tag;shell/binary 版本解耦見 PsychQuant/macdoc#116。
- Wrapper 改用硬化模板(同 che-pdf-mcp / che-pptx-mcp v0.1.0):強制 sha256 + requirement-based codesign(Team OU 6W377FS7BS)+ exec-time 重驗 + pinned version 不 fallback latest(PsychQuant/macdoc#112 verify R1/R2)。

### Changed

- **shell/binary 版本解耦(PsychQuant/macdoc#116)**:新增 `binary_version` 欄位(=3.20.0,binary release tag 來源);`version` 自此為 shell 版本、可獨立 bump。本版(3.20.1)即吸收 #112 的 wrapper 硬化變更。wrapper 對缺 `binary_version` 的舊 shell fallback 讀 `version`(backward compat)。

## [3.20.0] - 2026-05-04

Expand Down
19 changes: 16 additions & 3 deletions plugins/che-word-mcp/bin/che-word-mcp-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,24 @@ run_existing_or_die() {
exit 1
}

# Read desired version from plugin.json (empty string on any failure → latest).
# Read desired BINARY version from plugin.json. Since #116 the shell version
# ("version") and the binary release tag ("binary_version") are decoupled —
# shell-only changes bump "version" freely. Prefer "binary_version"; fall back
# to "version" ONLY when the key is absent entirely (plugin.json predates the
# field — backward compat). A binary_version key that exists but is empty or
# malformed fails closed instead of silently chasing the shell version tag.
DESIRED_VERSION=""
if [[ -f "$PLUGIN_JSON" ]]; then
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if grep -qE '"binary_version"[[:space:]]*:' "$PLUGIN_JSON" 2>/dev/null; then
DESIRED_VERSION=$(grep -oE '"binary_version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
if [[ -z "$DESIRED_VERSION" ]]; then
run_existing_or_die "binary_version present in plugin.json but empty/malformed — refusing to guess a release tag"
fi
else
DESIRED_VERSION=$(grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' "$PLUGIN_JSON" 2>/dev/null \
| head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)
fi
if [[ -z "$DESIRED_VERSION" ]]; then
# plugin.json exists but version unparseable — fail closed rather than
# silently degrading to the unpinned latest channel (#112 verify R2).
Expand Down
Loading