refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Build Your First Capability
|
||||
|
||||
In this tutorial you will build a tiny, fully declarative GSD capability from scratch and watch it act inside your project's loop. By the end you will have a working capability installed, visible in `gsd capability list`, and firing at the `plan:pre` extension point.
|
||||
In this tutorial you will build a tiny, fully declarative MSD capability from scratch and watch it act inside your project's loop. By the end you will have a working capability installed, visible in `msd capability list`, and firing at the `plan:pre` extension point.
|
||||
|
||||
No code is required. Declarative capabilities — those that own only prompt fragments and hook declarations, with no executable hook scripts or MCP servers — require no trust prompt at install time.
|
||||
|
||||
@@ -12,12 +12,12 @@ We will build a capability called `hello-note`. It registers a `contribution` at
|
||||
|
||||
You need:
|
||||
|
||||
- GSD 1.6.0 or later (`gsd --version`).
|
||||
- MSD 1.6.0 or later (`msd --version`).
|
||||
- A throwaway project directory. Create one now:
|
||||
|
||||
```bash
|
||||
mkdir ~/hello-demo && cd ~/hello-demo
|
||||
gsd init
|
||||
msd init
|
||||
```
|
||||
|
||||
You will work inside `~/hello-demo` for the rest of this tutorial.
|
||||
@@ -36,7 +36,7 @@ Your project tree now looks like this:
|
||||
|
||||
```text
|
||||
~/hello-demo/
|
||||
.gsd/
|
||||
.msd/
|
||||
capabilities/
|
||||
hello-note/
|
||||
fragments/ ← prompt fragments live here
|
||||
@@ -74,7 +74,7 @@ Create the manifest at `capabilities/hello-note/capability.json`:
|
||||
"description": "Injects a greeting note at plan:pre and produces HELLO.md.",
|
||||
"tier": "standard",
|
||||
"requires": [],
|
||||
"engines": { "gsd": ">=1.6.0" },
|
||||
"engines": { "msd": ">=1.6.0" },
|
||||
"runtimeCompat": { "supported": ["*"], "unsupported": [] },
|
||||
"skills": [],
|
||||
"agents": [],
|
||||
@@ -97,14 +97,14 @@ Create the manifest at `capabilities/hello-note/capability.json`:
|
||||
A few things to notice:
|
||||
|
||||
- `version` is required in 1.6.0. Use semver.
|
||||
- `engines.gsd` is a hard gate: GSD will refuse to install or load this capability on any version older than 1.6.0.
|
||||
- `engines.msd` is a hard gate: MSD will refuse to install or load this capability on any version older than 1.6.0.
|
||||
- `role: "feature"` means this capability adds optional behaviour to the loop — it is not a runtime descriptor. A `feature` capability must declare `runtimeCompat`; `{ "supported": ["*"] }` means "every runtime".
|
||||
- This is a **contribution**, not a **step**. A contribution injects a prompt fragment into a named agent role (`into`) and needs no dispatch target. A step, by contrast, *must* carry a `ref` with exactly one of `skill`, `agent`, or `command` — so a fragment-only injection is always a contribution. That is why `steps` is left empty here.
|
||||
- `into: "planner"` names the agent role that receives the fragment. `planner` is one of the roles published by the `plan:pre` extension point (alongside `researcher` and `checker`); the value must be a role that point publishes or the manifest fails validation.
|
||||
- `produces` tells the registry that this contribution writes `HELLO.md`, which lets the registry order hooks and detect unsatisfied dependencies in more complex setups.
|
||||
- `onError: "skip"` means the loop continues even if this contribution fails. For a first capability that is the safe choice.
|
||||
|
||||
The fragment is referenced by `path`. At load time GSD reads the file and inlines its text into the registry, so the contribution carries the materialised content wherever the loop renders it. This keeps the capability completely declarative — no executable code is involved.
|
||||
The fragment is referenced by `path`. At load time MSD reads the file and inlines its text into the registry, so the contribution carries the materialised content wherever the loop renders it. This keeps the capability completely declarative — no executable code is involved.
|
||||
|
||||
---
|
||||
|
||||
@@ -113,7 +113,7 @@ The fragment is referenced by `path`. At load time GSD reads the file and inline
|
||||
Install from the local path with `--scope project` so it is scoped only to this demo project:
|
||||
|
||||
```bash
|
||||
gsd capability install ./capabilities/hello-note --scope project
|
||||
msd capability install ./capabilities/hello-note --scope project
|
||||
```
|
||||
|
||||
The command emits a JSON result:
|
||||
@@ -130,17 +130,17 @@ The command emits a JSON result:
|
||||
}
|
||||
```
|
||||
|
||||
GSD copies the bundle into `.gsd/capabilities/hello-note/` and records it in the project ledger at `.gsd-capabilities.json`. Because `hello-note` declares no executable surfaces (no hook scripts, no MCP servers, no command modules) it installs without a consent prompt — the `disclosure` line confirms there was no runnable code to review. That is intentional: declarative capabilities are safe to install without reviewing executable code.
|
||||
MSD copies the bundle into `.msd/capabilities/hello-note/` and records it in the project ledger at `.msd-capabilities.json`. Because `hello-note` declares no executable surfaces (no hook scripts, no MCP servers, no command modules) it installs without a consent prompt — the `disclosure` line confirms there was no runnable code to review. That is intentional: declarative capabilities are safe to install without reviewing executable code.
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Confirm the installation
|
||||
|
||||
```bash
|
||||
gsd capability list
|
||||
msd capability list
|
||||
```
|
||||
|
||||
`list` emits a JSON array of every capability GSD can see — the first-party ones that ship with GSD, plus any you have installed. Your `hello-note` entry appears at the end:
|
||||
`list` emits a JSON array of every capability MSD can see — the first-party ones that ship with MSD, plus any you have installed. Your `hello-note` entry appears at the end:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -156,12 +156,12 @@ gsd capability list
|
||||
}
|
||||
```
|
||||
|
||||
`status` is `active` — the capability is installed, compatible with your GSD version, and will fire. (The other status values are `incompatible`, when the host GSD version is outside the capability's `engines.gsd` range, and `inactive`, when a project-scoped capability has not been consented on this machine.)
|
||||
`status` is `active` — the capability is installed, compatible with your MSD version, and will fire. (The other status values are `incompatible`, when the host MSD version is outside the capability's `engines.msd` range, and `inactive`, when a project-scoped capability has not been consented on this machine.)
|
||||
|
||||
You can also query the active hook set for the `plan:pre` point:
|
||||
|
||||
```bash
|
||||
gsd loop render-hooks plan:pre --raw
|
||||
msd loop render-hooks plan:pre --raw
|
||||
```
|
||||
|
||||
The envelope is `{ point, activeHooks, rendered }`. Your contribution appears in `activeHooks` (alongside any first-party hooks active at this point):
|
||||
@@ -180,26 +180,26 @@ The envelope is `{ point, activeHooks, rendered }`. Your contribution appears in
|
||||
}
|
||||
```
|
||||
|
||||
Notice that `fragment.inline` now holds the materialised text from `fragments/plan-pre.md` — GSD inlined it at load time, while keeping the original `path` for reference. The top-level `rendered` field is an unfiltered diagnostic digest across kinds and roles; planner hosts do not paste it. They read `activeHooks` in registry order and inject only active `kind: "contribution"` entries whose `into` is `planner`, using each entry's `fragment.inline` and resolved `configValues`.
|
||||
Notice that `fragment.inline` now holds the materialised text from `fragments/plan-pre.md` — MSD inlined it at load time, while keeping the original `path` for reference. The top-level `rendered` field is an unfiltered diagnostic digest across kinds and roles; planner hosts do not paste it. They read `activeHooks` in registry order and inject only active `kind: "contribution"` entries whose `into` is `planner`, using each entry's `fragment.inline` and resolved `configValues`.
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — See the contribution reach the planner
|
||||
|
||||
Planning is driven by a slash command, not a `gsd` subcommand. In your AI assistant, start a planning session for a phase with:
|
||||
Planning is driven by a slash command, not a `msd` subcommand. In your AI assistant, start a planning session for a phase with:
|
||||
|
||||
```text
|
||||
/gsd-plan-phase
|
||||
/msd-plan-phase
|
||||
```
|
||||
|
||||
When the planner runs — whether from `/gsd-plan-phase` or `/gsd-quick` — the active planner-targeted `plan:pre` contributions are injected into its prompt, so it receives `hello-note` and, following the fragment's instruction, records a one-line note in `HELLO.md`. In `/gsd-quick --full` and `/gsd-quick --validate`, the same rendered hook snapshot is reused if the plan checker sends the plan back to the planner for revision.
|
||||
When the planner runs — whether from `/msd-plan-phase` or `/msd-quick` — the active planner-targeted `plan:pre` contributions are injected into its prompt, so it receives `hello-note` and, following the fragment's instruction, records a one-line note in `HELLO.md`. In `/msd-quick --full` and `/msd-quick --validate`, the same rendered hook snapshot is reused if the plan checker sends the plan back to the planner for revision.
|
||||
|
||||
The first-party security capability is enabled by default and also contributes at `plan:pre` into the planner role. Its guidance requires generated plans to include `<threat_model>` blocks and carries the configured ASVS level and blocking threshold. Disable `workflow.security_enforcement` if that behavior is not wanted. Contributions targeting any non-planner role are not inserted into Quick's planner prompts.
|
||||
|
||||
You do not need to run a full planning session to confirm the wiring, though. The `loop render-hooks` command shows exactly what the loop would hand the planner — the same output you saw in Step 5:
|
||||
|
||||
```bash
|
||||
gsd loop render-hooks plan:pre --raw
|
||||
msd loop render-hooks plan:pre --raw
|
||||
```
|
||||
|
||||
Find `hello-note` in `activeHooks` and inspect its `fragment.inline`, `into`, and optional `configValues`. Those are the fields the planner host filters and injects. The unfiltered top-level `rendered` digest is useful for inspection, but it is not the planner prompt. This confirms the capability is wired into the loop without dispatching an agent.
|
||||
@@ -211,7 +211,7 @@ Find `hello-note` in `activeHooks` and inspect its `fragment.inline`, `into`, an
|
||||
When you want to stop the contribution from firing, remove the capability from the project:
|
||||
|
||||
```bash
|
||||
gsd capability remove hello-note --scope project
|
||||
msd capability remove hello-note --scope project
|
||||
```
|
||||
|
||||
This emits a JSON result describing what was removed:
|
||||
@@ -222,14 +222,14 @@ This emits a JSON result describing what was removed:
|
||||
"id": "hello-note",
|
||||
"scope": "project",
|
||||
"removedFiles": [
|
||||
".gsd/capabilities/hello-note"
|
||||
".msd/capabilities/hello-note"
|
||||
],
|
||||
"strippedEdits": 0,
|
||||
"dataPreserved": true
|
||||
}
|
||||
```
|
||||
|
||||
Run `gsd capability list` again and `hello-note` is gone from the array. Run `gsd loop render-hooks plan:pre --raw` and you will see it is absent from `activeHooks`: a removed capability contributes nothing to the loop.
|
||||
Run `msd capability list` again and `hello-note` is gone from the array. Run `msd loop render-hooks plan:pre --raw` and you will see it is absent from `activeHooks`: a removed capability contributes nothing to the loop.
|
||||
|
||||
Removing the installed bundle does not touch the source folder you authored under `capabilities/hello-note/` — that is your copy. To reinstall, just run the Step 4 command again.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user