opsx-gherkin 1.0.0
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/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +53 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/SECURITY.md +14 -0
- package/dist/cli.mjs +50 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/converter-CFtzcfoM.mjs +977 -0
- package/dist/converter-CFtzcfoM.mjs.map +1 -0
- package/dist/mdg-to-opsx.mjs +8 -0
- package/dist/mdg-to-opsx.mjs.map +1 -0
- package/dist/official-99qBUZpr.mjs +91 -0
- package/dist/official-99qBUZpr.mjs.map +1 -0
- package/dist/opsx-to-feature.mjs +8 -0
- package/dist/opsx-to-feature.mjs.map +1 -0
- package/dist/opsx-to-mdg.mjs +8 -0
- package/dist/opsx-to-mdg.mjs.map +1 -0
- package/dist/validate-spec.mjs +56 -0
- package/dist/validate-spec.mjs.map +1 -0
- package/package.json +87 -0
- package/skills/opsx-gherkin/SKILL.md +144 -0
- package/skills/opsx-gherkin/references/OPENSPEC_MDG_PROFILE.feature.md +372 -0
- package/skills/opsx-gherkin/references/examples/account.feature +85 -0
- package/skills/opsx-gherkin/references/examples/account.feature.md +96 -0
- package/skills/opsx-gherkin/references/examples/account.openspec.md +109 -0
- package/skills/opsx-gherkin/references/examples/authentication-delta.feature +41 -0
- package/skills/opsx-gherkin/references/examples/authentication-delta.feature.md +45 -0
- package/skills/opsx-gherkin/references/examples/authentication-delta.openspec.md +52 -0
- package/skills/opsx-gherkin/references/examples/minimal.feature +17 -0
- package/skills/opsx-gherkin/references/examples/minimal.feature.md +19 -0
- package/skills/opsx-gherkin/references/examples/minimal.openspec.md +24 -0
- package/skills/opsx-gherkin/references/profile-access.feature.md +34 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Migrate the conversion CLI into a typed, tested, reproducible package.
|
|
6
|
+
- Include an independent syntax compatibility skill owning the canonical profile.
|
|
7
|
+
- Check normalized model preservation before emitting converted documents.
|
|
8
|
+
- Preserve delta operation-group order and reject unmapped removal/rename content.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Use Node.js 22.18+ and the pnpm version declared in `package.json`.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
pnpm install --frozen-lockfile
|
|
7
|
+
pnpm verify
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
The only canonical compatibility contract is
|
|
11
|
+
[OPENSPEC_MDG_PROFILE.feature.md](skills/opsx-gherkin/references/OPENSPEC_MDG_PROFILE.feature.md).
|
|
12
|
+
Read it before changing conversion behavior or syntax guidance. Update the
|
|
13
|
+
relevant Rule/Scenario before introducing a compatibility correction; a new
|
|
14
|
+
mapping needs an explicit contract change. Keep examples executable and update
|
|
15
|
+
their generated counterparts when behavior changes.
|
|
16
|
+
|
|
17
|
+
Parsing and rendering operate on the typed document model. Keep filesystem I/O
|
|
18
|
+
and command diagnostics at the CLI boundary. Official validators remain behind
|
|
19
|
+
their shared adapter and pinned during compatibility-preserving maintenance.
|
|
20
|
+
|
|
21
|
+
Tests must examine actual interpreted structures and values, including expanded
|
|
22
|
+
Examples. Parser acceptance and stable text alone cannot establish preservation.
|
|
23
|
+
Package tests must use the installed tarball and the bundled skill resources.
|
|
24
|
+
`pnpm test` rebuilds commands before process tests; `pnpm test:coverage` also
|
|
25
|
+
checks coverage thresholds. `pnpm test:package` builds and verifies npm/npx in
|
|
26
|
+
an isolated temporary consumer directory.
|
|
27
|
+
|
|
28
|
+
Use Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`, etc.). Mark public
|
|
29
|
+
interface incompatibilities with `!` or a `BREAKING CHANGE:` footer. Check a
|
|
30
|
+
message with `pnpm exec commitlint --edit <message-file>`.
|
|
31
|
+
|
|
32
|
+
## Release setup
|
|
33
|
+
|
|
34
|
+
The repository includes a manually dispatched release workflow. Before its first run:
|
|
35
|
+
|
|
36
|
+
1. Configure the real Git remote and add its actual repository, homepage, and
|
|
37
|
+
issue URLs to package metadata. No destination is assumed by this repository.
|
|
38
|
+
2. Confirm npm ownership/availability for `opsx-gherkin` and register the GitHub
|
|
39
|
+
workflow as a trusted publisher for that package, permitting `npm publish`.
|
|
40
|
+
Use workflow filename `release.yml` and environment name `npm` in that configuration.
|
|
41
|
+
3. Configure the GitHub `npm` environment and repository permissions as desired.
|
|
42
|
+
The workflow requests an OIDC token for npm provenance and uses the repository's
|
|
43
|
+
`GITHUB_TOKEN` for release notes. No npm token is stored in the project.
|
|
44
|
+
4. Establish the release history. The package retains the prototype's `1.0.0`
|
|
45
|
+
baseline; semantic-release determines the published version from tags and
|
|
46
|
+
Conventional Commits. A first release requires a release-triggering commit.
|
|
47
|
+
5. Run `pnpm verify`, then dispatch the Release workflow on `main`.
|
|
48
|
+
|
|
49
|
+
The release job verifies before invoking semantic-release. Versioning, changelog,
|
|
50
|
+
and release-note configuration live in `release.config.mjs`. Local verification
|
|
51
|
+
and package smoke checks do not upload artifacts or require publishing credentials.
|
|
52
|
+
|
|
53
|
+
Trusted publisher requirements: [npm documentation](https://docs.npmjs.com/trusted-publishers/).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 opsx-gherkin contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# opsx-gherkin
|
|
2
|
+
|
|
3
|
+
Deterministic conversion between OpenSpec and Gherkin, with a self-contained
|
|
4
|
+
skill explaining compatible syntax. Requires Node.js 22.18+.
|
|
5
|
+
|
|
6
|
+
## Convert a specification
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npx opsx-gherkin mdg-to-opsx input.feature.md -o spec.md
|
|
10
|
+
npx opsx-gherkin opsx-to-mdg spec.md -o output.feature.md
|
|
11
|
+
npx opsx-gherkin opsx-to-feature spec.md -o output.feature
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The supported directions are Markdown with Gherkin to OpenSpec, OpenSpec to
|
|
15
|
+
Markdown with Gherkin, and OpenSpec to plain Gherkin. Plain `.feature` input is
|
|
16
|
+
available for direct validation only.
|
|
17
|
+
|
|
18
|
+
Each converter accepts one input path, inline `--text`, or stdin. With no `-o`,
|
|
19
|
+
the result goes to stdout. Existing destinations require `--force`; successful
|
|
20
|
+
file writes are atomic. Invalid conversions leave the destination unchanged.
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npx opsx-gherkin mdg-to-opsx < input.feature.md
|
|
24
|
+
npx opsx-gherkin opsx-to-feature --text "$(cat spec.md)"
|
|
25
|
+
npx opsx-gherkin opsx-to-mdg --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`--name` supplies a name when OpenSpec input lacks a title or usable source-path
|
|
29
|
+
context. `--project-root` supplies main-spec context for delta validation.
|
|
30
|
+
`--output` is an alias for `-o`. Standalone `mdg-to-opsx`, `opsx-to-mdg`, and
|
|
31
|
+
`opsx-to-feature` executables accept the same options after installation.
|
|
32
|
+
|
|
33
|
+
## Compatibility
|
|
34
|
+
|
|
35
|
+
Read the complete contract before authoring compatible documents:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npx opsx-gherkin profile
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`instructions` is an alias. Both print the same
|
|
42
|
+
[canonical contract](skills/opsx-gherkin/references/OPENSPEC_MDG_PROFILE.feature.md)
|
|
43
|
+
owned by the bundled skill.
|
|
44
|
+
|
|
45
|
+
Conversions validate both endpoints with the pinned official OpenSpec and
|
|
46
|
+
Cucumber validators and compare their normalized models. They preserve the
|
|
47
|
+
documented structure and values while normalizing formatting. Syntax outside
|
|
48
|
+
the compatibility profile produces a diagnostic instead of an inferred mapping.
|
|
49
|
+
Supported delta operations include ADDED, MODIFIED, REMOVED, and RENAMED; the
|
|
50
|
+
contract defines their allowed content.
|
|
51
|
+
|
|
52
|
+
Complete examples: [account access](skills/opsx-gherkin/references/examples/account.feature.md)
|
|
53
|
+
and [authentication delta](skills/opsx-gherkin/references/examples/authentication-delta.feature.md).
|
|
54
|
+
|
|
55
|
+
## Validate syntax directly
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npx --package opsx-gherkin validate-spec --format openspec spec.md
|
|
59
|
+
npx --package opsx-gherkin validate-spec --format mdg input.feature.md
|
|
60
|
+
npx --package opsx-gherkin validate-spec --format feature output.feature
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The validator emits JSON. Without `--format`, `.feature.md` selects MDG,
|
|
64
|
+
`.feature` selects plain Gherkin, and other suffixes select OpenSpec. The legacy
|
|
65
|
+
`--format gherkin` alias selects MDG for `.feature.md` and plain Gherkin otherwise.
|
|
66
|
+
Direct OpenSpec validation checks a main specification; converters also validate
|
|
67
|
+
supported deltas. Valid endpoint syntax alone does not establish convertibility.
|
|
68
|
+
|
|
69
|
+
Exit codes: `0` success, `1` invalid syntax/profile/conversion, `2` usage or I/O
|
|
70
|
+
failure. Conversion diagnostics go to stderr; stdout remains usable as a document.
|
|
71
|
+
|
|
72
|
+
## Use the syntax skill
|
|
73
|
+
|
|
74
|
+
The package contains [skills/opsx-gherkin](skills/opsx-gherkin/SKILL.md), including
|
|
75
|
+
its contract and examples. To obtain it locally:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
npm install --save-dev opsx-gherkin
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Copy the **complete** `node_modules/opsx-gherkin/skills/opsx-gherkin` directory to
|
|
82
|
+
the skill location supported by your agent. Keep the references beside
|
|
83
|
+
`SKILL.md`. The skill explains syntax and conversion independently; installing
|
|
84
|
+
the npm package does not activate it or change agent settings automatically.
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
pnpm install --frozen-lockfile
|
|
90
|
+
pnpm verify
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Verification includes lint, types, tests and coverage, build, package checks,
|
|
94
|
+
and a production installation of the actual tarball. It needs registry access
|
|
95
|
+
to install dependencies and does not publish. `pnpm test:package` runs the
|
|
96
|
+
package checks separately. Supported Node versions are tested in CI.
|
|
97
|
+
|
|
98
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for contract changes and release setup,
|
|
99
|
+
[SECURITY.md](SECURITY.md) for security reporting, and [LICENSE](LICENSE) for MIT terms.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
Keep Node.js and dependencies within their supported ranges. Before converting
|
|
4
|
+
untrusted specifications, inspect the selected source and destination paths.
|
|
5
|
+
The converters treat specification content as data; they do not execute steps
|
|
6
|
+
or Doc Strings. Existing output files require an explicit `--force`.
|
|
7
|
+
|
|
8
|
+
For a potential vulnerability, use the private reporting channel of the hosting
|
|
9
|
+
repository when available. Otherwise contact its maintainer privately. Avoid
|
|
10
|
+
including credentials or sensitive source documents in public reports.
|
|
11
|
+
|
|
12
|
+
Include the package and Node versions, affected command, a minimal sanitized
|
|
13
|
+
input, and the observed behavior. Security fixes should include a regression
|
|
14
|
+
test and pass the package's full verification command.
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { c as errorMessage } from "./official-99qBUZpr.mjs";
|
|
3
|
+
import { t as runConverterCli } from "./converter-CFtzcfoM.mjs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
//#region src/profile-resource.ts
|
|
6
|
+
const profileUrl = new URL("./skills/opsx-gherkin/references/OPENSPEC_MDG_PROFILE.feature.md", import.meta.resolve("opsx-gherkin/package.json"));
|
|
7
|
+
function readProfile() {
|
|
8
|
+
return readFile(profileUrl, "utf8");
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/cli.ts
|
|
12
|
+
const help = `Usage: opsx-gherkin <command> [options]
|
|
13
|
+
|
|
14
|
+
Before generating a compatible specification:
|
|
15
|
+
npx opsx-gherkin profile
|
|
16
|
+
|
|
17
|
+
Commands:
|
|
18
|
+
profile Print the complete normative authoring and conversion contract
|
|
19
|
+
instructions Alias for profile
|
|
20
|
+
mdg-to-opsx Convert Markdown with Gherkin (.feature.md) to OpenSpec
|
|
21
|
+
opsx-to-mdg Convert OpenSpec to Markdown with Gherkin (.feature.md)
|
|
22
|
+
opsx-to-feature Convert OpenSpec to plain Gherkin (.feature)
|
|
23
|
+
|
|
24
|
+
Standalone validator:
|
|
25
|
+
validate-spec [--format openspec|mdg|feature] <file>
|
|
26
|
+
|
|
27
|
+
Run <command> --help for converter options.
|
|
28
|
+
`;
|
|
29
|
+
const [command, ...args] = process.argv.slice(2);
|
|
30
|
+
if (!command || [
|
|
31
|
+
"--help",
|
|
32
|
+
"-h",
|
|
33
|
+
"help"
|
|
34
|
+
].includes(command)) process.stdout.write(help);
|
|
35
|
+
else if (command === "profile" || command === "instructions") try {
|
|
36
|
+
if (args.length) throw new Error(`The ${command} command accepts no arguments`);
|
|
37
|
+
process.stdout.write(await readProfile());
|
|
38
|
+
} catch (error) {
|
|
39
|
+
process.stderr.write(`${errorMessage(error)}\n`);
|
|
40
|
+
process.exitCode = 2;
|
|
41
|
+
}
|
|
42
|
+
else if (command === "mdg-to-opsx" || command === "opsx-to-mdg" || command === "opsx-to-feature") process.exitCode = await runConverterCli(command, args);
|
|
43
|
+
else {
|
|
44
|
+
process.stderr.write(`Unknown command: ${command}\n\n${help}`);
|
|
45
|
+
process.exitCode = 2;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export {};
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/profile-resource.ts","../src/cli.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\n\nexport const profileUrl = new URL(\n './skills/opsx-gherkin/references/OPENSPEC_MDG_PROFILE.feature.md',\n import.meta.resolve('opsx-gherkin/package.json'),\n)\n\nexport function readProfile(): Promise<string> {\n return readFile(profileUrl, 'utf8')\n}\n","#!/usr/bin/env node\nimport { runConverterCli } from './cli/converter.js'\nimport { errorMessage } from './errors.js'\nimport { readProfile } from './profile-resource.js'\n\nconst help = `Usage: opsx-gherkin <command> [options]\n\nBefore generating a compatible specification:\n npx opsx-gherkin profile\n\nCommands:\n profile Print the complete normative authoring and conversion contract\n instructions Alias for profile\n mdg-to-opsx Convert Markdown with Gherkin (.feature.md) to OpenSpec\n opsx-to-mdg Convert OpenSpec to Markdown with Gherkin (.feature.md)\n opsx-to-feature Convert OpenSpec to plain Gherkin (.feature)\n\nStandalone validator:\n validate-spec [--format openspec|mdg|feature] <file>\n\nRun <command> --help for converter options.\n`\n\nconst [command, ...args] = process.argv.slice(2)\nif (!command || ['--help', '-h', 'help'].includes(command)) {\n process.stdout.write(help)\n} else if (command === 'profile' || command === 'instructions') {\n try {\n if (args.length) throw new Error(`The ${command} command accepts no arguments`)\n process.stdout.write(await readProfile())\n } catch (error) {\n process.stderr.write(`${errorMessage(error)}\\n`)\n process.exitCode = 2\n }\n} else if (\n command === 'mdg-to-opsx' ||\n command === 'opsx-to-mdg' ||\n command === 'opsx-to-feature'\n) {\n process.exitCode = await runConverterCli(command, args)\n} else {\n process.stderr.write(`Unknown command: ${command}\\n\\n${help}`)\n process.exitCode = 2\n}\n"],"mappings":";;;;;AAEA,MAAa,aAAa,IAAI,IAC5B,oEACA,YAAY,QAAQ,2BAA2B,CACjD;AAEA,SAAgB,cAA+B;CAC7C,OAAO,SAAS,YAAY,MAAM;AACpC;;;ACJA,MAAM,OAAO;;;;;;;;;;;;;;;;;AAkBb,MAAM,CAAC,SAAS,GAAG,QAAQ,QAAQ,KAAK,MAAM,CAAC;AAC/C,IAAI,CAAC,WAAW;CAAC;CAAU;CAAM;AAAM,CAAC,CAAC,SAAS,OAAO,GACvD,QAAQ,OAAO,MAAM,IAAI;KACpB,IAAI,YAAY,aAAa,YAAY,gBAC9C,IAAI;CACF,IAAI,KAAK,QAAQ,MAAM,IAAI,MAAM,OAAO,QAAQ,8BAA8B;CAC9E,QAAQ,OAAO,MAAM,MAAM,YAAY,CAAC;AAC1C,SAAS,OAAO;CACd,QAAQ,OAAO,MAAM,GAAG,aAAa,KAAK,EAAE,GAAG;CAC/C,QAAQ,WAAW;AACrB;KACK,IACL,YAAY,iBACZ,YAAY,iBACZ,YAAY,mBAEZ,QAAQ,WAAW,MAAM,gBAAgB,SAAS,IAAI;KACjD;CACL,QAAQ,OAAO,MAAM,oBAAoB,QAAQ,MAAM,MAAM;CAC7D,QAAQ,WAAW;AACrB"}
|