Skip to content

feat(context): scoped DESIGN.md routing for multi-design-system projects#174

Open
modius wants to merge 1 commit into
pbakaus:mainfrom
modius:feat/scoped-design-routing
Open

feat(context): scoped DESIGN.md routing for multi-design-system projects#174
modius wants to merge 1 commit into
pbakaus:mainfrom
modius:feat/scoped-design-routing

Conversation

@modius
Copy link
Copy Markdown

@modius modius commented May 29, 2026

What

Adds zero-config scoped DESIGN.md routing to the context loader, so a project with more than one design system can tell impeccable which one applies to the surface being worked on.

Today there's a single DESIGN.md next to PRODUCT.md. Projects that ship, say, an admin app and a public marketing site (different look, shared product story) have no way to load the right design system per task.

How

Drop a DESIGN.md inside a named subdirectory of the context dir, alongside the shared PRODUCT.md, then pass the URL or file path you're working on to context.mjs:

.agents/context/PRODUCT.md            # shared — one product story
.agents/context/admin/DESIGN.md       # scope "admin"
.agents/context/marketing/DESIGN.md   # scope "marketing"
node scripts/context.mjs "https://admin.example.com/users"   # -> admin/DESIGN.md
node scripts/context.mjs "src/marketing/landing.tsx"          # -> marketing/DESIGN.md
node scripts/context.mjs                                       # -> shared DESIGN.md

The loader infers the scope by matching the target's hostname labels / path segments against the scope directory names (host labels take precedence). No config, no hardcoded names — scopes are discovered from the filesystem.

Changes

  • skill/scripts/context.mjs: discoverScopes(), inferScope(), resolveDesignPath(); loadContext(cwd, target) gains a designScope field; CLI reads argv[2].
  • skill/SKILL.src.md: setup step 1 documents passing the target.
  • tests/context.test.mjs: 7 new tests (inferScope, resolveDesignPath, loadContext scoped + unscoped).

Compatibility

Fully backward compatible: with no target argument, or no scope subdirectories, the loader returns the shared DESIGN.md exactly as before. All existing context tests pass (42/42).

Notes

  • I changed source only (skill/). The provider copies under the harness dirs are build outputs — they need bun run build:skills to regenerate (I couldn't run the full build locally without the toolchain). Happy to adjust to whatever you prefer for artifact regeneration.
  • Motivation: we maintain a local fork of context.mjs for exactly this (a 3-bundle app), and the 3.1→3.5 loader rewrite wiped it — keen to land a generic version upstream so it's maintained for everyone. Glad to iterate on the design (e.g. an explicit scope→pattern map in PRODUCT.md frontmatter) if you'd prefer a different shape.

Note

Low Risk
Additive, filesystem-driven context selection with fallback to the existing shared DESIGN.md; no auth, data, or breaking API changes beyond an optional second argument.

Overview
Adds zero-config scoped DESIGN.md routing so projects with multiple design systems (e.g. admin vs marketing) load the right design doc for the surface being worked on, while PRODUCT.md stays project-wide.

Convention: put scoped files under the context directory as <scope>/DESIGN.md (e.g. .agents/context/admin/DESIGN.md) next to shared PRODUCT.md. Pass an optional URL or file path to context.mjs (CLI argv[2], loadContext(cwd, target)). The loader discovers scope folders, tokenizes the target (hostname labels first, then path segments), and picks the first matching scope name; otherwise it uses the shared root DESIGN.md. loadContext now exposes designScope when a scoped file wins.

Docs & tests: SKILL.src.md setup step 1 documents the optional target argument; new unit tests cover inferScope, resolveDesignPath, and scoped vs legacy single-DESIGN.md behavior.

Compatibility: omitting the target or having no scope subdirs behaves exactly as before.

Reviewed by Cursor Bugbot for commit 064ab4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Projects that ship more than one design system (e.g. an admin app + a public
marketing site) currently can't tell impeccable which DESIGN.md applies to the
surface being worked on — there's a single DESIGN.md next to PRODUCT.md.

Add zero-config scoped DESIGN.md routing: drop a DESIGN.md inside a named
subdirectory of the context dir (alongside the shared PRODUCT.md), and pass the
URL or file path being designed to context.mjs. The loader matches the target's
hostname labels / path segments against the scope directory names and loads the
matching scope's DESIGN.md, falling back to the shared DESIGN.md when nothing
matches. PRODUCT.md stays project-wide.

  .agents/context/PRODUCT.md            (shared)
  .agents/context/admin/DESIGN.md       -> https://admin.example.com/... | src/admin/x
  .agents/context/marketing/DESIGN.md   -> https://example.com/marketing/...

- skill/scripts/context.mjs: discoverScopes(), inferScope(), resolveDesignPath();
  loadContext(cwd, target) now returns `designScope`; CLI reads argv[2].
- skill/SKILL.src.md: document passing the target in setup step 1.
- tests/context.test.mjs: 7 new tests (inferScope + resolveDesignPath + loadContext).

Single-DESIGN.md projects are unaffected (no target / no scope dirs -> shared).
Provider copies under the harness dirs are build outputs — run
`bun run build:skills` to regenerate them.
@modius modius requested a review from pbakaus as a code owner May 29, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant