opensdd 0.1.0 → 0.1.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/README.md +79 -0
- package/opensdd/cli.md +31 -14
- package/opensdd/{sdd-generate.md → skills/sdd-generate.md} +6 -2
- package/opensdd/{sdd-manager.md → skills/sdd-manager.md} +4 -0
- package/opensdd/spec-format.md +2 -2
- package/opensdd/spec.md +88 -0
- package/package.json +2 -2
- package/src/commands/publish.js +2 -3
- package/src/lib/skills.js +33 -14
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<b>OpenSDD</b>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<b>--Open Spec-Driven Development--</b>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
AI agents are great at writing code, but they need to know *what* to build. OpenSDD is a protocol and CLI for writing, sharing, and consuming **behavioral specs** — language-agnostic contracts that tell agents what software should do, without dictating how.
|
|
12
|
+
|
|
13
|
+
Think of it like a package manager, but for specifications instead of code.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g opensdd
|
|
17
|
+
|
|
18
|
+
# Initialize OpenSDD in your project
|
|
19
|
+
opensdd init
|
|
20
|
+
|
|
21
|
+
# Install a spec from the registry
|
|
22
|
+
opensdd install slugify
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then tell your coding agent: "implement the slugify spec" — it reads the spec, writes the code, and generates tests.
|
|
26
|
+
|
|
27
|
+
## How It Works
|
|
28
|
+
|
|
29
|
+
1. **Write a spec** — Define what your software does in `opensdd/spec.md` using a simple markdown format with behavioral contracts, edge cases, and invariants.
|
|
30
|
+
2. **Share it** — Publish your spec to a registry with `opensdd publish`. Others can install it with `opensdd install`.
|
|
31
|
+
3. **Implement it** — Your AI agent reads the spec and generates a bespoke implementation in whatever language and framework your project uses.
|
|
32
|
+
|
|
33
|
+
Specs are the source of truth. Code flows from the spec, not the other way around.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Language-agnostic specs** — One spec, any implementation. The same spec produces TypeScript, Python, Rust, or whatever your project needs.
|
|
38
|
+
- **Registry & versioning** — Publish, install, and update specs with semver. Updates produce changesets so your agent knows exactly what changed.
|
|
39
|
+
- **Multi-agent support** — Skills auto-install for Claude Code, Codex CLI, Cursor, GitHub Copilot, Gemini CLI, and Amp.
|
|
40
|
+
- **Deviations** — Need to diverge from a spec? Document it formally instead of silently drifting.
|
|
41
|
+
- **Spec dependencies** — Specs can reference other specs for shared types and contracts.
|
|
42
|
+
|
|
43
|
+
## Quick Example
|
|
44
|
+
|
|
45
|
+
A spec (`spec.md`) looks like this:
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
# slugify
|
|
49
|
+
|
|
50
|
+
> Converts a string into a URL-friendly slug.
|
|
51
|
+
|
|
52
|
+
## Behavioral Contract
|
|
53
|
+
|
|
54
|
+
### Core Behavior
|
|
55
|
+
|
|
56
|
+
Accepts a string and returns a lowercase, hyphen-separated slug.
|
|
57
|
+
|
|
58
|
+
- `slugify("Hello World")` MUST return `"hello-world"`
|
|
59
|
+
- `slugify("Déjà Vu")` MUST return `"deja-vu"`
|
|
60
|
+
|
|
61
|
+
## Invariants
|
|
62
|
+
|
|
63
|
+
- For any string `x`: `slugify(slugify(x)) === slugify(x)` (idempotent)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Documentation
|
|
67
|
+
|
|
68
|
+
- [Spec Format](opensdd/spec-format.md) — How to write specs
|
|
69
|
+
- [CLI Reference](opensdd/cli.md) — All CLI commands
|
|
70
|
+
- [SDD Manager Skill](opensdd/sdd-manager.md) — How agents implement and verify specs
|
|
71
|
+
- [SDD Generate Skill](opensdd/sdd-generate.md) — How agents generate specs from existing code
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and workflows.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT — see [LICENSE](LICENSE) for details.
|
package/opensdd/cli.md
CHANGED
|
@@ -81,38 +81,38 @@ Initialized OpenSDD:
|
|
|
81
81
|
|
|
82
82
|
### Skill Installation Mapping
|
|
83
83
|
|
|
84
|
-
`opensdd init` installs both skills (sdd-manager and sdd-generate) into the native configuration format of each supported coding agent. The canonical skill content is authored as markdown source files (`sdd-manager.md`, `sdd-generate.md
|
|
84
|
+
`opensdd init` installs both skills (sdd-manager and sdd-generate) into the native configuration format of each supported coding agent. The canonical skill content is authored as markdown source files in `opensdd/skills/` (`skills/sdd-manager.md`, `skills/sdd-generate.md`) and `opensdd/` (`spec-format.md`). Source skill files use Agent Skills frontmatter (`name`, `description`) which the CLI parses and transforms per-agent format during installation.
|
|
85
85
|
|
|
86
86
|
All installed skill files are **spec-owned** — they are overwritten on every `opensdd init` and MUST NOT be edited by the user.
|
|
87
87
|
|
|
88
88
|
#### Claude Code (Agent Skills standard)
|
|
89
89
|
|
|
90
|
-
Each skill is a directory with a `SKILL.md` and a `references/` subdirectory. Claude Code auto-discovers skills in `.claude/skills/`.
|
|
90
|
+
Each skill is a directory with a `SKILL.md` and a `references/` subdirectory. Claude Code auto-discovers skills in `.claude/skills/`. The `SKILL.md` files include Agent Skills frontmatter with `name` and `description` fields, copied as-is from the source skill files.
|
|
91
91
|
|
|
92
92
|
```
|
|
93
93
|
.claude/skills/
|
|
94
94
|
sdd-manager/
|
|
95
|
-
SKILL.md ← sdd-manager.md
|
|
95
|
+
SKILL.md ← skills/sdd-manager.md
|
|
96
96
|
references/
|
|
97
97
|
spec-format.md ← spec-format.md
|
|
98
98
|
sdd-generate/
|
|
99
|
-
SKILL.md ← sdd-generate.md
|
|
99
|
+
SKILL.md ← skills/sdd-generate.md
|
|
100
100
|
references/
|
|
101
101
|
spec-format.md ← spec-format.md
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
#### OpenAI Codex CLI (Agent Skills standard)
|
|
105
105
|
|
|
106
|
-
Codex CLI follows the same Agent Skills standard but discovers skills in `.agents/skills/`.
|
|
106
|
+
Codex CLI follows the same Agent Skills standard but discovers skills in `.agents/skills/`. The `SKILL.md` files include Agent Skills frontmatter with `name` and `description` fields, copied as-is from the source skill files.
|
|
107
107
|
|
|
108
108
|
```
|
|
109
109
|
.agents/skills/
|
|
110
110
|
sdd-manager/
|
|
111
|
-
SKILL.md ← sdd-manager.md
|
|
111
|
+
SKILL.md ← skills/sdd-manager.md
|
|
112
112
|
references/
|
|
113
113
|
spec-format.md ← spec-format.md
|
|
114
114
|
sdd-generate/
|
|
115
|
-
SKILL.md ← sdd-generate.md
|
|
115
|
+
SKILL.md ← skills/sdd-generate.md
|
|
116
116
|
references/
|
|
117
117
|
spec-format.md ← spec-format.md
|
|
118
118
|
```
|
|
@@ -123,9 +123,9 @@ Cursor discovers rules as `.md` or `.mdc` files in `.cursor/rules/`. Each skill
|
|
|
123
123
|
|
|
124
124
|
```
|
|
125
125
|
.cursor/rules/
|
|
126
|
-
sdd-manager.md ← sdd-manager.md with frontmatter
|
|
127
|
-
sdd-generate.md ← sdd-generate.md with frontmatter
|
|
128
|
-
opensdd-spec-format.md ← spec-format.md with frontmatter
|
|
126
|
+
sdd-manager.md ← skills/sdd-manager.md with Cursor frontmatter
|
|
127
|
+
sdd-generate.md ← skills/sdd-generate.md with Cursor frontmatter
|
|
128
|
+
opensdd-spec-format.md ← spec-format.md with Cursor frontmatter
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
Frontmatter for `sdd-manager.md`:
|
|
@@ -158,15 +158,32 @@ Copilot discovers instructions as `.instructions.md` files in `.github/instructi
|
|
|
158
158
|
|
|
159
159
|
```
|
|
160
160
|
.github/instructions/
|
|
161
|
-
sdd-manager.instructions.md ← sdd-manager.md with frontmatter
|
|
162
|
-
sdd-generate.instructions.md ← sdd-generate.md with frontmatter
|
|
163
|
-
opensdd-spec-format.instructions.md ← spec-format.md with frontmatter
|
|
161
|
+
sdd-manager.instructions.md ← skills/sdd-manager.md with Copilot frontmatter
|
|
162
|
+
sdd-generate.instructions.md ← skills/sdd-generate.md with Copilot frontmatter
|
|
163
|
+
opensdd-spec-format.instructions.md ← spec-format.md with Copilot frontmatter
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
Frontmatter for
|
|
166
|
+
Frontmatter for `sdd-manager.instructions.md`:
|
|
167
167
|
```yaml
|
|
168
168
|
---
|
|
169
169
|
applyTo: "**"
|
|
170
|
+
description: "Implement, update, and verify installed OpenSDD dependency specs. Use when the user asks to implement a spec, process a spec update, check conformance, or create a deviation."
|
|
171
|
+
---
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Frontmatter for `sdd-generate.instructions.md`:
|
|
175
|
+
```yaml
|
|
176
|
+
---
|
|
177
|
+
applyTo: "**"
|
|
178
|
+
description: "Generate an OpenSDD behavioral spec from existing code. Use when the user asks to generate, create, or extract a spec from a repository or codebase."
|
|
179
|
+
---
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Frontmatter for `opensdd-spec-format.instructions.md`:
|
|
183
|
+
```yaml
|
|
184
|
+
---
|
|
185
|
+
applyTo: "**"
|
|
186
|
+
description: "OpenSDD spec format reference. Defines the structure and rules for behavioral specifications. Referenced by sdd-manager and sdd-generate skills."
|
|
170
187
|
---
|
|
171
188
|
```
|
|
172
189
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdd-generate
|
|
3
|
+
description: "Generate an OpenSDD behavioral spec from existing code. Use when the user asks to generate, create, or extract a spec from a repository or codebase."
|
|
4
|
+
---
|
|
1
5
|
# SDD Generate
|
|
2
6
|
|
|
3
7
|
> Guides an AI agent through analyzing a repository and generating a behavioral spec in the OpenSDD format.
|
|
@@ -12,7 +16,7 @@ Before starting, you need:
|
|
|
12
16
|
|
|
13
17
|
1. A **target repository** — a GitHub URL or local path provided by the user.
|
|
14
18
|
2. A **scope** — which capability, module, or function to spec. If the user provides a whole-repo URL without scoping, ask them to narrow it before proceeding. A spec for "the entire lodash library" is not useful. A spec for "lodash's string slugification" is.
|
|
15
|
-
3. The **spec-format reference** — read [spec-format.md](spec-format.md) to understand the required output structure.
|
|
19
|
+
3. The **spec-format reference** — read [spec-format.md](../spec-format.md) to understand the required output structure.
|
|
16
20
|
4. A **working directory** — confirm with the user where the generated spec should be written. If the project has `opensdd.json`, use the directory specified by `specs_dir` (default: `opensdd/`). If the project is not yet initialized, ask the user where to output the spec — a common default is `opensdd/` in the current project root. The agent does not need `opensdd.json` to exist before generating a spec.
|
|
17
21
|
|
|
18
22
|
## Output
|
|
@@ -153,7 +157,7 @@ Always update `_notes/gaps.md` at the end of each pass with what still needs to
|
|
|
153
157
|
- The full `spec.md` draft
|
|
154
158
|
- `_notes/inventory.md` — verify every public API item is covered
|
|
155
159
|
- `_notes/gaps.md` — verify no critical gaps remain
|
|
156
|
-
- [spec-format.md](spec-format.md) — verify structural compliance
|
|
160
|
+
- [spec-format.md](../spec-format.md) — verify structural compliance
|
|
157
161
|
|
|
158
162
|
**Write:**
|
|
159
163
|
- `spec.md` — add or complete:
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdd-manager
|
|
3
|
+
description: "Implement, update, and verify installed OpenSDD dependency specs. Use when the user asks to implement a spec, process a spec update, check conformance, or create a deviation."
|
|
4
|
+
---
|
|
1
5
|
# SDD Manager
|
|
2
6
|
|
|
3
7
|
> Teaches agents how to implement, update, and verify installed dependency specs in an OpenSDD-compliant project.
|
package/opensdd/spec-format.md
CHANGED
|
@@ -440,11 +440,11 @@ This is a transient artifact. `opensdd update apply` reads this file, applies th
|
|
|
440
440
|
|
|
441
441
|
### SDD-Manager Skill
|
|
442
442
|
|
|
443
|
-
The sdd-manager skill teaches agents how to implement, update, and verify installed dependency specs. It is installed once per project via `opensdd init` alongside the sdd-generate skill, into each supported agent's configuration directory. See [sdd-manager.md](sdd-manager.md) for the full skill workflow, including implementation defaults, the project conventions check, and the verification protocol.
|
|
443
|
+
The sdd-manager skill teaches agents how to implement, update, and verify installed dependency specs. It is installed once per project via `opensdd init` alongside the sdd-generate skill, into each supported agent's configuration directory. See [sdd-manager.md](skills/sdd-manager.md) for the full skill workflow, including implementation defaults, the project conventions check, and the verification protocol.
|
|
444
444
|
|
|
445
445
|
### SDD-Generate Skill
|
|
446
446
|
|
|
447
|
-
The sdd-generate skill teaches agents how to generate a spec from existing code. See [sdd-generate.md](sdd-generate.md) for the full skill workflow.
|
|
447
|
+
The sdd-generate skill teaches agents how to generate a spec from existing code. See [sdd-generate.md](skills/sdd-generate.md) for the full skill workflow.
|
|
448
448
|
|
|
449
449
|
### Versioning
|
|
450
450
|
|
package/opensdd/spec.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# OpenSDD
|
|
2
|
+
|
|
3
|
+
> A protocol, CLI, and agent skills for spec-driven development — write behavioral specs, share them via a registry, and let AI agents generate bespoke implementations.
|
|
4
|
+
|
|
5
|
+
## Version
|
|
6
|
+
|
|
7
|
+
0.1.0
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
OpenSDD (Open Spec-Driven Development) treats behavioral specifications as the source of truth for software. A spec defines **what** software does and **what constraints** it must satisfy, while leaving **how** it is implemented to the consuming agent. Specs are language-agnostic by default — the same spec can produce implementations in any language or framework.
|
|
12
|
+
|
|
13
|
+
The system has four components:
|
|
14
|
+
|
|
15
|
+
- **[Spec Format](spec-format.md)** — The standard format for behavioral specifications. Defines spec structure, the `opensdd.json` manifest, the registry layout, and the protocol rules that all other components depend on.
|
|
16
|
+
- **[CLI](cli.md)** — A Node.js command-line tool (`opensdd`) that initializes projects, installs and updates specs from a registry, publishes authored specs, and installs agent skills.
|
|
17
|
+
- **[SDD Manager](sdd-manager.md)** — A skill installed into coding agents that teaches them how to implement, update, verify, and deviate from installed dependency specs.
|
|
18
|
+
- **[SDD Generate](sdd-generate.md)** — A skill installed into coding agents that teaches them how to generate a behavioral spec from an existing codebase.
|
|
19
|
+
|
|
20
|
+
## Behavioral Contract
|
|
21
|
+
|
|
22
|
+
### Spec Authoring
|
|
23
|
+
|
|
24
|
+
A project authors a spec by placing a `spec.md` in its `opensdd/` directory (configurable via `opensdd.json`). The spec MUST contain an H1 header with a blockquote summary and a `## Behavioral Contract` section. The author MAY include supplementary files in the same directory; all supplementary files MUST be reachable by following links from `spec.md`.
|
|
25
|
+
|
|
26
|
+
Development is spec-first: behavior changes start in the spec, then code is updated to match.
|
|
27
|
+
|
|
28
|
+
See [Spec Format](spec-format.md) for the full format definition, required and recommended sections, and inline example conventions.
|
|
29
|
+
|
|
30
|
+
### Spec Distribution
|
|
31
|
+
|
|
32
|
+
Specs are distributed via a registry — a versioned store of published specs. The default registry is the `registry/` directory in the OpenSDD GitHub repository.
|
|
33
|
+
|
|
34
|
+
- `opensdd publish` packages the authored spec and opens a PR against the registry.
|
|
35
|
+
- `opensdd install <name>` fetches a spec from the registry and places it in `.opensdd.deps/<name>/`.
|
|
36
|
+
- `opensdd update [name]` pulls newer versions and stages changesets for the agent to process.
|
|
37
|
+
|
|
38
|
+
Installed spec files are spec-owned and MUST NOT be edited by the consumer. The `.opensdd.deps/` directory MUST be committed to the repo.
|
|
39
|
+
|
|
40
|
+
See [CLI](cli.md) for the full command reference, registry source resolution, and update staging behavior.
|
|
41
|
+
|
|
42
|
+
### Spec Implementation
|
|
43
|
+
|
|
44
|
+
When a consumer installs a spec, their AI agent implements it using the sdd-manager skill. The agent reads the spec, checks project conventions (language, framework, test runner), generates an implementation, and runs a verification protocol that includes both a test suite and a spec compliance audit.
|
|
45
|
+
|
|
46
|
+
The agent MUST NOT implement or modify code based on an OpenSDD spec outside of the workflows defined by the sdd-manager skill.
|
|
47
|
+
|
|
48
|
+
See [SDD Manager](sdd-manager.md) for the implementation, update, conformance check, and deviation workflows.
|
|
49
|
+
|
|
50
|
+
### Spec Generation
|
|
51
|
+
|
|
52
|
+
The sdd-generate skill teaches agents to generate a behavioral spec from an existing codebase via a multi-pass, artifact-driven strategy. The generated spec follows the spec format and is written to `opensdd/spec.md`.
|
|
53
|
+
|
|
54
|
+
See [SDD Generate](sdd-generate.md) for the multi-pass strategy, prerequisites, and output format.
|
|
55
|
+
|
|
56
|
+
### Agent Skill Installation
|
|
57
|
+
|
|
58
|
+
`opensdd init` installs both skills (sdd-manager and sdd-generate) into the native configuration format of each supported coding agent:
|
|
59
|
+
|
|
60
|
+
- **Claude Code** — `.claude/skills/<name>/SKILL.md` with `references/`
|
|
61
|
+
- **OpenAI Codex CLI** — `.agents/skills/<name>/SKILL.md` with `references/`
|
|
62
|
+
- **Cursor** — `.cursor/rules/<name>.md` with YAML frontmatter
|
|
63
|
+
- **GitHub Copilot** — `.github/instructions/<name>.instructions.md` with YAML frontmatter
|
|
64
|
+
- **Gemini CLI** — `GEMINI.md` with `@` imports to canonical skill files
|
|
65
|
+
- **Amp** — `AGENTS.md` with `@` references to canonical skill files
|
|
66
|
+
|
|
67
|
+
All skill files are spec-owned and overwritten on every `opensdd init`. The Claude Code installation serves as the canonical source that Gemini CLI and Amp reference.
|
|
68
|
+
|
|
69
|
+
See [CLI — Skill Installation Mapping](cli.md#skill-installation-mapping) for the full mapping and installation rules.
|
|
70
|
+
|
|
71
|
+
## NOT Specified (Implementation Freedom)
|
|
72
|
+
|
|
73
|
+
- The internal prompting strategy of the sdd-manager and sdd-generate skills
|
|
74
|
+
- How agents discover skills (defined by each agent's native mechanism)
|
|
75
|
+
- The specific testing framework or test runner (determined by the consumer's project)
|
|
76
|
+
- How agents generate implementations (model choice, temperature, etc.)
|
|
77
|
+
- The transport mechanism for fetching specs from a registry (defined by the CLI)
|
|
78
|
+
- File encoding (assumed UTF-8)
|
|
79
|
+
|
|
80
|
+
## Invariants
|
|
81
|
+
|
|
82
|
+
- A spec MUST always contain an H1 header with blockquote summary and a `## Behavioral Contract` section
|
|
83
|
+
- Spec-owned files in `.opensdd.deps/` MUST NOT be modified by the consumer
|
|
84
|
+
- `deviations.md` MUST NOT be created, modified, or deleted by the CLI or any automated tooling
|
|
85
|
+
- Consumer-managed `opensdd.json` fields MUST survive all update operations
|
|
86
|
+
- The `.opensdd.deps/` directory MUST be committed to the repo
|
|
87
|
+
- Publishing MUST NOT allow overwriting an existing version in the registry
|
|
88
|
+
- All supplementary files in a spec directory MUST be reachable by following links from `spec.md`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opensdd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The official OpenSDD (Open Spec-Driven Development) CLI, spec, and spec registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"diff": "^7.0.0"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
package/src/commands/publish.js
CHANGED
|
@@ -145,14 +145,13 @@ export async function publishCommand(options) {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
const { owner, repo } = parseGitHubUrl(registrySource);
|
|
148
|
-
const repoUrl = `https://github.com/${owner}/${repo}.git`;
|
|
149
148
|
|
|
150
149
|
// Step 10: Clone, create branch, add files, push, create PR
|
|
151
150
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opensdd-publish-'));
|
|
152
151
|
|
|
153
152
|
try {
|
|
154
|
-
// Clone
|
|
155
|
-
execSync(`
|
|
153
|
+
// Clone using gh to respect the user's configured git protocol (ssh vs https)
|
|
154
|
+
execSync(`gh repo clone "${owner}/${repo}" "${tmpDir}" -- --depth 1`, { stdio: 'pipe' });
|
|
156
155
|
|
|
157
156
|
// Create branch
|
|
158
157
|
execSync(`git checkout -b "${branchName}"`, { cwd: tmpDir, stdio: 'pipe' });
|
package/src/lib/skills.js
CHANGED
|
@@ -8,11 +8,30 @@ const __dirname = path.dirname(__filename);
|
|
|
8
8
|
const OPENSDD_SECTION_START = '<!-- OpenSDD Skills (managed by opensdd init \u2014 do not edit this section) -->';
|
|
9
9
|
const OPENSDD_SECTION_END = '<!-- /OpenSDD Skills -->';
|
|
10
10
|
|
|
11
|
+
function parseFrontmatter(content) {
|
|
12
|
+
if (!content.startsWith('---\n')) return { frontmatter: {}, body: content };
|
|
13
|
+
const endIdx = content.indexOf('\n---\n', 4);
|
|
14
|
+
if (endIdx === -1) return { frontmatter: {}, body: content };
|
|
15
|
+
|
|
16
|
+
const yamlStr = content.substring(4, endIdx);
|
|
17
|
+
const body = content.substring(endIdx + 5);
|
|
18
|
+
|
|
19
|
+
const frontmatter = {};
|
|
20
|
+
for (const line of yamlStr.split('\n')) {
|
|
21
|
+
const match = line.match(/^(\w+):\s*"([^"]*)"\s*$/) || line.match(/^(\w+):\s*(.*?)\s*$/);
|
|
22
|
+
if (match) {
|
|
23
|
+
frontmatter[match[1]] = match[2];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { frontmatter, body };
|
|
27
|
+
}
|
|
28
|
+
|
|
11
29
|
function getSkillContent() {
|
|
12
30
|
const opensddDir = path.resolve(__dirname, '../../opensdd');
|
|
31
|
+
const skillsDir = path.join(opensddDir, 'skills');
|
|
13
32
|
return {
|
|
14
|
-
sddManager: fs.readFileSync(path.join(
|
|
15
|
-
sddGenerate: fs.readFileSync(path.join(
|
|
33
|
+
sddManager: fs.readFileSync(path.join(skillsDir, 'sdd-manager.md'), 'utf-8'),
|
|
34
|
+
sddGenerate: fs.readFileSync(path.join(skillsDir, 'sdd-generate.md'), 'utf-8'),
|
|
16
35
|
specFormat: fs.readFileSync(path.join(opensddDir, 'spec-format.md'), 'utf-8'),
|
|
17
36
|
};
|
|
18
37
|
}
|
|
@@ -121,19 +140,22 @@ export function installSkills(projectRoot) {
|
|
|
121
140
|
const cursorBase = path.join(projectRoot, '.cursor', 'rules');
|
|
122
141
|
ensureDir(cursorBase);
|
|
123
142
|
|
|
143
|
+
const { frontmatter: managerFm, body: managerBody } = parseFrontmatter(skills.sddManager);
|
|
144
|
+
const { frontmatter: generateFm, body: generateBody } = parseFrontmatter(skills.sddGenerate);
|
|
145
|
+
|
|
124
146
|
const sddManagerCursor = `---
|
|
125
|
-
description: "
|
|
147
|
+
description: "${managerFm.description}"
|
|
126
148
|
alwaysApply: false
|
|
127
149
|
---
|
|
128
150
|
|
|
129
|
-
${
|
|
151
|
+
${managerBody}`;
|
|
130
152
|
|
|
131
153
|
const sddGenerateCursor = `---
|
|
132
|
-
description: "
|
|
154
|
+
description: "${generateFm.description}"
|
|
133
155
|
alwaysApply: false
|
|
134
156
|
---
|
|
135
157
|
|
|
136
|
-
${
|
|
158
|
+
${generateBody}`;
|
|
137
159
|
|
|
138
160
|
const specFormatCursor = `---
|
|
139
161
|
description: "OpenSDD spec format reference. Defines the structure and rules for behavioral specifications. Referenced by sdd-manager and sdd-generate skills."
|
|
@@ -154,23 +176,20 @@ ${skills.specFormat}`;
|
|
|
154
176
|
const copilotBase = path.join(projectRoot, '.github', 'instructions');
|
|
155
177
|
ensureDir(copilotBase);
|
|
156
178
|
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
`;
|
|
179
|
+
const { frontmatter: managerFmCp, body: managerBodyCp } = parseFrontmatter(skills.sddManager);
|
|
180
|
+
const { frontmatter: generateFmCp, body: generateBodyCp } = parseFrontmatter(skills.sddGenerate);
|
|
162
181
|
|
|
163
182
|
writeFileSync(
|
|
164
183
|
path.join(copilotBase, 'sdd-manager.instructions.md'),
|
|
165
|
-
|
|
184
|
+
`---\napplyTo: "**"\ndescription: "${managerFmCp.description}"\n---\n\n${managerBodyCp}`
|
|
166
185
|
);
|
|
167
186
|
writeFileSync(
|
|
168
187
|
path.join(copilotBase, 'sdd-generate.instructions.md'),
|
|
169
|
-
|
|
188
|
+
`---\napplyTo: "**"\ndescription: "${generateFmCp.description}"\n---\n\n${generateBodyCp}`
|
|
170
189
|
);
|
|
171
190
|
writeFileSync(
|
|
172
191
|
path.join(copilotBase, 'opensdd-spec-format.instructions.md'),
|
|
173
|
-
|
|
192
|
+
`---\napplyTo: "**"\ndescription: "OpenSDD spec format reference. Defines the structure and rules for behavioral specifications. Referenced by sdd-manager and sdd-generate skills."\n---\n\n${skills.specFormat}`
|
|
174
193
|
);
|
|
175
194
|
} catch (err) {
|
|
176
195
|
warnings.push(`Could not install GitHub Copilot skills: ${err.message}`);
|