Commit graph

34 commits

Author SHA1 Message Date
Tuola-waj
5abca505b1
add FlowAI live dashboard template skill (#801)
* add flowai live dashboard template skill

Introduce a new template-mode skill under the live-artifacts scenario with a default interactive example and seed template so users can generate polished, refresh-ready team dashboards quickly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* add preview screenshot for flowai live dashboard template

Attach the provided dashboard screenshot under docs/screenshots/skills so the template contribution includes a visual preview artifact.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(flowai-template): reposition as static prototype dashboard skill

Address review feedback on PR #801:

- SKILL.md: drop `scenario: live-artifacts` and live-related triggers;
  align with peer single-page dashboard skills using
  `mode: prototype` + `scenario: operations` so the four-file
  live-artifact contract no longer applies.
- references/checklist.md: rewrite quality gates around the static
  prototype scope (export-from-DOM, responsive breakpoints, theme-aware
  charts).
- assets/template.html:
  - CSV export now reads every visible row from the table DOM,
    including the Workflow column, instead of a hardcoded fixture.
  - Add 1300px and 720px breakpoints; the main grid stacks to one
    column, stat cards fall back to two then one, tabs wrap, table
    scrolls horizontally on phones.
  - Move chart colors into CSS variables (--chart-stroke,
    --chart-fill, --chart-axis, --chart-bar-label, --chart-bar-value)
    so dark-mode toggling re-derives them; chart canvases are
    re-rendered after theme switch.
  - Hash-sync tabs (#members | #details | #activity), animate the
    role bar chart only on first reveal of the details tab,
    fall back when CanvasRenderingContext2D.roundRect is unavailable,
    add Esc to exit zoom and prevent tooltip clipping.
- example.html: title cleanup to match new skill identity.

Localized content:
- Add `flowai-live-dashboard-template` to DE/FR/RU
  SKILL_IDS_WITH_EN_FALLBACK lists in apps/web/src/i18n so the
  e2e localized-content test passes.

---------

Co-authored-by: tuolaji <tuola@tuolajideMacBook-Air.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Tuola Ge <gexingli@refly.ai>
2026-05-07 19:07:45 +08:00
Joey-nexu
55aa24167b
add live-dashboard skill (#778)
* add live-dashboard skill

Notion-style team dashboard rendered as a Live Artifact.

Wires the OD 0.4.0 connector catalog (#381) end-to-end:

refresh-on-open, manual Refresh tween, auto-refresh, stale state.

Falls back to seeded mock data when no connector is bound.

* address PR #778 review comments

P1 — security and correctness:
- skills/live-dashboard/assets/template.html · skills/live-dashboard/example.html: escape every connector-derived string before innerHTML interpolation. Adds a tiny e() helper and routes feed.who/action/target/suffix/icon, row.title/icon/due/prio, person.name/color/id, KPI label/delta through it. Closes lefarcen #3200122795 + #3200122820.
- skills/live-dashboard/SKILL.md (live behavior section): align connector poll URL with references/connectors.md — POST /api/od/connectors/poll with { project, read } body, not /api/od/connectors/<id>/poll. Closes codex bot #3200100897.
- apps/web/src/i18n/content{,.ru,.fr}.ts: register live-dashboard in DE_/RU_/FR_SKILL_IDS_WITH_EN_FALLBACK so the localized-content e2e check passes. Closes mrcfps #3200122059.
- skills/live-dashboard/references/connectors.md: prepend a Status callout that names skills/live-artifact/ as the canonical file/CLI live-artifact contract and frames the HTTP shape as a forward-looking proposal sitting alongside it (out-of-the-box the artifact runs on seeded data; only seedNextChange() needs swapping when POST /api/od/connectors/poll lands). Closes lefarcen #3200122811.

P2 — quality and honesty:
- skills/live-dashboard/references/connectors.md: rewrite the auth_ref resolution step to match apps/daemon/src/media-config.ts (OD_MEDIA_CONFIG_DIR → OD_DATA_DIR → <projectRoot>/.od/media-config.json, $HOME/~/relative paths handled via expandHomePrefix). Closes codex bot #3200100906.
- skills/live-dashboard/example.html: switch the live-pill to a sticky Sample data state with a grey static dot, rewrite the callout to admit the figures are seeded fixtures, retitle the toast and the refresh tooltip, and refuse to flip to Live · synced inside updateTimes(). Adds a .pill-live.sample CSS variant. Closes lefarcen #3200122823.
- skills/live-dashboard/assets/template.html: hoist <meta name=od:project> from <body> into <head>. Closes lefarcen #3200122832.
- skills/live-dashboard/assets/template.html · example.html: add role=button + tabindex=0 + aria-current to every clickable .ws / .side-search / .nav-item, and wire a single document-level keydown handler that maps Enter/Space to a synthetic click for any role=button div (skipping real buttons / anchors / form controls). Closes lefarcen #3200122837.
- skills/live-dashboard/assets/template.html: implement the KPI tween + flash + snapshotKpi() the SKILL.md prose already promised — first render builds escaped cards, subsequent renderKpi(prev) calls tween numeric values and flash() the cells that actually changed; refresh() now calls snapshotKpi() before mutating state and forwards prev. SKILL.md spells out the wire-up. Closes lefarcen #3200122839.

* gate KPI tween + flash + row/feed highlight on prefers-reduced-motion

Addresses mrcfps's non-blocking review item on PR #778 (comment #3200614137,
template.html:453). The CSS @media (prefers-reduced-motion: reduce) block
already neutralizes CSS animations and transitions, but the new JS-driven
helpers kept moving for opted-out users:

- tweenText() scheduled requestAnimationFrame updates for 600ms
- flash() toggled the .flash highlight class for 700ms
- renderFeed()/renderRows() applied .feed-row.new / .db-row.changed
  classes which carry transient backgrounds even when their CSS
  animations are off

Both runtimes (assets/template.html and example.html) now share a
reduceMotion() helper (window.matchMedia('(prefers-reduced-motion:
reduce)').matches). When it returns true:

- tweenText()/tween() set the final value immediately and return
- flash() returns without touching the class
- renderFeed()/renderRows() pass null as the highlight id so the .new /
  .changed classes are never applied

Normal-motion users see the existing tween + flash + highlight pulse
unchanged. Keeps the P0 prefers-reduced-motion row in
references/checklist.md honest for agents that copy this template
verbatim.

---------

Co-authored-by: joey <joey@joeydeMacBook-Air.local>
Co-authored-by: joeylee12629-star <joeylee12629-star@users.noreply.github.com>
2026-05-07 18:21:22 +08:00
Vedank Vansia
b95ba5e79e
add waitlist-page skill (#555)
* add waitlist-page skill

* fix(waitlist-page): address PR review feedback

- Remove novalidate from example.html form
- Ensure checkValidity() guard present in both template and example
- Remove required from firstname input in template
- Add token escaping rules to SKILL.md workflow (step 9)
- Add token mapping/fallback rules for BORDER/SUCCESS/STRIPE/DECO (step 7)
- Fix mobile quality gate to be measurable (375x667, 390x844)
- Promote hardcoded #fff, rgba(0,0,0,0.9), rgba(255,255,255,0.9) to
  CSS variables (--btn-label, --ticker-bg, --ticker-fg) in template
- Create references/checklist.md with P0/P1/P2 tiers; countdown timer
  is now a hard P0 prohibition; a11y gate split into six specific checks"

* fix: resolve P0 color and accessibility issues

- Add role=status to success messages for screen reader announcement
- Replace all hardcoded hex/rgba colors with template tokens
- Update SKILL.md with comprehensive color token mapping rules
- SVG decorations now use CSS variables instead of hardcoded strokes

* fix: address PR review feedback on scope, scrolling, and font tokens

Fixes:
- Restore pricing-page files accidentally deleted in previous commit
  (skills/pricing-page/SKILL.md and example.html now back on branch)
- Remove temp-original.html scratch file from commit
- Fix mobile viewport scrolling: change 'height: 100vh; overflow: hidden'
  to 'min-height: 100svh; overflow-x: hidden; overflow-y: auto'
  so content doesn't clip on 375×667 and 390×844 screens
- Split font tokens into URL-safe and CSS-safe variants:
  * {{DISPLAY_FONT_URL}} and {{DISPLAY_FONT_CSS}} for display fonts
  * {{BODY_FONT_URL}} and {{BODY_FONT_CSS}} for body fonts
  This fixes encoding: spaces as '+' in Google Fonts URL, literal in CSS
- Update SKILL.md frontmatter with new font input fields
- Update token escaping rules to document the split

* fix: resolve token contract mismatch and remove hardcoded colors from example.html

P0 Fixes:
- Remove all hardcoded colors from example.html (except #2D6A4F for --success)
- Use CSS variables for all color values: --btn-label, --ticker-bg, --ticker-fg, --deco-stroke
- Fix gradient to use var(--deco) instead of hardcoded #D1632B
- Apply consistent color expressions across decorations and text

Token Contract Fixes:
- template.html now uses full CSS expressions for opacity-based colors:
  * {{BORDER_EXPRESSION}} instead of {{BORDER_HEX}} (no # prefix)
  * {{BTN_LABEL_EXPRESSION}} instead of {{BTN_LABEL_HEX}}
  * {{TICKER_BG_EXPRESSION}}, {{TICKER_FG_EXPRESSION}}, {{DECO_STROKE_EXPRESSION}}
- Remove extra quotes from font tokens in template:
  * --font-body: {{BODY_FONT_CSS}} instead of '{{BODY_FONT_CSS}}'
  * Font tokens are already quoted if needed, no wrapping
- Update SKILL.md frontmatter with all color expression inputs and descriptions
- Update token mapping rules to clarify the new contract:
  * Hex tokens: simple six-digit colors
  * Expression tokens: full CSS values (rgba/color-mix), no # prefix
  * Font tokens: CSS font-family values, no extra wrapping
- Update token escaping rules to reflect new contract

This ensures agents can follow SKILL.md instructions without producing invalid CSS.

* fix: remove final hardcoded colors from example.html - P0 complete

- Button text: #fff → var(--btn-label)
- Ticker background: rgba(0,0,0,0.9) → var(--ticker-bg)
- Ticker text: rgba(255,255,255,0.9) → var(--ticker-fg)
- Logo text: fill=white → fill=var(--btn-label)

All colors now derive from design system tokens. Only #2D6A4F (--success) allowed hardcoded exception.

* fix: correct --btn-label contrast for CTA readability

Change --btn-label from #1A1410 (same as button background) to #FDE8DF
(light background color) so button text has proper contrast against
the dark --accent button background.

This resolves the black-text-on-black issue that broke the main
email capture action and satisfies the checklist button contrast gate.

* fix: add visible focus indicator for input accessibility

P1 Accessibility Polish:
- Update .form-row input:focus to include outline and outline-offset
- Before: border-color only, removing default outline (no visible focus)
- After: border-color + 2px outline + 2px offset (clear focus indicator)

This satisfies the checklist P1 focus-style gate and ensures keyboard
users can see which form field has focus. Both example.html and
template.html updated so agents copy complete focus patterns.

* fix: remove hardcoded logo shadow color - P0 compliance

- Add --logo-shadow CSS variable derived from foreground
- example.html: box-shadow 0 2px 8px rgba(0,0,0,0.08) → var(--logo-shadow)
- template.html: add {{LOGO_SHADOW_EXPRESSION}} placeholder
- Update SKILL.md with logo_shadow_expression input and mapping rules

All colors in example.html now derive from design system tokens.
Ensures agents copy compliant reference without hardcoded shadow colors.

* fix: register waitlist-page skill in i18n localized content registry

Add waitlist-page to locale-specific skill fallback lists so the web
content coverage test passes when the new skill is discovered:

- apps/web/src/i18n/content.ts: Add to DE_SKILL_IDS_WITH_EN_FALLBACK
- apps/web/src/i18n/content.fr.ts: Add to FR_SKILL_IDS_WITH_EN_FALLBACK
- apps/web/src/i18n/content.ru.ts: Add to RU_SKILL_IDS_WITH_EN_FALLBACK

The skill falls back to English localization for now; localized
descriptions can be added to each locale file later.

Fixes: web content coverage test now passes (6/6 tests).

* fix: wire template and checklist into skill workflow as mandatory gates

Restructure waitlist-page SKILL.md workflow to enforce the hardened
template-based execution path:

- Add Preflight section: agents MUST read assets/template.html first
- Add explicit token mapping and escaping rules (steps 2-4)
- Add mandatory Validation section: run references/checklist.md P0/P1
  gates BEFORE emitting artifact; fail fast if any P0 gate fails
- Update Quality gates section to emphasize template-based execution
  and reinforce P0/P1 gate hierarchy
- Update Output section: only emit after P0 passes; re-validate on
  iterations

This prevents agents from writing HTML from scratch or skipping the
hardened seed (template) and validation (checklist) that this PR adds.

* refactor(waitlist-page): replace literal logo placeholder with token

- Replaced `[LOGO]` with `{{LOGO_MARK}}` in template.html
- Added `logo_mark` to inputs in SKILL.md
- Updated mapping rules in SKILL.md to handle raw SVG or text for logo
- Updated P0 validation gates in SKILL.md and checklist.md to ensure logo replacement

* fix(waitlist-page): enforce strict escaping and sanitization for logo token

- Mandate HTML-escaping for text initials.
- Enforce strict allowlist-based sanitization for inline SVG (stripping `<script>`, `on*`, `<foreignObject>`, `href`, `xlink:href`, `url()`).
- Add fallback to escaped text initials for invalid/unsafe SVG.

* docs(waitlist-page): sync logo_mark frontmatter description with rules

- Updated the `logo_mark` input description in the SKILL.md frontmatter to explicitly outline the new requirements for HTML-escaped text or strict allowlist-sanitized SVG.

* fix(waitlist-page): add logo_fg_expression to guarantee contrast in logo mark text fallback

- Added `--logo-fg` CSS variable mapped to `{{LOGO_FG_EXPRESSION}}`.
- Updated `.logo-container` in `template.html` to inherit typography styles and apply `--logo-fg` for safe fallback when rendering escaped initials.
- Enforced WCAG AA contrast for logo initials against container background in `checklist.md`.

* refactor(waitlist-page): migrate hex color tokens to full css expressions

* refactor(waitlist-page): strict validation for color expression tokens to prevent CSS injection

* docs(waitlist-page): update validation summary to reflect strict color grammar

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
2026-05-07 17:39:17 +08:00
github-actions[bot]
71a344f951
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#718)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-07 10:12:29 +08:00
Mario
2afb002a62
docs: fix broken links to pi-ai (404), split into coding-agent and ai packages (#277)
* docs: fix broken pi-ai links, point to correct pi-mono packages

All links to https://github.com/mariozechner/pi-ai returned 404 after
the project was restructured into the badlogic/pi-mono monorepo.

- "pi" / "Pi" (the CLI tool the daemon scans for) now points to
  packages/coding-agent
- "pi-ai" (the multi-provider LLM API) now points to packages/ai
  via the shared [piai] reference definitions

Closes #275.

* fixup! Merge remote-tracking branch 'upstream/main' into docs/fix-pi-pi-ai-links

Fix [piai] reference in README.ar.md and README.es.md: was incorrectly
pointing to packages/coding-agent (pi CLI) instead of packages/ai (pi-ai
provider library).

* fixup! fix row order in README.uk.md: move Pi after DeepSeek TUI to match English README
2026-05-07 00:41:11 +08:00
mamba
570d06419c
feat[qoder cli] add Qoder CLI agent support (#626)
* chore(agent): 增加对 Qoder CLI 的支持和识别

- 在 QUICKSTART 文档中添加 Qoder CLI 为可选本地 agent CLI
- 更新代码中 agents.ts 注释包含 Qoder CLI 扫描支持
- 修改首次加载时检测的可用 CLI 列表,加入 Qoder CLI
- 在多个语言版本的 README 中增加 Qoder CLI 支持及相关徽章统计
- 更新 agent 适配器与事件解析相关的代码注释和文档,包含 qoder-stream-json 解析器
- 调整 Windows 下 spawn 行为以支持 Qoder CLI 的 stdin 提供 prompt
- 修复多语言文档对支持的 CLI 数量描述错误,确保数据保持同步

Change-Id: I388f2f61c60ce8faa7cef5d84eb407950f8bdbfb
Co-developed-by: Qoder <noreply@qoder.com>

* chore(agent): 增加对 Qoder CLI 的支持和识别

- 在 QUICKSTART 文档中添加 Qoder CLI 为可选本地 agent CLI
- 更新代码中 agents.ts 注释包含 Qoder CLI 扫描支持
- 修改首次加载时检测的可用 CLI 列表,加入 Qoder CLI
- 在多个语言版本的 README 中增加 Qoder CLI 支持及相关徽章统计
- 更新 agent 适配器与事件解析相关的代码注释和文档,包含 qoder-stream-json 解析器
- 调整 Windows 下 spawn 行为以支持 Qoder CLI 的 stdin 提供 prompt
- 修复多语言文档对支持的 CLI 数量描述错误,确保数据保持同步

Change-Id: Id33f125b7c0b1a1c0b0274073da74d1578c324f7
Co-developed-by: Qoder <noreply@qoder.com>

* feat(agent-icon): 添加新的Qoder徽标SVG图形组件

- 新增qoderGlyph函数,返回指定大小的SVG格式图形
- 图形包含多路径定义,颜色使用深灰和绿色填充
- 该组件可用于替代或补充现有AgentIcon图标功能
- 提升应用程序的品牌标识和视觉表现力

Change-Id: I4eca18166b5e33bc6229b40b2531d5a54607a560
Co-developed-by: Qoder <noreply@qoder.com>

* Translate to English:

---

**docs(readme): update to expand CLI agents to 16**

- Increased the number of coding agent CLIs from 11 to 16
- New agents included: Devin for Terminal, Kiro CLI, Kilo, Mistral Vibe CLI, DeepSeek TUI

**docs(readme): update to expand supported coding agents to 16**

- Increased the number of supported code agent CLIs from 11 to 16
- Added support for new CLI tools: Devin for Terminal, Kiro CLI, Kilo, Mistral Vibe CLI, DeepSeek CLI
- Added automatic CLI detection and switching while maintaining support for more agents
- Added BYOK proxy TUI
- Expanded compatibility and support coverage in the README’s multiple language versions
- Reflected changes across all README translations (Arabic, German, French, Japanese, Korean)
- Updated badges and descriptions to reflect CLI count and feature changes
- Added event parsers and protocols for the new CLIs in the agent transport implementation
- Updated the BYOK proxy and tool exploration features to be compatible with the expanded CLIs

Change-Id: I89786b4a0b09bd279fb23265c2177076206fc5af
Co-developed-by: Qoder <noreply@qoder.com>

* feat(daemon): 支持 imagePaths 参数作为附件路径传递给 Qoder

- 修改 buildArgs 函数,添加 --attachment 参数处理 imagePaths 中的绝对路径
- 过滤并忽略空字符串、非字符串及相对路径的 imagePaths 项
- 在单元测试中覆盖 imagePaths 参数支持及无效项过滤逻辑
- 在文档中补充 Qoder 运行时适配器对 --attachment 参数的说明

Change-Id: Ibfc3583ba86c6d258d524912559e97b77bf1dc87
Co-developed-by: Qoder <noreply@qoder.com>

* docs(runtime): 说明Qoder适配器继承用户令牌的环境变量

- 添加文档说明检测代理仅为可用性探针,不进行身份验证
- 说明Qoder CLI账号状态独立,认证通过运行时错误路径反馈
- 详细描述子进程环境继承机制及静态环境变量与用户私密令牌区分
- 明确QODER_PERSONAL_ACCESS_TOKEN通过守护进程环境传递,不写入静态环境
- 解释Qoder验证由Qoder CLI负责,支持持久登录和自动化环境变量注入

test(agent): 添加QODER_PERSONAL_ACCESS_TOKEN环境变量继承测试

- 验证qoder适配器环境继承守护进程中的QODER_PERSONAL_ACCESS_TOKEN
- 确认qoder适配器未在静态环境变量中定义用户令牌
- 保证用户私密令牌不会被写入静态适配器环境配置

Change-Id: Ie61869afbe497df1b16879b4e47b35123f758ed8
Co-developed-by: Qoder <noreply@qoder.com>

* fix(daemon): 改进Qoder模式支持及错误处理机制

- 更新Qoder CLI参数,使用`--yolo`替代`--permission-mode bypass_permissions`
- 将工作目录参数从`--cwd`改为`-w`以符合Qoder文档
- 在agent流事件处理中新增错误捕获并通过SSE错误事件发送
- 运行结束时若检测到agent流错误,则标记运行失败
- 测试中fix(daemon): 优化Qoder代理参数与错误处理

- 调整Qoder启动参数,改用`--yolo`和`-w`替代旧参数,避开argv长度限制
- 增强代理流事件处理,捕获并通过SSE错误通同步更新Qoder参数使用及相应断言
- 新增端到端测试,覆盖Qoder助手错误通过SSE错误通道反馈及运行状态失败处理
- 补充工具函数辅助测试事件流读取与运行状态轮询

Change-Id: I5d933745c3659e093b0d2d807f22726e7f83eb48
Co-developed-by: Qoder <noreply@qoder.com>

* feat(qoder-stream): 识别并报告Qoder运行错误事件

- 新增messageFromResult函数以从结果对象提取错误信息
- 在处理result事件时根据is_error字段触发error事件
- error事件携带具体错误消息和原始数据
- 添加测试验证Qoder运行返回is_error且退出码为0时正确触发错误事件
- 更新qoder流解析测试以校验错误事件映射
- 在聊天路由测试中增加针对Qoder错误运行的端到端场景验证

Change-Id: Ie98ac518135dbec3181c52de5a49afdea993e279
Co-developed-by: Qoder <noreply@qoder.com>
2026-05-06 19:54:03 +08:00
Caprika
8eb9b1b506
Implement manual edit mode (#620) 2026-05-06 16:13:52 +08:00
github-actions[bot]
241846e1ef
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#592)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-06 09:21:39 +08:00
github-actions[bot]
e9fd616a5a
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#489)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-05 11:57:47 +08:00
Ajay Satish
ec7dafc007
feat(daemon): add Kilo CLI (ACP) (#480)
* docs(readme): refresh contributors wall

* docs(readme): refresh contributors wall

* feat: kilo cli

* fix: use default model option for kilo

* chore: add  agent_diff id unique test

* chore: add deepseek to docs
2026-05-05 09:17:56 +08:00
Tom Huang
da2b007a43
feat(daemon): add DeepSeek TUI as a code agent adapter (#439)
* feat(daemon): add DeepSeek TUI as a code agent adapter

Register `deepseek` (with `deepseek-tui` cargo-only fallback) in
AGENT_DEFS via `deepseek exec --auto [--model X] <prompt>` and plain-text
streaming. Ships `deepseek-v4-pro` / `deepseek-v4-flash` as fallback
model hints; users can paste any other id (incl. NIM / Fireworks /
SGLang routes) via the custom-model input.

Web UI gets a DeepSeek-blue gradient icon, label/alias mapping, and
docs/agent-adapters.md §5.9 documents the auth state, prompt-as-argv
Windows size limit, and the upstream gap that prevents stdin delivery
today (clap declares `prompt: String` as a required positional).

Adds .deepseek/ to .gitignore alongside the other per-agent runtime
data dirs so first-launch trust files don't leak into git.

* fix(daemon): drop unsupported deepseek-tui fallback bin

The `deepseek` dispatcher owns `exec` / `--auto`; `deepseek-tui` is the
runtime companion it invokes. Listing `deepseek-tui` in fallbackBins
advertised availability for a host that only had the TUI binary, but
buildArgs still emitted `<resolved> exec --auto <prompt>` — which
deepseek-tui itself doesn't accept, so the first /api/chat run would
fail. Upstream documents both binaries as required (npm and cargo paths
install them together), so the fallback didn't correspond to a supported
install. Pin the absence in the agents test and update docs §5.9 + the
adapter table to match.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* fix(daemon): pre-flight DeepSeek TUI prompts against argv byte budget

DeepSeek's exec mode requires the prompt as a positional argv arg (no
`-` stdin sentinel upstream), so a fully composed OD prompt — system
text + history + skills + design-system content + the user message —
can blow Windows' ~32 KB CreateProcess limit (or Linux MAX_ARG_STRLEN
on extreme edges) and surface as a generic spawn failure instead of
a DeepSeek-specific, user-actionable message. The adapter now declares
`maxPromptArgBytes = 30_000` (leaves ~2.7 KB argv headroom for `exec
--auto --model <id>` and Windows quoting), and the /api/chat spawn
path checks the composed prompt against that budget before calling
`spawn`. Oversized prompts fail fast with `AGENT_PROMPT_TOO_LARGE`
and guidance to reduce skills/design context or pick an adapter with
stdin support.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* test(daemon): pin DeepSeek argv-budget guard with regression tests

The previous spawn-path guard inlined the byte-budget check in the
chat handler, so the only safety net for the DeepSeek argv-only
prompt-delivery shape was a static "the field exists" assertion —
nothing actually exercised the AGENT_PROMPT_TOO_LARGE path or the
short-prompt happy path. Extract the check into a pure
`checkPromptArgvBudget(def, composed)` helper in agents.ts, call it
from /api/chat before bin resolution (so the guard is order-
independent and fires regardless of whether the adapter binary is
on PATH in CI), and add a regression test that exercises both the
oversized-prompt branch (over the conservative under-Windows-
CreateProcess budget) and the short-prompt branch, plus a UTF-8
byte-vs-codepoint case and a stdin-adapter no-op case so the guard
can't silently regress or leak onto adapters that ship the prompt
over stdin.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* fix(daemon): pre-flight DeepSeek prompts against Windows .cmd-shim quoting

The first-pass argv-byte guard only inspects the raw composed prompt, so
on Windows an npm-installed `deepseek` resolves to a `.cmd` shim and the
spawn path then wraps the call in `cmd.exe /d /s /c "<inner>"` with
every embedded `"` doubled by `quoteWindowsCommandArg`. A quote-heavy
prompt (code blocks, JSON-shaped skill seeds) under the 30,000-byte
budget can therefore still expand past CreateProcess's 32_767-char
`lpCommandLine` cap and surface as a generic spawn ENAMETOOLONG instead
of the DeepSeek-named, actionable `AGENT_PROMPT_TOO_LARGE` the budget
guard was meant to provide. Add a second pure helper
`checkWindowsCmdShimCommandLineBudget(def, resolvedBin, args)` that
mirrors the platform layer's per-arg quoting and recomputes the would-be
command line length whenever the resolved binary is a `.cmd` / `.bat`
shim, and call it from `/api/chat` after `buildArgs` / `resolveAgentBin`
so the same SSE error fires before `spawn`. Pin the new path with a
quote-heavy regression (prompt is under the byte budget but doubles
past the kernel cap) plus no-op tests for non-`.cmd` resolutions, null
bin, and stdin-only adapters so the guard can't drift back.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* fix(daemon): extend DeepSeek argv guard to direct .exe Windows installs

The cmd-shim guard added in 9011361 early-returned for non-`.cmd` /
`.bat` resolutions, so a Windows host that resolved `deepseek` directly
to a `.exe` (cargo-installed CLI, hand-built release, anything outside
the npm shim path) bypassed the post-`buildArgs` budget check entirely.
Direct `.exe` spawns skip the `cmd.exe /d /s /c "<inner>"` wrap, but
Node/libuv still composes a CreateProcess `lpCommandLine` by walking
each argv element through `quote_cmd_arg` — every embedded `"` becomes
`\"`, backslashes adjacent to a quote get doubled. A quote-heavy
prompt (code blocks, JSON-shaped skill seeds) under the 30,000-byte
`maxPromptArgBytes` budget can therefore still expand past the kernel's
32_767-char cap on those installs and surface as a generic spawn
ENAMETOOLONG instead of the actionable `AGENT_PROMPT_TOO_LARGE` the
guard was meant to provide.

Add a sibling pure helper `checkWindowsDirectExeCommandLineBudget(def,
resolvedBin, args)` that mirrors libuv's quoting math (empty -> `""`;
no whitespace/quote -> pass-through; quote-only -> simple wrap;
otherwise per-char escape with backslash-doubling around quotes and
trailing backslashes) and recomputes the would-be command line length
whenever the resolved binary is a non-shim Windows install. The two
Windows guards are mutually exclusive: the cmd-shim guard owns
`.bat` / `.cmd`, the direct-exe guard owns everything else, so a
single oversized prompt never double-emits an SSE error. POSIX paths
on POSIX hosts still skip both guards (no CreateProcess in play), and
stdin-delivered adapters still skip the entire post-buildArgs path.

Wire the new helper into `/api/chat` after the cmd-shim check, pin
the path with a quote-heavy regression on a `C:\Program
Files\DeepSeek\deepseek.exe` resolved bin (prompt under the byte
budget but past the kernel cap once libuv-quoted), plus no-op tests
for ordinary prompts, `.cmd`/`.bat` resolutions, POSIX paths,
null/empty bin, and stdin-only adapters, plus a mutual-exclusivity
assertion so the two guards' division of labour can't drift.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* fix(daemon): neutralize cmd.exe %var% expansion in DeepSeek argv

Wrap each `%` in `"^%"` inside `quoteWindowsCommandArg` so cmd.exe's
percent-expansion can't substitute env values into a `.cmd`-shim spawn
when the DeepSeek argv carries a prompt mentioning `%DEEPSEEK_API_KEY%`.
Mirror the change in the agents.ts helper used by the budget guard, add
`AGENT_PROMPT_TOO_LARGE` to the contracts so typed SSE consumers
recognize the existing daemon error code, and pin the literal-prompt
contract with regression tests.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
2026-05-05 00:08:26 +08:00
Daniel Duma, PhD
cfd359e05a
[codex] Fix Gemini CLI trust handling (#352)
* Fix Gemini CLI trust handling

* Preserve agent spawn env filtering
2026-05-04 21:39:59 +08:00
github-actions[bot]
fcca9fd7c9
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#406)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-04 09:18:45 +08:00
bezineb5
051d9b890d
feat(daemon): add Mistral Vibe CLI agent adapter (#354) 2026-05-03 16:19:09 +08:00
github-actions[bot]
4f04553948
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#334)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-03 09:32:13 +08:00
Tom Huang
6fa2077651
feat(web): add pet companion with Codex hatch-pet integration (#296)
* feat(web): add pet companion with Codex hatch-pet integration

Introduces a customizable floating pet companion (overlay + entry-view rail
+ composer menu + dedicated Settings → Pets section) that supports built-in
pets, user customization (glyph/image/spritesheet), and one-click adoption
of pets packaged by the upstream Codex `hatch-pet` skill via a new
`/api/codex-pets` daemon endpoint. Vendors the unmodified `hatch-pet`
skill under `skills/hatch-pet/` and adds i18n strings across all locales.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(scripts): sync community Codex pets from public catalogs

Adds `pnpm sync:community-pets` which fetches all pets from
codex-pet-share.pages.dev (paginated Supabase Functions API) and
j20.nz/hatchery (single-shot JSON), then writes each one as
`<id>/pet.json` + `<id>/spritesheet.webp` under
`\${CODEX_HOME:-\$HOME/.codex}/pets/`. The existing daemon
`codex-pets` registry already scans that folder, so synced pets
appear under Settings → Pets → Recently hatched and adopt with one
click — no manual upload. Supports --source/--out/--force/--limit
flags and validates magic bytes so HTML error pages never end up
masquerading as `.webp` files.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(daemon): tighten codex-pets validation and document vendoring

- sanitizeId now rejects ids that still contain `..` after collapsing,
  closing a defensive gap on the path-traversal guard for the
  `/api/codex-pets/:id/spritesheet` route.
- listCodexPets emits the sanitised folder name as the public id so the
  download route resolves directly against the on-disk folder, even when
  `manifest.id` differs (manual drops, sanitiser-touched manifests).
- Drop `@ts-nocheck` from `codex-pets.ts`; module is now strict-typed
  with explicit interfaces, an unknown-narrowed JSON.parse path, and a
  `pickString` helper guarding manifest fields one by one.
- Restrict the spritesheet response CORS header to sandboxed-iframe
  callers (Origin: null) instead of unconditional `*`, matching the
  existing raw-file route pattern. Same-origin web traffic does not
  need the header (web proxies `/api/*` through the daemon).
- Add `skills/hatch-pet/README.md` explaining the vendoring trade-off,
  provenance, and re-sync procedure.
- Add `docs/codex-pets.md` covering where pets live, how to populate the
  registry without Codex installed, and the manifest contract.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* fix(i18n): add pet.* keys to Hungarian locale

Hungarian locale was added on main after this branch diverged, so the new
pet.* dictionary keys never landed there and tsc -b reports hu's Dict as
incomplete once main is merged in.

Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)

* feat(web): atlas-driven pet animations + bundled community pets

Builds on the existing pet companion (#296) with a richer animation
loop, a curated set of community pets that ship with the repo, and a
one-click sync into ~/.codex/pets/.

- Atlas-mode rendering: PetSpriteFace can now play the full Codex 8x9
  sprite atlas and swap rows from a JS-driven frame index. PetOverlay
  classifies pointer interactions (idle / hover / drag-direction /
  long-idle waiting) and maps them to the matching atlas row, so the
  pet waves on hover, runs on drag, and falls into a waiting pose
  after 6s of stillness. Single-strip pets keep their existing CSS
  steps() animation, with the steps timing fixed to jump-none so frame
  cells line up on cell boundaries.
- Atlas adoption: PetSettings exposes both "Use full atlas (animated)"
  and "Freeze to this row" — full mode keeps every row for the
  interaction state machine, single-row mode crops one strip via the
  existing canvas helper. New prepareCodexAtlas downscales the atlas
  to a localStorage-friendly PNG while preserving the grid layout.
- Settings tabs: pet sources are now split into Built-in / Custom /
  Community tabs so each origin gets its own dedicated surface.
- Bundled pets: scripts/bake-community-pets.ts seeds a curated set
  (clippit, dario, nyako-shigure, slavik, trump, tux, yelling-dario,
  yorha-sit-2b) into assets/community-pets/. The daemon scans this
  alongside the user's ~/.codex/pets/ root, with user pets winning
  when ids collide. CodexPetSummary gains a `bundled` flag so the UI
  can tag those cards with a "Bundled" pill.
- One-click community sync: daemon-side port of sync-community-pets
  exposed via POST /api/codex-pets/sync. Returns the same
  wrote/skipped/failed/total summary the CLI prints. Web Pet settings
  surface this as a "Download community pets" button under the
  Community tab.
- Avatar dropdown + hide rail: EntryView's avatar button is now a
  small menu (mirrors the project-view AvatarMenu) with toggles for
  hiding/showing the pet rail and opening Settings. PetRail gets a
  matching × button for the same hide flow.
- Locales: 7 new pet.* keys for tabs, sync, hide/show, atlas full
  mode, and the Bundled pill — translated into all 13 supported
  locales.

Typechecks pass across all workspace packages; daemon + web vitest
suites stay green.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(web): bundled-pets built-in tab, ambient atlas animations, and community sync button

The Built-in tab now sources its catalog from the bundled spritesheets
at `assets/community-pets/` instead of the eight emoji placeholders that
felt boring next to the Codex hatch-pet atlases.

- Daemon: `listCodexPets` flags `bundled: true` by curated-set membership
  in `assets/community-pets/`, not by which folder the sprite happened to
  be read from. Previously a fully-synced user inbox preempted every
  bundled id and left the tab empty.
- Settings → Pets → Built-in renders the same sprite-card grid as
  Community, filtered by `bundled: true`, and reuses the existing
  `adoptCodexPet` flow. Community tab filters to non-bundled so the
  curated set never appears twice.
- Community tab gains the long-promised "Download community pets"
  trigger that calls `/api/codex-pets/sync` and shows an inline status
  line for the run summary. Strings already existed in every locale; we
  just plumbed the button.
- `PetOverlay` gets ambient atlas-row choreography — while idle, the
  overlay occasionally swaps `idle` for a random non-idle row (wave /
  hop / look) so the pet doesn't feel frozen. User gestures cancel the
  beat and take over instantly. `pickAmbientRow` lives next to
  `pickAtlasRow` so both row pickers share the fallback discipline.
- One-shot `migrateCustomPetAtlas` heals configs adopted before the
  overlay learned row switching by re-downloading the full spritesheet
  so hover / drag / ambient variety light up on next launch.
- `BUILT_IN_PETS` is now an empty array (the type stays for backwards
  compat); legacy configs whose `petId` still points at an emoji id
  (`mochi`, `pixel`, …) fall back to the user's custom slot in
  `resolveActivePet` so the overlay never renders blank.
- i18n: refresh `pet.tabBuiltInHint` (drop "emoji companions") and add
  `pet.builtInEmpty` across all locales.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 23:45:39 +08:00
Nader Dabit
8c61e43c44
Added Devin for Terminal (#301)
* added Devin for Terminal

* updates based on PR feedback
2026-05-02 22:40:08 +08:00
luo jiyin
96db795d7d
docs: fix spelling mistakes in CLI comment, spec, and video prompt (#300)
* fix: correct cli typo comment

* docs: fix spec typo

* fix: correct video prompt typo
2026-05-02 22:32:26 +08:00
Tom Huang
1edab990bb
feat(craft): add brand-agnostic craft references + Refero-derived lint rules (#225)
* feat(craft): add brand-agnostic craft references and refero-derived lint rules

Introduce `craft/` as a third top-level content axis alongside `skills/`
and `design-systems/`, holding universal (brand-agnostic) craft rules
that apply on top of any DESIGN.md. Skills opt in via a new
`od.craft.requires` front-matter array; the daemon resolves the slug
list and injects the matching files between DESIGN.md and the skill
body in the system prompt.

Initial vendor (MIT, adapted from referodesign/refero_skill): typography
craft, color craft, anti-ai-slop. Pilot wired on saas-landing.

Extend the existing lint-artifact pass with two refero-derived rules:
- P0 ai-default-indigo — solid #6366f1 / #4f46e5 / #4338ca / #8b5cf6 as
  accent (not just gradients) is the most-reported AI tell.
- P1 all-caps-no-tracking — `text-transform: uppercase` rules without
  ≥0.06em letter-spacing.

The craft loader silently drops missing files so a skill can
forward-reference future sections (e.g. `motion`) without breaking.

* fix(daemon): skip :root token blocks in ai-default-indigo lint

The ai-default-indigo P0 check scanned the whole HTML for the raw
hex, so brands that intentionally encode indigo as `--accent: #6366f1`
in :root and consume it via var(--accent) downstream were flagged
as AI-default — a false positive that forced the agent to "fix"
valid output. Strip :root token-definition blocks (including
attribute-selector theme variants) before scanning, mirroring the
existing pattern used by the raw-hex P1 check. Hex still flagged
when it appears in component rules or inline styles.

* docs(craft): address PR #225 P3 review feedback

- craft/README.md: explain why missing craft sections are silently
  dropped (forward-compatibility) instead of surfacing a warning.
- craft/typography.md: ground the 0.06em ALL CAPS tracking floor in
  Bringhurst-derived typographic practice rather than presenting
  the threshold as unattributed.
- craft/color.md: cover the edge case where a brand's DESIGN.md
  intentionally encodes indigo as --accent — `var(--accent)` uses
  remain unflagged because the linter only inspects hardcoded hex.
- docs/skills-protocol.md: link the "missing files dropped silently"
  note back to craft/README.md for the canonical slug list and the
  rationale behind the choice.

* fix(craft): address PR #225 P0 review feedback

- tools/pack: copy `craft/` into the packaged resource root alongside
  `skills`, `design-systems`, and `frames`, so the `od.craft.requires`
  integration isn't a silent no-op when the daemon resolves
  `${OD_RESOURCE_ROOT}/craft` in packaged builds.
- packages/contracts: add `craftRequires?: string[]` to `SkillSummary`
  (and therefore `SkillDetail`) so the field that `listSkills()`
  already returns and `/api/skills(/:id)` already serializes via
  `...rest` is part of the documented web/daemon contract instead of
  leaking through as an untyped property.
- apps/daemon/lint-artifact: expand the indigo token-strip pass to
  cover selector lists containing `:root` (e.g. `:root, [data-theme="light"]`)
  and any rule whose body is custom-property-only (e.g. a
  `[data-theme="dark"] { --accent: ... }` theme variant). Real
  component rules with a hardcoded indigo are still preserved so the
  P0 finding still fires; tests cover the new selector-list and
  theme-variant cases.

* fix(craft): address PR #225 follow-up review feedback

- lint-artifact: scope the indigo token-strip to <style> blocks so the
  rule-shaped regex no longer captures leading `<style>` text into the
  selector (which broke `:root` recognition for token blocks that mix
  `color-scheme`/etc. with `--accent`). Run the strip on the extracted
  CSS instead, with a regression covering `:root { color-scheme: light;
  --accent: #6366f1 }`.
- lint-artifact: tighten the custom-property-only exemption to global
  theme-scope selectors (`:root`, `html`, `body`, bare attribute
  selectors like `[data-theme="dark"]`). Component-local rules such as
  `.cta { --cta-bg: #6366f1 }` are no longer exempted, so an agent
  cannot launder default indigo through a local var. Regression test
  added.
- craft/anti-ai-slop.md: stop claiming every rule below is enforced by
  the linter; only several are. The unenforced rules (standard
  Hero→Features→Pricing→FAQ→CTA flow, decorative blob/wave SVG
  backgrounds, perfect symmetry) are now flagged inline as
  "(guidance, not auto-checked)" so the contract with the lint surface
  stays honest.

* fix(daemon): tighten lint-artifact iteration and :root token gating

- all-caps-no-tracking: iterate every <style> block. The previous
  check called `exec` once on a non-global regex, so an artifact
  whose offending uppercase rule sat in a second <style> block
  (e.g. a reset block followed by a components block) slipped
  past. Switch to `matchAll` and break across both loops once a
  violation is found. Regression test covers a second-block
  uppercase rule.
- ai-default-indigo: stop unconditionally exempting any selector
  list containing `:root`. The exemption now requires both
  conditions to hold: every selector in the list is global theme
  scope AND the body is token-shaped (CSS custom properties or
  the `color-scheme` keyword). So `:root { background: #6366f1 }`
  and `:root, .cta { --cta-bg: #6366f1 }` no longer launder a
  hardcoded indigo through the strip pass. Regression tests cover
  both bypass shapes.

* fix(daemon): scope theme-attr exemption and strip CSS comments in token blocks

Address PR #225 review feedback on `ai-default-indigo`:

- The bare-attribute branch of `selectorListIsGlobalThemeScope` accepted
  any `[attr=...]` selector, so a custom-property-only rule on a
  component/state attribute (e.g. `[data-variant="primary"]`,
  `[aria-current="page"]`) was treated as a global theme block and
  stripped before the indigo scan — exactly the component-local indigo
  laundering this lint is meant to catch. Restrict the exemption to a
  small allowlist of known theme switches: `data-theme`,
  `data-color-scheme`, `data-mode`.
- `stripTokenBlocksFromCss` split rule bodies on `;` and matched each
  fragment from the start, so a token block whose body contained a
  normal CSS comment such as `:root { /* brand accent */ --accent:
  #6366f1; }` produced a fragment beginning with the comment, failed
  `isTokenShapedDeclaration`, and the rule was left in scope of the
  indigo scan — a false P0 on a legitimate token definition. Strip CSS
  comments before splitting/classifying declarations.

Add regression coverage: arbitrary component/state attribute selectors
still trip `ai-default-indigo`; `data-color-scheme` theme variants stay
exempted; `:root` token blocks with leading, trailing, and
between-declaration CSS comments are recognized.

* fix(daemon): strip CSS comments and recognize tokens nested in at-rules

The all-caps-no-tracking scan ran against raw `<style>` content, so a
commented-out rule like `/* .eyebrow { text-transform: uppercase; } */`
matched `upperRe` and emitted a P1 for CSS the browser ignores. Strip
CSS comments from the style body before structural matching.

`stripTokenBlocksFromCss` only matched flat `selector { body }` rules,
so a media-query-wrapped token block like
`@media (prefers-color-scheme: dark) { :root { --accent: #6366f1 } }`
had its outer `@media` rule treated as the selector/body pair and the
inner `:root` token block was never stripped, producing a P0 false
positive on legitimate responsive theme CSS. Tighten the body
alternation to `[^{}]*` so the regex matches innermost rules and
recognizes the inner `:root` block directly while preserving the
outer at-rule wrapper.

* fix(daemon): align ai-default-indigo list with documented cardinal sins

The lint's AI_DEFAULT_INDIGO subset omitted #3730a3 and #a855f7, which
craft/anti-ai-slop.md lists as P0-blocked solid accents. An artifact
could hard-code one of those documented colors as a button fill and
slip past the indigo scan unless it happened to be inside a gradient.

Bring the lint set to the exact list documented in the craft doc, and
tighten the doc's wording from "etc." to an explicit enumeration that
points at AI_DEFAULT_INDIGO so the prompt contract and daemon behavior
stay in sync. Add regression tests pinning each newly-included hex.

* fix(daemon): tighten theme-scope selector and scan inline ALL CAPS

The theme-scope exemption used to accept any attribute on `:root`,
`html`, or `body` (e.g. `:root[data-variant="primary"]`), letting an
agent launder default indigo through a component/state attribute and
slip past the `ai-default-indigo` lint. The prefixed branches now
require the attribute name to be one of GLOBAL_THEME_ATTRIBUTES,
matching the bare-attribute branch.

The `all-caps-no-tracking` rule only iterated `<style>` blocks, so
inline declarations like `<span style="text-transform: uppercase">`
produced no finding even though craft/typography.md treats the
≥0.06em tracking floor as having no exceptions. Added a second scan
over `style="..."` attributes that runs the same letter-spacing
check and dedupes against the existing `<style>`-block finding so
the agent gets a single corrective signal per artifact.

* fix(daemon): align uppercase tracking px floor with the 0.06em rule

The previous absolute fallback (>=1.5px) was stricter than the craft
rule it enforces. `font-size: 12px; letter-spacing: 1px` is 0.083em
— above the 0.06em floor — but 1.5px would reject it and trigger an
unnecessary correction loop on compliant small-label CSS.

Extract `hasAdequateUppercaseTracking`: read `font-size` from the same
rule body and compare px tracking against `fontSize * 0.06`; fall back
to a conservative >=1px floor when font-size is inherited (covers the
default 16px body where 1px ≈ 0.0625em). Apply the helper to both the
<style>-block scan and the inline-style scan, and add 12–14px label
tests in both branches.

* fix(daemon): treat rem letter-spacing as absolute, not per-element em

`rem` was previously folded into the same branch as `em` and accepted
at the 0.06 threshold. But `rem` is relative to the root font-size
(16px default), not the element's own font-size, so on a 48px heading
`letter-spacing: 0.06rem` resolves to 0.96px — about 0.02em of the
element, well below the 0.06em rule the lint enforces.

Convert rem to absolute px through the 16px root assumption and reuse
the same px-vs-element-font-size resolution: same-rule `font-size: <n>px`
gives an exact `n * 0.06` floor; otherwise the conservative >=1px
fallback applies. Add regression tests for 48px headings with 0.06rem
tracking (must flag) plus the 16px-element and rem-floor matches that
must keep passing, in both <style>-block and inline-style branches.

* fix(daemon): resolve var() refs in uppercase tracking lint

`hasAdequateUppercaseTracking` only matched literal numeric values,
so a tokenized rule like `letter-spacing: var(--caps-tracking)` —
exactly the pattern the craft prompt steers artifacts toward — was
falsely reported as `all-caps-no-tracking`. Extract `--name: value`
declarations from global theme scopes (`:root`, `html`, theme-attribute
selectors) once per artifact, then expand simple `var(--name)` (and
`var(--name, fallback)`) references in the inspected rule body before
applying the existing 0.06em / px-floor / rem-conversion logic.
References without a matching token and no fallback stay in place,
preserving the conservative "missing tracking" finding.

* fix(daemon): resolve rem and var() font-size in uppercase tracking lint

Previously the px-vs-element-font-size resolution only matched
`font-size: <n>px`. Any rem-based or tokenized display size fell
through to the lenient `>= 1px` body-text fallback, so an artifact
emitting `.display { font-size: 3rem; text-transform: uppercase;
letter-spacing: 1px; }` (a ~48px heading with a 2.88px floor) slipped
past the lint that this helper exists to enforce.

Resolve `rem` font-size via the same root-font assumption already used
for tracking, and treat any explicitly declared but unresolvable unit
(`em`, `%`, `calc(...)`, an unresolved `var(...)`) conservatively —
refuse the lenient fallback so the rule must use either an `em`
letter-spacing or a verifiable px/rem font-size.

`var()` font-size declarations resolve through the existing
`resolveCssVars` pass before the size scan runs, so the same fix
catches the tokenized-display-size pattern (`--display-size: 3rem`).

* fix(daemon): parse declarations to ignore custom-prop names in uppercase tracking lint

The hasAdequateUppercaseTracking and resolveFontSizePx helpers used substring regexes against the rule body, so a token-name declaration such as `--letter-spacing: 0.08em` or `--display-font-size: 48px` could satisfy the `letter-spacing` / `font-size` checks even though it has no rendered effect — letting actual ALL-CAPS-without-tracking rules slip past the P1 lint.

Parse the declaration list, compare exact property names, and skip declarations whose property starts with `--`. Adds regression tests covering token-name letter-spacing (style-block + inline) and a token-name font-size masking the bail-out branch.

* fix(daemon): scope indigo token exemption to --accent only

Previously stripTokenBlocksFromCss removed every custom-property-only
global theme block before the ai-default-indigo scan, which let a
laundered indigo token like `:root { --primary: #6366f1 }` consumed
via `var(--primary)` slip past the lint. The craft contract is that
the only escape hatch is encoding indigo as the design system's
`--accent` token; any other token name is still the LLM-default
color hidden behind an arbitrary name. Narrow the strip pass so a
non-`--accent` token whose value carries an AI-default indigo hex
keeps the rule in scope, and add regression tests for `--primary` /
`--button-bg` global tokens feeding a CTA, including the at-rule
and theme-attribute variants.

* fix(daemon): model CSS cascade in tracking lint and detect blue→cyan trust gradients

Address PR #225 review feedback (3 comments):

- `letter-spacing` / `font-size` selection now picks the LAST matching
  declaration in the rule body, modeling CSS source-order cascade.
  `.eyebrow { letter-spacing: 0.08em; letter-spacing: 0.02em }` renders
  the noncompliant 0.02em the browser actually shows; the previous
  first-match behaviour silently passed it.
- `extractCssTokens` now records every distinct value seen for a token
  across global theme scopes, and `hasAdequateUppercaseTracking`
  enumerates each combination so a default-theme value below the floor
  cannot be rescued by a scoped override that happened to be parsed
  later (`:root { --caps-tracking: 0.02em }` +
  `[data-theme="dark"] { --caps-tracking: 0.08em }` now fires).
- New `trust-gradient` P0 rule pairs blue/sky tokens against cyan
  tokens in `linear-gradient(...)` bodies so `blue→cyan` two-stop
  trust gradients (documented as a cardinal sin in
  `craft/anti-ai-slop.md`) are actually enforced — both the hex form
  (`linear-gradient(90deg, #3b82f6, #06b6d4)`) and the keyword form
  (`linear-gradient(90deg, blue, cyan)`).

Adds 11 regression tests covering each path (cascade override in
<style> and inline form, font-size cascade shifting the floor, both
orderings of the conflicting-token cascade, the don't-over-fire case
when every theme value clears the floor, hex / keyword / sky variants
of the trust gradient, and the don't-double-fire case when
purple-gradient already caught a mixed gradient).

* fix(daemon): apply per-scope cascade in extractCssTokens

When the same CSS custom property is declared more than once inside a
single rule body (e.g. `:root { --caps-tracking: 0.02em;
--caps-tracking: 0.08em }`), CSS source-order cascade collapses to the
last value; the earlier declaration never reaches any element.
`extractCssTokens` was treating intra-scope duplicates as simultaneous
theme alternatives, so `hasAdequateUppercaseTracking` enumerated the
stale 0.02em and emitted a spurious all-caps-no-tracking finding.

Collapse duplicate token declarations within a rule body to the last
value before merging into the cross-scope distinct-value map. Cross-scope
overrides (separate `:root` and `[data-theme]` rules) remain preserved
as distinct values so the conservative theme-cascade check still fires
when ANY applicable theme renders below the floor.

* fix(daemon): scope tracking lint to innermost rules and per-theme tokens

Restrict the upperRe body alternation to [^{}]* so the regex matches
innermost CSS rules and skips at-rule wrappers — an outer @media or
@supports could otherwise capture as a single rule whose selector was
the at-rule and whose body began with the inner selector token, masking
the same-rule font-size and letting noncompliant tracking on large
headings slip through the lenient inherited-size fallback.

Replace the by-name-distinct-values token map with per-scope token
records and a buildResolvedThemes pass that materializes one effective
map per theme. Paired token declarations now stay paired during
evaluation, so theme variants like :root + [data-theme=dark] no longer
generate cross-theme cartesian pairings (e.g. default-size + dark-track)
that emit false positives on legitimate light/dark themes.

---------

Co-authored-by: looper <looper@open-claude.dev>
2026-05-02 11:00:33 +08:00
github-actions[bot]
bc16a2d5b8
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#241)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-02 10:47:05 +08:00
github-actions[bot]
8df7951cfc
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#228)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-01 23:12:15 +08:00
GeorgePSpark
534349aa4c
feat(daemon): add Kiro CLI agent adapter (#185)
* feat(daemon): add Kiro CLI agent adapter

* docs: add Kiro CLI to README and agent-adapters

* test(daemon): add kiro fetchModels fallback test
2026-05-01 12:25:26 +08:00
Tom Huang
d25a7aaf42
docs(readme): refresh stats, agents, skills and add metrics workflow (#173)
* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* chore: update next-env.d.ts route types path

Made-with: Cursor

* docs(readme): refresh stats, agents, skills and add metrics workflow

Make all three READMEs (en / zh-CN / ko) tell the truth about what the
project actually ships, and add lightweight community signals at the top
and bottom.

- Hero block: live for-the-badge GitHub stats (stars, forks, issues,
  PRs, contributors, commit activity, last commit) sit directly under
  the banner, with the smaller flat-square project-meta row (License,
  Agents, Design systems, Skills, Quickstart) below them and the
  language switcher below that.
- Counts updated to reality: 31 skills (was 19), 72 design systems
  (was 71), 10 coding-agent CLIs + OpenAI-compatible BYOK (was 7).
- "At a glance", architecture, and prompt-stack tables updated to
  cover /api/templates, /api/import/claude-design, /api/proxy/stream,
  /api/artifacts/lint, sidecar IPC, and per-namespace runtime data.
- New "Beyond chat — what else ships" section covering Claude Design
  ZIP import, BYOK proxy with SSRF block, saved templates, tab
  persistence, artifact lint, sidecar protocol + headless desktop, and
  Windows-friendly spawning.
- Skills tables rebuilt by mode (prototype, deck) and scenario; the
  "template" mode claim is removed.
- Supported coding agents table expanded to all 10 CLIs (Claude Code,
  Codex, Gemini, OpenCode, Cursor Agent, Qwen, Copilot, Hermes, Kimi,
  Pi) plus a BYOK row, with accurate stream formats and argv shapes.
- Roadmap re-flowed to mark shipped vs pending items.
- Contributors wall (contrib.rocks), Repository activity (lowlighter
  metrics SVG), and Star History added to all three READMEs, with
  cache_bust=2026-04-30 on the contrib.rocks and star-history image
  URLs to bypass GitHub camo caching.
- Korean README harmonised end-to-end with the English/Chinese ones.
- New .github/workflows/metrics.yml regenerates
  docs/assets/github-metrics.svg daily; ship a placeholder SVG so the
  image works before the first scheduled run.

Made-with: Cursor

* docs(readme): address PR #173 review feedback

- Replace invalid 0x14 control character in github-metrics.svg with an
  em-dash so the placeholder is well-formed XML and renders as an
  image (P1: was breaking SVG parse before the first metrics run).
- Clarify the placeholder SVG subtitle to spell out the token model:
  GITHUB_TOKEN gives core stats; METRICS_TOKEN unlocks richer plugins
  (traffic, follow-up). Reduces "do I need a secret?" confusion.
- Rewrite the metrics.yml inline auth comment to match: METRICS_TOKEN
  is optional and only enables richer plugins; GITHUB_TOKEN is enough
  for core metrics. Previous comment read as if METRICS_TOKEN was
  mandatory.
- Soften the BYOK fallback row in all three READMEs (EN / zh-CN / ko)
  with a catch-all phrase ("or any other OpenAI-compatible provider")
  so the listed vendors don't read as exhaustive.
2026-04-30 23:57:19 +08:00
PerishFire
c6d11018a0
Refresh desktop integration control plane (#123)
* feat(dev): add desktop tools-dev control plane

* refactor(sidecar): split Open Design contracts

Move Open Design-specific sidecar protocol definitions into @open-design/contracts so sidecar and platform can remain descriptor-driven primitives.

* refactor(daemon): organize package sources

Keep daemon app code, tests, and sidecar entrypoints in separate package directories so each layer can be built and verified independently.

* chore(repo): streamline maintenance entrypoints

Centralize agent guidance by directory and reduce root command chains while preserving the existing build scope.

* docs: translate agent guidance to English

* fix(sidecar): tolerate stale IPC sockets

Remove stale Unix socket files only after confirming no listener is active, so tools-dev can restart after unclean shutdowns.
2026-04-30 14:23:53 +08:00
Caprika
5c45c3b967
fix sse keepalive behind nginx (#111) 2026-04-30 11:31:18 +08:00
PerishFire
3f1e2cb60e
docs: refresh environment setup guidance (#104) 2026-04-30 10:00:33 +08:00
PerishFire
cfebff9653
Align app directories and isolate e2e tests (#102)
* chore: align app directories

* test: consolidate external suites under e2e
2026-04-30 09:47:03 +08:00
Tom Huang
4db0483721
chore: migrate frontend toolchain from Vite to Next.js 16 App Router (#66)
* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* chore: migrate frontend toolchain from Vite to Next.js 16 App Router

Replace the Vite SPA scaffold with Next.js 16 App Router while keeping
the existing daemon as the API/SSE/sqlite backend. The whole client
tree now mounts under a single optional catch-all route
(app/[[...slug]]) loaded with ssr:false; static export emits one shell
HTML the daemon serves as the SPA fallback for deep links. Dev uses
next.config rewrites to proxy /api, /artifacts, /frames to the daemon,
matching the previous Vite setup.

Made-with: Cursor

* fix: address Next migration review feedback

* fix: serve static export in preview script

---------

Co-authored-by: mrcfps <mrc@powerformer.com>
2026-04-29 21:33:21 +08:00
KNIGHTABDO
623444fe48
fix: deliver prompt via stdin for non-Claude agents to avoid spawn ENAMETOOLONG on Windows (#15)
The composed prompt (system instructions + skill body + cwd hint + file
listing + user message) can easily exceed Windows' CreateProcess limit of
~32 KB when passed as a CLI argument via -p <string>.  This causes
spawn ENAMETOOLONG whenever Gemini CLI (or Codex, OpenCode, Cursor
Agent, Qwen) is selected on Windows — even for short user messages,
because the skill / design-system system prompt is folded in.

Fix: add promptViaStdin: true to every plain-text agent definition.
The daemon's /api/chat handler checks this flag, opens stdin as a pipe,
writes the composed prompt to it and closes the stream.  Claude Code is
unaffected — it still uses the -p argv path and a separate stream-json
parser.

docs/agent-adapters.md: update §5.5 Gemini CLI to document the stdin
delivery strategy, and update the Windows open-question note to reflect
the fix.

Co-authored-by: KNIGHTABDO <abdessamad.aabida-etu@etu.univh2c.ma>
Co-authored-by: pftom <1043269994@qq.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: lefarcen <20859779+lefarcen@users.noreply.github.com>
2026-04-29 17:10:20 +08:00
lakatos
9858f496fd
feat(agents): add GitHub Copilot CLI as a code-agent option (#28)
* feat(agents): add GitHub Copilot CLI as a code-agent option

Wire `copilot -p "..." --allow-all-tools` into AGENT_DEFS so the daemon
can spawn it alongside the other CLIs. `--allow-all-tools` is required
in non-interactive mode (same tradeoff as Claude's `-p` and Codex's
`exec`). Add a matching GitHub-dark icon with the Copilot two-eye mark.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(copilot-stream): treat result.success as completed when exitCode missing

Strict `obj.exitCode === 0 ? 'completed' : 'error'` mis-flags turns
where Copilot emits a `result` event with `success: true` but no numeric
exitCode. Switch to `obj.success === true || obj.exitCode === 0`. The
asymmetry argument that applies to other defensive ideas in this file
(raw fallback, stringifyResult cap) doesn't apply here — Claude's
`result` event uses a string `stop_reason`, not exitCode, so this is a
Copilot-specific schema-variance fix rather than a one-sided hardening.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(agent-adapters): list Copilot CLI auth paths in §5.7

Adds a one-line note: detection assumes Copilot is already
authenticated, via either `copilot login` (subcommand, OAuth device
flow) or the interactive `/login` slash command inside `copilot` with
no args. Surfaces the assumption so anyone hitting an undetected /
unversioned Copilot install can trace it back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 16:54:47 +08:00
Tom Huang
1c942e6cb7
Feat/support star us (#5)
* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* Add contributing guidelines in English and Chinese

- Introduced CONTRIBUTING.md and CONTRIBUTING.zh-CN.md to provide clear instructions for contributors.
- Outlined contribution types, local setup instructions, and merging criteria for skills and design systems.
- Enhanced README files to reference the new contributing guidelines.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Enhance README and add star promotion assets

- Added a "Star us" section in both English and Chinese README files to encourage users to star the project on GitHub.
- Included a new image asset for the star promotion.
- Introduced a new HTML file for a dedicated star promotion page.
- Updated .gitignore to exclude new cursor-related files.
2026-04-28 21:00:33 +08:00
Tom Huang
bc2198103a
Feat/optimize naming (#2)
* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* Add contributing guidelines in English and Chinese

- Introduced CONTRIBUTING.md and CONTRIBUTING.zh-CN.md to provide clear instructions for contributors.
- Outlined contribution types, local setup instructions, and merging criteria for skills and design systems.
- Enhanced README files to reference the new contributing guidelines.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.
2026-04-28 16:28:19 +08:00
Tom Huang
6f6bf31dd2
Refactor project name from "Open Claude Design" to "Open Design" (#1)
* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* Add contributing guidelines in English and Chinese

- Introduced CONTRIBUTING.md and CONTRIBUTING.zh-CN.md to provide clear instructions for contributors.
- Outlined contribution types, local setup instructions, and merging criteria for skills and design systems.
- Enhanced README files to reference the new contributing guidelines.
2026-04-28 16:03:35 +08:00
pftom
a98096a042 Add initial project structure with essential files
- Created .gitignore to exclude build artifacts and dependencies.
- Added index.html as the main entry point for the application.
- Included LICENSE file with Apache 2.0 terms.
- Initialized package.json and package-lock.json for project dependencies.
- Added pnpm-lock.yaml for package management.
- Created QUICKSTART.md for setup instructions.
- Added README.md and README.zh-CN.md for project documentation in English and Chinese.
2026-04-28 12:25:59 +08:00