You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
opendoc is distributed as an agent plugin — one package, dual-manifested for both agents — via the [arcships/plugins](https://github.com/arcships/plugins) marketplace catalog. Installing sparse-fetches only the plugin package (`skill/`), never this repo's source tree. Then just start using it (e.g. ask the agent to search your notes; it will walk you through first-time setup). The engine binary isn't committed; on first use the skill notices it's missing and, with your OK, downloads the platform build (`opendoc-<os>-<arch>`) from GitHub releases, verified by sha256.
76
+
opendoc is distributed as an agent plugin — one package, dual-manifested for both agents — via the [arcships/plugins](https://github.com/arcships/plugins) marketplace catalog. Installing sparse-fetches only the plugin package (`plugin/`), never this repo's source tree. Then just start using it (e.g. ask the agent to search your notes; it will walk you through first-time setup). The engine binary isn't committed; on first use the skill notices it's missing and, with your OK, downloads the platform build (`opendoc-<os>-<arch>`) from GitHub releases, verified by sha256.
**For development** — build the engine from source and install the plugin from your working tree (this repo carries a dev-only catalog named `arcships-dev` so it can't collide with the real marketplace):
Copy file name to clipboardExpand all lines: docs/dev/README.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ go build ./...
12
12
go test ./... # all green means the environment is ready, ~20 seconds
13
13
```
14
14
15
-
Runtime credentials are only needed if you want to actually run a sync (not required): Feishu authorization (`opendoc init` walks you through it — the embedded engine handles QR-code app creation + login, zero install) and a Notion integration token. See [skill/skills/opendoc/references/setup.md](../../skill/skills/opendoc/references/setup.md) for the configuration flow — that's a script written for an agent to guide a user through, but a human can follow it too.
15
+
Runtime credentials are only needed if you want to actually run a sync (not required): Feishu authorization (`opendoc init` walks you through it — the embedded engine handles QR-code app creation + login, zero install) and a Notion integration token. See [plugin/skills/opendoc/references/setup.md](../../plugin/skills/opendoc/references/setup.md) for the configuration flow — that's a script written for an agent to guide a user through, but a human can follow it too.
16
16
17
17
## Running Locally (Without Polluting Your Real Mirror)
18
18
@@ -29,7 +29,7 @@ go run ./cmd/opendoc --root /tmp/opendoc-dev sync
29
29
1. Root [README](../../README.md) — why the project exists, the product shape, design principles.
30
30
2.[architecture.md](architecture.md) — the layering, the Adapter contract, the full flow of one sync, what each package is responsible for. **Required reading before changing code — this is the spec of record.**
31
31
3.[testing.md](testing.md) — how tests are organized, mock patterns, fixture red lines. **Required reading before writing tests.**
32
-
4. Reference material (consult as needed): [notion-properties-mapping.md](../notion-properties-mapping.md) — how Notion database properties land in frontmatter; [skill/skills/opendoc/references/degradation-tags.md](../../skill/skills/opendoc/references/degradation-tags.md) — the exact degradation markers the engine emits.
32
+
4. Reference material (consult as needed): [notion-properties-mapping.md](../notion-properties-mapping.md) — how Notion database properties land in frontmatter; [plugin/skills/opendoc/references/degradation-tags.md](../../plugin/skills/opendoc/references/degradation-tags.md) — the exact degradation markers the engine emits.
Copy file name to clipboardExpand all lines: docs/dev/architecture.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,7 +74,7 @@ The leaf-to-directory conversion that happens the first time a leaf gains a chil
74
74
-**content_hash is always computed on the "fetched original"** (before degradation, before rewriting), so degraded output and link rewriting never make a document look "dirty." Link rewriting also deliberately doesn't write back the hash.
75
75
-**All disk writes go through `atomicWrite`** (temp + fsync + rename); readers never see a half-written file.
76
76
-**Frontmatter is hand-rendered** (no YAML library), guaranteeing deterministic key order and byte-for-byte stability across runs ([frontmatter.go](../../internal/frontmatter/frontmatter.go)).
77
-
-**The degradation contract: loss is never silent.** Conversion is inevitably lossy (whiteboards, embedded tables, oversized pages, unsupported blocks), but every degraded resource block must land at least two of three things: **readable degraded content, a drillable ID, and a jumpable online link** — and every degradation increments a counter in the sync report. An unknown block is preserved as its verbatim tag rather than dropped. The exact marker shapes the engine emits, per platform, are catalogued in [skill/skills/opendoc/references/degradation-tags.md](../../skill/skills/opendoc/references/degradation-tags.md) (that file ships in the plugin and must stay in sync with the emitters in `internal/feishu/degrade.go` / `internal/notion/degrade.go`).
77
+
-**The degradation contract: loss is never silent.** Conversion is inevitably lossy (whiteboards, embedded tables, oversized pages, unsupported blocks), but every degraded resource block must land at least two of three things: **readable degraded content, a drillable ID, and a jumpable online link** — and every degradation increments a counter in the sync report. An unknown block is preserved as its verbatim tag rather than dropped. The exact marker shapes the engine emits, per platform, are catalogued in [plugin/skills/opendoc/references/degradation-tags.md](../../plugin/skills/opendoc/references/degradation-tags.md) (that file ships in the plugin and must stay in sync with the emitters in `internal/feishu/degrade.go` / `internal/notion/degrade.go`).
78
78
79
79
## manifest.sqlite (`internal/manifest/`)
80
80
@@ -157,7 +157,7 @@ The **doctor probes** are the foundation of onboarding: the structured failure c
`skill/` is the plugin root, dual-manifested for both supported agents: `.claude-plugin/plugin.json` (Claude Code) + `.codex-plugin/plugin.json` (Codex) + `bin/opendoc` + the skill itself under `skills/opendoc/` (`SKILL.md` + `references/` + `scripts/`). Distribution is marketplace-only, via the separate catalog repo `arcships/plugins`, whose entries use `git-subdir` sources pointing at this repo's `skill/` — installs sparse-fetch only that directory, never the Go source. The catalogs at this repo's root (`.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`) are the dev-only `arcships-dev` marketplace that installs from the local working tree. End users get the engine binary via the bundled `scripts/download-binary.sh`, which installs it at the stable, plugin-independent path `~/.opendoc/bin/opendoc` — plugin directories are unsuitable as the binary's home because hosts variously re-provision them per session (Claude desktop app), mount them read-only (claude.ai cloud), or version-stamp them so each update starts from a clean package (Codex, Claude Code CLI cache). SKILL.md's invocation contract: `command -v opendoc` first (a dev checkout's plugin `bin/` is on the Claude Code CLI's PATH), falling back to `~/.opendoc/bin/opendoc`. Unattended launchd invokes the binary via an absolute path — the stable path keeps the plist valid across plugin updates (see [skill/skills/opendoc/references/launchd/](../../skill/skills/opendoc/references/launchd/)).
163
+
`plugin/` is the plugin root, dual-manifested for both supported agents: `.claude-plugin/plugin.json` (Claude Code) + `.codex-plugin/plugin.json` (Codex) + `bin/` + the skill itself under `skills/opendoc/` (`SKILL.md` + `references/` + `scripts/`). Distribution is marketplace-only, via the separate catalog repo `arcships/plugins`, whose entries use `git-subdir` sources pointing at this repo's `plugin/` — installs sparse-fetch only that directory, never the Go source. The catalogs at this repo's root (`.claude-plugin/marketplace.json`, `.agents/plugins/marketplace.json`) are the dev-only `arcships-dev` marketplace that installs from the local working tree. End users get the engine binary via the bundled `scripts/download-binary.sh`, which installs it at the stable, plugin-independent path `~/.opendoc/bin/opendoc` — plugin directories are unsuitable as the binary's home because hosts variously re-provision them per session (Claude desktop app), mount them read-only (claude.ai cloud), or version-stamp them so each update starts from a clean package (Codex, Claude Code CLI cache). What `bin/` ships instead is a committed shim (`bin/opendoc`) that execs, in order: `$OPENDOC_ENGINE` → `bin/opendoc-dev` (the gitignored dev build) → `~/.opendoc/bin/opendoc`. Claude Code puts an enabled plugin's `bin/` on the Bash tool's PATH, so bare `opendoc` works there; Codex has no PATH mechanism, so SKILL.md's invocation contract resolves the path without ever exiting non-zero: `OPENDOC=$(command -v opendoc || echo "$HOME/.opendoc/bin/opendoc")`. Unattended launchd invokes the binary via an absolute path — the stable path keeps the plist valid across plugin updates (see [plugin/skills/opendoc/references/launchd/](../../plugin/skills/opendoc/references/launchd/)).
0 commit comments