DeepSeek Harness Remote
DeepSeek Harness Remote 可将手机或另一台电脑与你运行 DeepSeek Harness 的电脑安全连接,随时随地继续你的工作,方便随时查看进度并继续工作。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Paste markdown, get a link. No signup, no tracking. Opensource telegra.ph alternative.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Paste markdown, get a link. No signup, no tracking.
pencil.md is an open-source telegra.ph alternative for markdown.
Write something, publish it, share the link. If you keep the edit key, you can change it later.
/ command menu:
"Add image" (multi-file upload straight into the document) and
"Add carousel" (a swipeable ```carousel image gallery).draw.pencil.md — freehand, shapes, images,
and Obsidian-style live-markdown text, with the same save/share/edit flow.chat.pencil.md — people and agents, live, by
link; deleted 24 hours after the last message.edit_token.paste markdown -> publish -> get a URL
Pages are public. Editing requires the owner cookie or the edit_token returned
by the API. Lose both and the page becomes read-only.
chat.pencil.md is the third sibling app (matched by the chat. hostname).
Each chat is one SQLite-backed Durable Object (ChatRoom, src/chat/room.ts)
addressed by its slug:
join
(nickname + random pattern avatar). Up to 100 participants.?after=<seq>&wait=25) or MCP: the chat tools are part
of the main connector at pencil.md/mcp (next to pages and drawings);
chat.pencil.md/mcp serves just the chat tools with no auth.chat/<slug>/.deleteAll() — nothing is kept.API reference: /api#chat.
draw.pencil.md is a sibling app served by the same Worker (matched by the
draw. hostname). It's a vanilla infinite canvas:
A drawing is stored as a JSON scene ({ schemaVersion, elements[], viewport })
in the drawings table; pasted images and the share thumbnail live in R2.
Identity is shared with pencil.md via a cookie scoped to the apex domain.
Create a drawing with POST https://draw.pencil.md/ and a JSON body
{ title, scene, thumb? }, where scene is the stringified JSON of
{ schemaVersion: 1, viewport: { x, y, zoom }, elements: [...] }. Each element:
{ "id": "a", "type": "stroke", "points": [[x,y],…], "color": "#1A1714", "width": 3, "dash": "solid" }
{ "id": "b", "type": "shape", "shape": "rect|ellipse|line|arrow",
"x": 0, "y": 0, "w": 160, "h": 90, "color": "#2B5C8A", "width": 4, "dash": "dashed", "fill": false }
{ "id": "c", "type": "text", "x": 0, "y": 0, "md": "# Title", "color": "#1A1714", "fontSize": 24 }
{ "id": "d", "type": "image", "x": 0, "y": 0, "w": 200, "h": 120, "url": "/img/abc.png" }
Layout rules agents must account for (there is no auto-layout):
\n in md is its own line; the block grows to its
widest line. Insert your own line breaks.fontSize is the base size. Markdown headings scale it: # ≈ 1.9×,
## ≈ 1.5×, ### ≈ 1.25×. Line height is 1.5× the (scaled) size.
So a # Heading at fontSize: 40 occupies ≈ 40 × 1.9 × 1.5 ≈ 114px of height —
budget vertical space accordingly before placing the next element.md supports the same live markdown as the editor (headings, **bold**,
*italic*, `code`, ~~strike~~, ==mark==, > quote, - list, links).color is any hex; dash is solid | dashed | dotted; fill applies to
rect/ellipse. Images must reference an issued /img/… key (upload via
POST /api/images); external URLs are rejected.viewport is how the drawing opens (pan x/y + zoom).thumb (optional) is a data:image/png;base64,… used as the share/OG image;
the editor renders it from the canvas, so it mirrors heading scaling and fills.The Worker also serves an MCP server at /mcp so Claude, ChatGPT and any
other MCP client can publish and edit pages and drawings on the user's behalf.
Users add it from /connect; the server handles OAuth 2.1 itself (PKCE S256,
client-ID metadata documents, dynamic registration, refresh-token rotation,
revocation) and binds the issued tokens to the approving browser's
pencil_uid identity — no account system is introduced.
POST /mcp Streamable HTTP, stateless, dual-era (2026-07-28 + legacy initialize)
GET /.well-known/oauth-protected-resource[/mcp]
GET /.well-known/oauth-authorization-server
POST /oauth/register GET|POST /oauth/authorize POST /oauth/token POST /oauth/revoke
GET|POST /connect/claim/:code one-time "sign this browser in" link
GET /connect /privacy /terms landing + legal pages the directories require
Tools: create_page, get_page, update_page, list_pages,
set_page_options, delete_page, upload_image, create_drawing,
get_drawing, update_drawing, list_drawings, set_drawing_options,
delete_drawing, get_browser_login_link. Read tools carry
readOnlyHint, write tools destructiveHint, so hosts confirm the latter.
Self-hosters: run migration 0006_oauth.sql (npm run db:migrate). To list in
the ChatGPT plugin directory set the OPENAI_APPS_CHALLENGE var to the token
from the OpenAI portal; it is served at /.well-known/openai-apps-challenge.
The directory submission kit (listing copy, plugin manifest, test cases) lives
in docs/connector/.
Recommended edge rate limit (in addition to the table below): /oauth/*
POST — 50 requests / 10 s / IP.
You need a Cloudflare account, Node 20+, and wrangler through npm.
git clone https://github.com/botpapa/pencil
cd pencil
npm install
# 1. Authenticate with Cloudflare.
npx wrangler login
# 2. Provision storage.
npx wrangler d1 create pencil-md
# Copy the returned database_id into wrangler.jsonc d1_databases[0].database_id
npx wrangler r2 bucket create pencil-og # cached OG images
npx wrangler r2 bucket create pencil-draw-img # draw canvas images + thumbnails
# 3. Set the cookie-signing secret.
openssl rand -base64 32 | npx wrangler secret put COOKIE_SECRET
# 4. Apply migrations.
npm run db:migrate
# 5. Build and deploy.
npm run deploy
Open / and start writing. /health should return {"ok":true,"app":"pencil.md"}.
To serve the drawing canvas, add draw.<your-domain> as a custom-domain route
in your Wrangler config (it runs from the same Worker). Locally it's reachable
at http://draw.localhost:8787 with no extra setup.
cp .dev.vars.example .dev.vars
# Generate COOKIE_SECRET with: openssl rand -base64 32
npm run db:migrate:local
npm run dev
The dev server runs at http://localhost:8787.
npm run build # bundle client assets
npm run test # run Vitest suite
npm run typecheck # run TypeScript checks
npm run deploy # build and deploy to Cloudflare
POST /api/v1/pages create a page
GET /api/v1/pages/:slug read a page
PUT /api/v1/pages/:slug update a page
See /api on a running deployment for examples.
Cloudflare Workers + Hono
D1 for pages and drawings
R2 for cached OG images and canvas images
Vanilla TypeScript client (markdown + canvas)
markdown-it + sanitize-html
markdown-it.sanitize-html with a strict allowlist.unsafe-inline scripts./img/…)
images — a shared scene can't point a viewer's browser at arbitrary URLs.Creation and password endpoints are intentionally unauthenticated (no signup), so protect them at the edge with Cloudflare Rate Limiting rules rather than in the Worker. Recommended rules:
| Path | Method | Suggested limit |
|---|---|---|
/:slug/unlock (both apps) | POST | 10 / minute / IP |
/api/images (both apps) | POST | 30 / hour / IP |
/ and draw.*/ (create) | POST | 60 / hour / IP |
In-Worker, uploads and bodies are already size-capped (MAX_IMAGE_BYTES,
MAX_SCENE_BYTES) and require a Content-Length; the rate rules above bound
volume and brute-force.
Pull requests are welcome. Keep it small, readable, and privacy-friendly.
npm install
npm test
npm run typecheck
tests/e2e/production.test.ts exercises a live deployment via real fetch. It
is opt-in (separate config, never run by npm test).
npm run e2e:prod # hits https://pencil.md
E2E_BASE_URL=https://staging.example npm run e2e
Each run creates a handful of pages whose titles begin with e2e:. To clean
them out:
wrangler d1 execute pencil-md --remote \
--command "DELETE FROM pages WHERE title LIKE 'e2e:%'"
MIT.