Skip to content
Open
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
19 changes: 19 additions & 0 deletions external_plugins/craft/.zcode-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "craft",
"version": "0.1.4",
"description": "Craft Connector: read, search and create notes in Craft (craft.do) and maintain daily notes – via the official Craft API and the craftdocs:// URL scheme.",
"description_i18n": {
"en": "Craft Connector: read, search and create notes in Craft (craft.do) and maintain daily notes – via the official Craft API and the craftdocs:// URL scheme.",
"zh-CN": "Craft 连接器:通过官方 Craft API 和 craftdocs:// URL Scheme 读取、搜索、创建 Craft (craft.do) 笔记并维护每日笔记。"
},
"author": { "name": "Deebeli" },
"keywords": [
"craft",
"craft.do",
"notes",
"daily-notes",
"knowledge-base"
],
"skills": "./skills",
"commands": "./commands"
}
21 changes: 21 additions & 0 deletions external_plugins/craft/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Deebeli

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
89 changes: 89 additions & 0 deletions external_plugins/craft/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Craft Connector for ZCode

A ZCode plugin that connects the agent to [Craft](https://www.craft.do) (craft.do) on macOS:

- **Create notes** (`/craft-notiz`) – new document with a title and Markdown content
- **Search & read notes** (`/craft-suche`) – full-text search via `documents/search`
- **Daily notes** (`/craft-daily`) – read today's note and append entries
- **Open in Craft** – `craftdocs://` deep links for pages, search and daily notes

The primary path is the official [Craft API](https://connect.craft.do/api-docs);
the `craftdocs://` URL scheme is used for opening things in the app.
Source and issue tracker: <https://github.com/dbrussig/craft-connector>

## Requirements

- macOS with the Craft desktop app
- A Craft API connection: in Craft, open your space's **Connect** area, create an
API connection (e.g. "connect all documents"). Craft shows **two** values that
belong together: the **connection URL** (`https://connect.craft.do/links/<id>/api/v1`)
and the **key** (`pdk_…`).

## One-time setup (API credentials)

Store both values in a local env file, outside any project. Use a terminal so
nothing lands in your shell history (zsh syntax below):

```bash
mkdir -p ~/.config/craft-connector && chmod 700 ~/.config/craft-connector
umask 077
printf 'CRAFT_API_URL=%s\n' 'YOUR-CONNECTION-URL' > ~/.config/craft-connector/craft.env
read -s "CRAFT_API_KEY?Paste key and press Enter: "
printf 'CRAFT_API_KEY=%s\n' "$CRAFT_API_KEY" >> ~/.config/craft-connector/craft.env
unset CRAFT_API_KEY
chmod 600 ~/.config/craft-connector/craft.env
```

Sanity check (shows only space name/timezone, never the key):

```bash
set -a; source ~/.config/craft-connector/craft.env; set +a
curl -sS -H "Authorization: Bearer $CRAFT_API_KEY" "${CRAFT_API_URL%/}/connection"
```

URL and key are credentials. Never print them, paste them into chats, or commit them.

## Installation

- **Official marketplace (recommended):** ZCode → plugin manager → search for
**Craft Connector** → install → enable → restart ZCode.
- **From source / own GitHub marketplace:** add
<https://github.com/dbrussig/craft-connector> as a plugin marketplace
(Plugin Marketplace → Add) and install the `craft` plugin from it.

## Components

- `skills/craft/SKILL.md` – core knowledge: env handling, safety, API flows
- `commands/craft-notiz.md`, `commands/craft-suche.md`, `commands/craft-daily.md`
- No bundled MCP server, no background processes, no hooks

## Known API behavior (live-verified 2026-11-07)

- `POST /documents` **ignores** the `content` field – create documents with a title
only, then append content as blocks via `pageId` (the skill documents the
reliable two-step flow).
- The `documentId` inside `clickableLink` differs from the API-addressable page ID
(`items[].id`); the link opens Craft, but the ID is not usable with
`GET /blocks?id=`.
- `GET /documents?id=…` does not filter by ID, it returns the space's document list.

## Network access & side effects

- **Network:** the plugin talks only to the user's own Craft Connect API endpoint
(`https://connect.craft.do/links/<id>/api/v1`, shown when creating an API
connection in Craft), authenticated with the user's own credentials from the
local env file. No telemetry, no third-party services, no automatic cloud calls.
- **Writes:** the agent can append blocks to daily notes and pages and create new
documents in the connected Craft space – only within the scope of the user's
task. Deletions happen only on explicit per-object user requests.
- **Credentials:** read from `~/.config/craft-connector/craft.env` (outside any
project); never printed, logged or committed.
- **No hooks, no MCP server, no background processes** – the plugin is one skill
plus three slash commands executed by the agent.
- **Third-party service:** Craft (craft.do) and its Connect API; the
`craftdocs://` URL scheme opens the local Craft desktop app. This plugin is not
affiliated with or endorsed by Craft.

## License

MIT – see [LICENSE](./LICENSE).
82 changes: 82 additions & 0 deletions external_plugins/craft/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Craft Connector(ZCode 插件)

一个把 ZCode 智能体连接到 macOS 上 [Craft](https://www.craft.do)(craft.do)的插件:

- **创建笔记**(`/craft-notiz`)——新建带标题和 Markdown 内容的文档
- **搜索并阅读笔记**(`/craft-suche`)——通过 `documents/search` 进行全文检索
- **每日笔记**(`/craft-daily`)——读取今天的笔记并追加条目
- **在 Craft 中打开**——针对页面、搜索和每日笔记的 `craftdocs://` 深度链接

首选路径是官方 [Craft API](https://connect.craft.do/api-docs);`craftdocs://` URL
Scheme 用于在应用中打开内容。源码与问题反馈:<https://github.com/dbrussig/craft-connector>

## 环境要求

- macOS,并安装 Craft 桌面应用
- 一个 Craft API 连接:在 Craft 中打开所属 Space 的 **Connect** 区域,创建 API
连接(例如"连接全部文档")。Craft 会显示**两个**成对的值:**连接 URL**
(`https://connect.craft.do/links/<id>/api/v1`)和**密钥**(`pdk_…`)。

## 一次性配置(API 凭据)

把两个值保存到项目之外的本地 env 文件中,并在终端里操作,避免进入 shell
历史(以下为 zsh 语法):

```bash
mkdir -p ~/.config/craft-connector && chmod 700 ~/.config/craft-connector
umask 077
printf 'CRAFT_API_URL=%s\n' 'YOUR-CONNECTION-URL' > ~/.config/craft-connector/craft.env
read -s "CRAFT_API_KEY?粘贴密钥后回车: "
printf 'CRAFT_API_KEY=%s\n' "$CRAFT_API_KEY" >> ~/.config/craft-connector/craft.env
unset CRAFT_API_KEY
chmod 600 ~/.config/craft-connector/craft.env
```

连通性检查(只显示 Space 名称/时区,绝不显示密钥):

```bash
set -a; source ~/.config/craft-connector/craft.env; set +a
curl -sS -H "Authorization: Bearer $CRAFT_API_KEY" "${CRAFT_API_URL%/}/connection"
```

URL 和密钥属于凭据:绝不打印、粘贴到聊天中或提交到版本库。

## 安装

- **官方插件市场(推荐)**:ZCode → 插件管理器 → 搜索 **Craft Connector** →
安装 → 启用 → 重启 ZCode。
- **从源码 / 自建 GitHub 市场**:把 <https://github.com/dbrussig/craft-connector>
作为插件市场添加(Plugin Marketplace → Add),然后安装其中的 `craft` 插件。

## 组件

- `skills/craft/SKILL.md`——核心知识:env 处理、安全规则、API 流程
- `commands/craft-notiz.md`、`commands/craft-suche.md`、`commands/craft-daily.md`
- 不包含 MCP 服务器、后台进程或 hooks

## 已知的 API 行为(2026-11-07 实测)

- `POST /documents` 会**忽略** `content` 字段——先用标题创建文档,再通过
`pageId` 以块的形式追加内容(Skill 中记录了可靠的两步流程)。
- `clickableLink` 中的 `documentId` 与可通过 API 寻址的页面 ID
(`items[].id`)不同;该链接可打开 Craft,但其 ID 不能用于 `GET /blocks?id=`。
- `GET /documents?id=…` 不按 ID 过滤,而是返回整个 Space 的文档列表。

## 网络访问与副作用

- **网络**:插件只访问用户自己的 Craft Connect API 端点
(`https://connect.craft.do/links/<id>/api/v1`,在 Craft 中创建 API 连接时
显示),并使用本地 env 文件中用户自己的凭据进行认证。无遥测、无第三方服务、
无自动云端调用。
- **写入**:智能体可以在所连接 Craft Space 的每日笔记和页面中追加块、创建新
文档——且仅限用户任务范围内。删除操作仅在用户对具体对象明确提出请求时进行。
- **凭据**:从 `~/.config/craft-connector/craft.env`(位于所有项目之外)读取;
绝不打印、记录或提交。
- **无 hooks、无 MCP 服务器、无后台进程**——本插件由一个 Skill 和三条斜杠命令
组成,由智能体执行。
- **第三方服务**:Craft(craft.do)及其 Connect API;`craftdocs://` URL Scheme
用于打开本地 Craft 桌面应用。本插件与 Craft 官方无关联、亦未获其背书。

## 许可证

MIT——见 [LICENSE](./LICENSE)。
20 changes: 20 additions & 0 deletions external_plugins/craft/commands/craft-daily.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
description: Read or append to today's Craft daily note
argument-hint: [entry – optional; without an argument the current note is shown]
---

Work with today's Craft daily note.

Arguments: $ARGUMENTS

Steps:

1. Follow the `craft` skill flow: load the env file and check the connection.
2. Read today's note: `GET /blocks?date=today` with `Accept: text/markdown`.
Without an argument: present the content in a clear structure (tasks, notes,
events).
3. With an argument: format the entry as Markdown and append it via `POST /blocks`
with `position: {"date":"today"}` (form see skill). Report success or failure
concretely; on 4xx calibrate instead of retrying blindly.
4. Afterwards offer to open the daily note in Craft
(`craftdocs://openByQuery?query=today`).
24 changes: 24 additions & 0 deletions external_plugins/craft/commands/craft-notiz.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
description: Create a new note in Craft
argument-hint: [title | title + content | "from the conversation"]
---

Create a new note in Craft.

Arguments: $ARGUMENTS

Steps:

1. Follow the `craft` skill flow: load the env file and check the connection via
`GET /connection`. If setup is missing, point to the README setup – don't guess.
2. Determine the content:
- If $ARGUMENTS contains content, structure it as Markdown.
- If only a title or "from the conversation" is given, prepare suitable content
from the current conversation as Markdown. Don't invent anything, mark gaps.
3. Create the document via `POST /documents` **with title only**, then append the
content as blocks using `pageId` = `items[].id` (form see skill, section 4 –
the `content` field is ignored by the API). Then read back and verify the
content against the intended text. On 4xx: show status and error message,
calibrate, don't retry blindly.
4. Report success: title, location (folder/unsorted), document ID and deep link.
Ask whether to open the note in Craft (`craftdocs://open`).
21 changes: 21 additions & 0 deletions external_plugins/craft/commands/craft-suche.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
description: Search and read Craft notes
argument-hint: [search term or question]
---

Search the user's Craft notes and report the hits.

Arguments: $ARGUMENTS

Steps:

1. Follow the `craft` skill flow: load the env file and check the connection.
2. Derive a solid search term from $ARGUMENTS (don't throw the whole sentence as a
phrase; with multiple terms search individually and merge the hits).
3. Run `GET /documents/search?include=…`; set `location=` if needed
(default: all locations except trash).
4. Read the up to five most relevant documents individually via
`GET /blocks?id=…` with `Accept: text/markdown`.
5. Report: per hit title, location (section/quote), deep link and relevance. Quote
verbatim where the exact wording matters. No hits → say so openly and suggest
alternative search terms, don't invent them.
Loading