Skip to content

v0.4.0

Choose a tag to compare

@hpieris-dm hpieris-dm released this 10 Sep 00:49
· 5 commits to main since this release

[0.4.0] — 2026-09-09

Added

  • (Phase 1 of GH-27, org-wide shared sources) A new .dmx/shared-sources.yaml file lets a repo declare one or more org-wide shared sources (git::<url>[//<subdir>]?ref=<tag|branch|sha>, Terraform's module-source convention) that resolve as a new tier — after the app repo, before the bundled fallback — for loops (_resolve_loop), skills (_resolve_skill), and validators (resolve_validator_path). Declared-list order is the precedence order among multiple shared sources. This phase wires the resolver tier only; it reads directly from .dmx/vendor/{name}/ if already populated, but nothing yet clones/fetches a source into that location — that's the /dmx/sync skill, landing in a follow-up phase. A repo with no .dmx/shared-sources.yaml behaves exactly as it did before this change — fully backward compatible, zero risk to existing resolution behavior.
  • (Phase 2 of GH-27, org-wide shared sources) New /dmx/sync skill: clones each source declared in .dmx/shared-sources.yaml at its pinned ref, copies its tree (not a nested git repo/submodule — a plain copy tracked by the app repo's own git history) into .dmx/vendor/{name}/, and writes a per-source .lock.json recording the resolved commit SHA, before committing and pushing the result. Blocked from running directly on the configured branch_base, matching every other write path in dmx that requires a reviewed PR. Clone/checkout/shape failures are reported per source with one of three distinguishable causes (auth/URL, missing ref, wrong-shaped source) rather than a generic git error. Backed by a new deterministic MCP tool, sync_shared_sources (dmx.sync_runner), for the same reason validators and loop orchestration stay out of the agent's hands — no LLM judgment is needed for cloning and copying files.
  • (Phase 3 of GH-27, org-wide shared sources) /dmx/sync now detects and warns about same-name collisions across the app repo's own .dmx/loops//.dmx/skills//validators/ and every declared shared source, checked per category and in shared_sources declared-order (the same order the resolvers use to pick a winner) — e.g. two shared sources both defining spec.yaml, or a local skill accidentally shadowing an org-wide one. A collision is a warning, not a failure: sync and commit still proceed, surfaced in /dmx/sync's output (and therefore the PR diff) so an unintended shadow doesn't go unnoticed. (detect_collisions in dmx.sync_runner)
  • (Phase 4 of GH-27, org-wide shared sources) _resolve_skill now recognizes the {name}/SKILL.md folder shape (the agentskills.io / Claude Code ecosystem convention — SKILL.md plus optional scripts//references//assets/) as a fallback within a shared source, after dmx's own flat {name}.md — so an org can point shared_sources directly at an already-standards-shaped skills repo with zero dmx-specific restructuring. When a folder-shaped skill resolves, get_skill_definition prefixes the returned instructions with the skill's on-disk root path (e.g. .dmx/vendor/{source}/skills/{name}/) so the agent can resolve scripts//references//assets/ paths mentioned in the body directly, and surfaces any dependencies: declared in frontmatter as an explicit note rather than silently dropping it. Vendored content is never copied into .dmx/skills/ or emitted into an IDE's native skills directory — see GH-27 for why both were rejected.
  • (Phase 5 of GH-27, org-wide shared sources) Docs: new README "Shared sources" section covering the resolution tier, .dmx/shared-sources.yaml config, /dmx/sync, dual-format skill support, and the enterprise/private-repo auth story; Roadmap checklist entry marked done. This closes out GH-27 — all five phases (resolver plumbing, /dmx/sync vendoring, collision detection, dual-format skills, docs) are now implemented.

Fixed

  • (GH-27 hardening, found in post-implementation review) detect_collisions now correctly compares skills by their logical name instead of a raw filename glob, so it catches two cases the phase-3 implementation missed once phase 4 added dual-format skill support: two sources both declaring the same folder-shaped {name}/SKILL.md skill (a directory never matched the skills/*.md glob at all), and a flat {name}.md in one source colliding with a folder-shaped or dmx--prefixed version of the same logical skill in another — both of which do collide at actual _resolve_skill time and were previously shadowed with no warning.
  • (GH-27 hardening) .dmx/shared-sources.yaml entries now validate name (must be a plain slug — letters, digits, _, -, not leading with -) and subdir (must be relative, no .. segment) at parse time, instead of trusting them as literal path segments. Previously, a typo'd or malicious name/subdir could make sync_source's shutil.rmtree/vendoring, or a resolver's source_root, operate on a path outside .dmx/vendor/ entirely — most notably a subdir starting with /, which Path.__truediv__ silently resolves as absolute, discarding the intended base path completely.
  • (GH-27 hardening) /dmx/sync now fails fast, per-source, if any entry under a shared source's skills/ directory is neither a flat {name}.md file nor a {name}/SKILL.md folder (e.g. a stray non-Markdown file, or a folder with no SKILL.md inside) — previously such an entry vendored silently and then simply never resolved, with no diagnostic pointing at which entry was wrong. Hidden entries (.gitkeep, .gitignore, .DS_Store, and similar repo-hygiene artifacts extremely common at the top of any real directory) are skipped rather than flagged — found immediately in a follow-up review of this same check, since it would otherwise fail an entirely well-formed source over something unrelated to whether its skills resolve. Vendoring also now strips a .git directory at any depth in the copied tree (shutil.copytree(..., ignore=shutil.ignore_patterns(".git"))), not just the top-level one — defensive, since git itself already refuses to track a path literally named .git at any depth, so this can't currently be hit through normal git usage, but it costs nothing to guard directly at the copy step rather than relying on that as the only line of defense.