Files
msd-core/CLAUDE.md
Jakub Zych 6524974d93 feat: install and update msd from git release tags, not npm
MSD is not published to npm, so /msd-update and the SessionStart update
check could never find a release. Releases are now vX.Y.Z git tags plus a
stable branch:

- check-latest-version reads release tags via git ls-remote against the
  baked repository URL (latest = highest stable tag, next = incl. -rc)
- /msd-update reruns the bootstrap installer pinned to the checked tag and
  reads the changelog from that tag
- bootstrap.sh defaults to the stable branch and supports --local/--global
- package identity: changelog URL on stable, manual install via
  msd.golem15.com
- README quickstart and update how-to describe the one-line installer
- track the repo-root CLAUDE.md

Emitted-Drift-Ack-Growth: update.md — the update flow now explains the git-tag release lookup and pins the bootstrap installer to the checked tag, replacing the npm/npx wording
2026-10-09 10:54:04 +02:00

65 lines
7.7 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this is
`@golem15/msd-core` (MSD) is a meta-prompting / spec-driven development system for AI coding agents, a fork of open-gsd `gsd-core` that was renamed GSD → MSD. Most of the product is **prompt text** (slash commands, workflows, agents) plus a Node CLI (`msd-tools`) that the prompts shell out to for state, config, phase and git work. An installer copies or converts this content into each supported runtime: Claude Code, Codex, OpenCode, Cursor, ZCode and Antigravity. Other runtimes were removed on purpose, and `lint:retired-runtime-name` guards against re-adding their names.
Before you name or refactor modules, read `CONTEXT.md`, the canonical domain vocabulary. Its predicates are cited by ID, so don't paraphrase them. Also check `docs/adr/`. The architecture deep-dive is `docs/ARCHITECTURE.md`.
## Commands
Node ≥ 24 (`.nvmrc`). Install with `npm ci`, not `npm install`.
```bash
npm run build:lib # tsc: src/*.cts -> msd-core/bin/lib/*.cjs (required before running anything)
npm run build # full build: lib + generated manifests/indexes/skills/hooks
npm test # all suites (pretest runs build:lib + lint:skill-deps)
npm run test:unit # also: test:integration, test:install, test:security, test:slow, test:qa
npm run test:affected # only tests affected by your changes
node --test tests/foo.test.cjs # single file (run build:lib first)
node scripts/run-tests.cjs --files "tests/a.test.cjs tests/b.test.cjs"
npm run lint # eslint, --max-warnings 0
npm run lint:ci # the full CI lint battery (drift/parity/seam linters)
npm run lint:generated-sync # verifies every generated artifact is up to date (--check mode)
npm run regen:derived # regenerate all derived files after changing their sources
npm run check:alias-drift # after touching src/command-aliases.cts or src/*-command-router.cts
npm run changeset -- --type Fixed --pr <N> --body "..." # changelog fragment
```
The test suite comes from the filename suffix: `foo.security.test.cjs` → `security`, and a plain `foo.test.cjs` → `unit`. See `docs/TESTING-SUITES.md`.
## Architecture
- **`commands/msd/*.md`**: slash-command definitions, the source of truth. `skills/msd-*/SKILL.md` is **generated** from them (`gen:plugin-skills`), so never edit `skills/` by hand.
- **`msd-core/workflows/*.md`**: the workflow bodies that commands dispatch to. Large workflows use progressive disclosure: `workflows/<name>/modes/*.md`, with `discuss-phase/` as the canonical example. Workflows are thin orchestrators that spawn agents with fresh context, and state lives in files under the user project's `.planning/` (STATE.md, ROADMAP.md, phases/).
- **`agents/*.md`**: subagent definitions, the canonical source. `.claude/agents/`, `.cursor/agents/` and `.github/agents/msd-*` are gitignored install outputs, so never edit them.
- **`msd-core/references/`, `templates/`, `contexts/`**: shared reference text and templates loaded by workflows.
- **`src/*.cts` → `msd-core/bin/lib/*.cjs`** (ADR-457, "build-at-publish"): the core library is TypeScript compiled to CommonJS, and the compiled `.cjs` files are **gitignored**. Edit `src/`, never the generated `.cjs`. A handful of `bin/lib/*.cjs` files are still tracked: some are hand-written and some are generated-and-committed (`capability-registry.cjs`, `package-identity.cjs`, `loop-host-contract.cjs`, `vendor/`). Run `git ls-files msd-core/bin/lib` to tell which is which.
- **`msd-core/bin/msd-tools.cjs`**: the CLI the prompts call (`state …`, `phase …`, `resolve-model`, `init …`, `commit`, and more). Subcommands go through `command-routing-hub` and the per-family `src/*-command-router.cts` + `src/command-aliases.cts`, and the alias drift check keeps these in sync.
- **`capabilities/<id>/capability.json`**: optional feature/runtime modules (tdd, security, code-review, mempalace, per-runtime ones such as `claude`, `codex`, …). They declare config keys, contributions to workflow steps, hooks and agents. The aggregated registry `msd-core/bin/lib/capability-registry.cjs` is generated (`gen:capability-registry`).
- **`hooks/`**: runtime hooks (prompt/read guards, context monitor, commit validation, …), built into `hooks/dist` by `build:hooks`.
- **`bin/install.js`**: the multi-runtime installer that converts and copies commands, agents, skills and hooks into each runtime's config dir.
- **`scripts/`**: build, generate and lint tooling. Many `gen-*.cjs` scripts support `--write` and `--check`, and CI runs them all in `--check`.
Generated artifacts are everywhere (skills, registries, `docs/INVENTORY-MANIFEST.json`, `docs/CONTEXT-INDEX.json`, `FEATURES.md`, exit-code docs, …). If you change a source that feeds one, regenerate it (`npm run regen:derived` or the specific `gen:*` script), or `lint:generated-sync` will fail.
## Coding rules (from CONTRIBUTING.md / .clinerules)
- CommonJS runtime (`require`). Core lib/CLI use **Node built-ins only**, with no runtime npm deps in core (vendored deps sit in `bin/lib/vendor/`).
- To spawn a process, use `execFileSync` with array args, never `execSync` with string interpolation. Validate user-provided paths with `validatePath()` (security module).
- Tests use **`node:test` + `node:assert/strict` only**. Use `tests/helpers.cjs` (`createTempProject`, `createTempGitProject`, `cleanup`, `runMsdTools`) and spawn subprocesses through `tests/helpers/process-seam.cjs`. Clean up with `beforeEach`/`afterEach` or `t.after()`, never `try/finally` in a test body.
- **No source-grep tests and no raw-text matching on outputs** (stdout, rendered files, reason strings). Assert on structured values: `--json` modes, frozen reason enums, builder IRs. This is enforced by the `local/no-source-grep` ESLint rule. Exemptions need an `allow-test-rule: <reason>` annotation (for example `source-text-is-the-product` for `.md` prompt content).
- Changes to shipped prompt content (workflows, agents, commands) are checked by `tests/emitted-attribution.test.cjs`, and size budgets exist (`workflow-size-budget`, `agent-size-budget`). If emitted bytes move for a reason the diff doesn't show, add a commit trailer: `Emitted-Drift-Ack-Hash:` / `Emitted-Drift-Ack-Growth: <path> — <why>`.
- Commits follow conventional format `<type>(<scope>): <subject>`, with the subject ≤72 chars, lowercase, imperative and without a trailing period (enforced by `hooks/msd-validate-commit.sh`). Put the test-fixture correction in its own `test:` commit.
- A PR that touches `bin/`, `msd-core/`, `src/`, `agents/`, `commands/` or `hooks/` needs a `.changeset/*.md` fragment. Never edit `CHANGELOG.md` directly.
- Branching: feature branches open PRs against `next` on git.golem15.com (Gitea; use `tea`, not `gh`). There is no `main`. `.githooks/` contains pre-commit (alias drift) and pre-push gates.
## Distribution and releases
MSD is **not on npm**; the inherited `.github/workflows/release.yml` npm pipeline does not apply to this fork.
- Users install with `curl -fsSL https://msd.golem15.com | bash` (`scripts/bootstrap.sh`). It clones into `~/.local/share/msd-core`, builds, and runs `bin/install.js`. A Cloudflare Worker (`msd-installer`) serves the script from the `stable` branch.
- A release is a `vX.Y.Z` tag on `next`, after which the `stable` branch is moved to that tag. `/msd-update` and the SessionStart update check find the latest version from those tags (`msd-core/bin/check-latest-version.cjs`, `git ls-remote`), then rerun the bootstrap installer pinned with `--ref vX.Y.Z`.
- The repository URL and manual-install command come from the generated Package Identity seam (`scripts/generate-package-identity.cjs` → `msd-core/bin/lib/package-identity.cjs`), derived from `package.json`.