Ivan's Blog
项目实践

Tuckmark

Tuckmark 是一个 agent-native label printing workspace,统一承载打印机发现、能力探测、模板渲染、批量预览、位图打印,以及 CLI、MCP、HTTP 和 Web surfaces(README.md)。

  • Developer utility
  • Progressive web app
  • Application icon
  • Worktree bootstrap

目录

技术栈

运行与交付

CI 工作流
  • ci-main.yml
  • ci-pr.yml
  • label-gate.yml
  • notify-release-failure.yml
  • pages.yml
  • release.yml
能力标记
  • bun_lock
  • github_actions
  • package_json
  • pnpm_lock
JSON

Purpose

Tuckmark 是一个 agent-native label printing workspace,统一承载打印机发现、能力探测、模板渲染、批量预览、位图打印,以及 CLI、MCP、HTTP 和 Web surfaces(README.md)。它位于 detonger 之上:Tuckmark 负责产品级模板、库存与运行时边界,detonger submodule 负责更低层的传输和控制;本项目不把物理打印能力隐式暴露给任意 Agent,server-side print 仍需显式开关和 capability checks(README.md、docs/specs/m2ksq-tuckmark-bun-pages-release-contract-initialization/SPEC.md)。

Taxonomy

  • Tags: Developer utility, Progressive web app, Application icon, Worktree bootstrap

Repository map

  • packages/core 维护共享领域模型、渲染、artifact storage 和 detonger integration;packages/server 提供 HTTP API;packages/cli 和 packages/mcp 暴露操作与 Agent-facing surfaces。
  • apps/web 是正式 Web app,同时产出 browser-static Pages bundle;plugins/inventory 保存库存和 data-directory template domain。
  • detonger 以 git submodule 形式存在。scripts/setup.ts 负责初始化 submodule、安装 hooks 和同步本地资源;.github/ 则拆出 CI、质量门禁、Pages 与 durable release pipeline。

Runtime and delivery

Tuckmark 以 Bun workspace 为主要本地工具链,package.json 的 setup、dev:preview、dev:server、dev:web、dev:storybook、test、check 和 build scripts 区分完整产品预览、单独 Web、组件工作和 Pages 发布。默认 dev:preview 同时启动 packages/server 与 apps/web,并为当前 worktree 解析独立的 DEVD instance 和 data directory;正式用户数据不会被隐式复制(README.md、scripts/dev-preview.ts、scripts/dev-data-prepare.ts)。

lefthook.yml 的 post-checkout command 调用 scripts/sync-worktree-resources.ts,pre-commit 负责 format,commit-msg 负责 commitlint。scripts/test-worktree-bootstrap.ts 创建真实 linked worktree,重复执行资源同步并验证 .env.local 的缺失文件恢复,因此这里的 Worktree bootstrap 是 repo-owned、幂等、copy-missing 的 readiness contract,而不是某个维护者的口头步骤(lefthook.yml、scripts/test-worktree-bootstrap.ts)。

发布面使用 PR labels 作为 release intent,mainline release 由 durable snapshot 生成 bundles、release notes 和 Pages deployment(.github/pr-label-release.json、.github/quality-gates.json、.github/workflows/release.yml、.github/workflows/pages.yml)。

Architecture notes

产品运行时区分 server-http 与 browser-static 两条 surface。Web 端通过显式 API abstraction 连接 server,browser-static 则使用相对 asset URL、PWA manifest、service worker 和版本探针维护离线 shell 与非阻塞更新(docs/specs/m2ksq-tuckmark-bun-pages-release-contract-initialization/SPEC.md、apps/web/src/pwa-lifecycle.ts、apps/web/public/)。模板、库存、设置、备份和 archive 由 DEVD 权威拥有;Web、native CLI 与 Agent Import 通过 named IPC 或 /api/data 进入同一数据边界,避免从 Web 或 Agent 直接猜测本地 data directory(README.md、packages/server/、packages/ipc/)。

打印路径保持隔离:browser-direct path 由浏览器渲染并通过 Web Bluetooth 发送,service-api path 由 server 与 detonger 控制硬件,二者使用不同的显式开关(README.md、apps/web/src/browser-direct-path.ts)。

Workflow and quality gates

bun run check 串联 lint、format check、typecheck、各 package tests、Web tests 与 build;Web 还维护 Vitest、Playwright 和 Storybook interaction/a11y surface(package.json、apps/web/package.json、apps/web/src/*.test.tsx、apps/web/src/*.stories.tsx)。CI 把 PR、main、label gate、release、Pages 和 release failure notification 拆成独立 workflow,并以 .github/quality-gates.json 声明 required checks。Worktree smoke 是独立的 repo-local contract test,不应被普通 Web e2e 替代(scripts/test-worktree-bootstrap.ts、.github/workflows/ci-pr.yml)。

Reusable decisions

  • 对多 package Bun workspace,用单一 scripts/setup.ts 先初始化 submodule,再安装 hooks 和同步缺失本地资源;让新 linked worktree 可重复执行,而不是依赖当前目录是否碰巧有缓存。
  • 生产数据、template archive 和 DEVD instance 通过明确 IPC/data-directory contract 隔离;开发 preview 可以使用 worktree-specific disposable data,但不默认复制正式用户数据(README.md、scripts/dev-data-prepare.ts)。
  • browser-static 的 launch shell、service-worker version cache 和 release metadata 应作为一个 install/runtime contract 维护,而不是把 Pages 当成普通静态文件上传。
  • application icon 作为 browser-static 安装面的一部分,应从 canonical mark 派生 regular、maskable 与 Apple 资产,并在发布 bundle 中让 URL 与内容代际一起更新;平台圆角和阴影不应预烘焙进通用源图。
  • Worktree bootstrap 只做 copy-missing、幂等同步和必要初始化;已有 .env.local 或 worktree-local data 不应被覆盖(scripts/sync-worktree-resources.ts、scripts/test-worktree-bootstrap.ts)。

Risks and open questions

  • detonger 是 submodule,fresh checkout 若未运行 git submodule update --init --recursive 会缺少底层控制能力;setup 失败应明确暴露,不应伪装成 Web-only 可用(scripts/setup.ts、README.md)。
  • browser-direct 与 service-api 两条打印路径拥有不同的权限和硬件前提,新增功能不能把一个路径的成功当作另一个路径的验证(README.md)。
  • Pages/browser-static 的 service worker、版本探针和离线缓存是高风险交付面;发布、回滚和 cache readiness 需要继续由 Playwright/Storybook 证据锁住(docs/specs/m2ksq-tuckmark-bun-pages-release-contract-initialization/SPEC.md)。

Evidence index

  • README.md
  • package.json
  • pnpm-workspace.yaml
  • lefthook.yml
  • scripts/setup.ts
  • scripts/sync-worktree-resources.ts
  • scripts/test-worktree-bootstrap.ts
  • apps/web/package.json
  • apps/web/public/manifest.webmanifest
  • apps/web/src/pwa-lifecycle.ts
  • apps/web/src/pwa/
  • docs/specs/m2ksq-tuckmark-bun-pages-release-contract-initialization/SPEC.md
  • .github/quality-gates.json
  • .github/workflows/ci-pr.yml
  • .github/workflows/release.yml