design-playbook 0.24.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/codex/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- generated-by design-playbook v0.24.0 -->
1
+ <!-- generated-by design-playbook v0.24.1 -->
2
2
  # design-playbook for Codex
3
3
 
4
4
  ## Install (path of record)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "design-playbook",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "description": "Design I/O for coding agents: controllable UI generation via declarations (spec/domain/craft/design/components/template) and contracts (skill/evaluator). Use for product UI—console, dashboard, agent-ops, CJK-first apps.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -115,6 +115,16 @@ _TIER2: tuple[AgentRow, ...] = (
115
115
  skills=False,
116
116
  rules_target=".github/copilot-instructions.md",
117
117
  ),
118
+ AgentRow(
119
+ agent="zed",
120
+ tier=2,
121
+ rules=True,
122
+ commands=False,
123
+ mcp_project=True,
124
+ hooks=False,
125
+ skills=False,
126
+ rules_target=".rules + .zed/settings.json",
127
+ ),
118
128
  )
119
129
 
120
130
  # Tier 3 — rules floor (generated AGENTS.md + inline MCP guide).
package/scripts/doctor.py CHANGED
@@ -59,6 +59,7 @@ _ORPHAN_SCAN_DIRS: dict[str, tuple[str, ...]] = {
59
59
  "gemini-cli": (".gemini/commands",),
60
60
  "windsurf": (".windsurf/rules", ".windsurf/workflows"),
61
61
  "github-copilot": (".github/instructions",),
62
+ "zed": (".zed",),
62
63
  }
63
64
  # Whole-file candidates carrying the generated-by marker outside namespaced
64
65
  # dirs (marker-block targets are always re-rendered in place, so they are
@@ -68,6 +69,7 @@ _WHOLE_FILE_CANDIDATES = (
68
69
  "GEMINI.md",
69
70
  ".github/copilot-instructions.md",
70
71
  "design-playbook-mcp-setup.md",
72
+ ".rules",
71
73
  )
72
74
 
73
75
  _LIMITATIONS = (
@@ -649,6 +649,60 @@ def _agents_md_floor_files(version: str, out_dir: Path) -> list[tuple[str, str]]
649
649
  return [_marker_entry(out_dir, "AGENTS.md", version, "".join(block_parts))]
650
650
 
651
651
 
652
+ # ---------------------------------------------------------------------------
653
+ # Zed renderer (Tier 2)
654
+ # ---------------------------------------------------------------------------
655
+
656
+ # Zed reads project-root rules via a first-match priority list with `.rules`
657
+ # on top, then `.cursorrules`, `.windsurfrules`, `.clinerules`,
658
+ # `.github/copilot-instructions.md`, `CLAUDE.md`, `AGENTS.md`, … (zed.dev
659
+ # agent rules docs, fetched 2026-09-19). Creating `.rules` when a
660
+ # lower-priority competitor exists would silently shadow the user's own
661
+ # rules, so the renderer refuses to introduce one into that state.
662
+ _ZED_RULES_COMPETITORS = (
663
+ ".cursorrules",
664
+ ".windsurfrules",
665
+ ".clinerules",
666
+ "CLAUDE.md",
667
+ ".github/copilot-instructions.md",
668
+ )
669
+
670
+
671
+ def _zed_files(version: str, out_dir: Path) -> list[tuple[str, str]]:
672
+ files: list[tuple[str, str]] = []
673
+ skills = _read_skills()
674
+
675
+ # `.rules` — marker-block (may pre-exist). Skip creating a *new* `.rules`
676
+ # while a documented lower-priority competitor is present; an existing
677
+ # `.rules` (ours or the user's) takes refresh/append semantics instead,
678
+ # since Zed already reads that exact file.
679
+ rules_existing = _existing_text(out_dir, ".rules")
680
+ if rules_existing is not None or not any(
681
+ (out_dir / c).exists() for c in _ZED_RULES_COMPETITORS
682
+ ):
683
+ block_parts = _digest_head(skills)
684
+ files.append(_marker_entry(out_dir, ".rules", version, "".join(block_parts)))
685
+
686
+ # .zed/settings.json — merge-safe context_servers (project-level MCP).
687
+ # Official docs (fetched 2026-09-19) document the stdio entry as
688
+ # {"command": "…", "args": […], "env": {…}}; community examples also show
689
+ # an object form ({"command": {"path": …, "args": […]}}) — the string
690
+ # form is pinned here per the official page, and the merge keeps any
691
+ # user-managed entries verbatim.
692
+ mcp_servers = _mcp_servers_abs()
693
+ zed_servers: dict = {}
694
+ for name, srv in mcp_servers.items():
695
+ entry: dict = {"command": srv["command"], "args": srv["args"]}
696
+ if "env" in srv and any(v for v in srv["env"].values()):
697
+ entry["env"] = srv["env"]
698
+ zed_servers[name] = entry
699
+ files.append(
700
+ _merge_json_entry(out_dir, ".zed/settings.json", {"context_servers": zed_servers})
701
+ )
702
+
703
+ return files
704
+
705
+
652
706
  # ---------------------------------------------------------------------------
653
707
  # Renderer dispatch
654
708
  # ---------------------------------------------------------------------------
@@ -664,6 +718,7 @@ _SPECIALIZED_RENDERERS: dict[str, Renderer] = {
664
718
  "opencode": _opencode_files,
665
719
  "windsurf": _windsurf_files,
666
720
  "github-copilot": _github_copilot_files,
721
+ "zed": _zed_files,
667
722
  }
668
723
 
669
724