mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 17:10:43 -10:00
Merge pull request #11646 from KHG420/codex/studio-scenario-skill-frontmatter
fix(studio): keep scenario skill frontmatter valid YAML
This commit is contained in:
7 files changed
+84
-18
No files matched your search
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: api-notes
|
||||
description: Turn a user-selected local OpenAPI JSON document into a Markdown guide with source pointers and an explicit review record.
|
||||
owner: @esengine
|
||||
backup: @SivanCola
|
||||
owner: "@esengine"
|
||||
backup: "@SivanCola"
|
||||
status: active
|
||||
reviewed: 2026-10-01
|
||||
---
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: frontend-page
|
||||
description: Build a frontend from selected requirements and hand it off with observed browser acceptance and remaining issues.
|
||||
owner: @esengine
|
||||
backup: @SivanCola
|
||||
owner: "@esengine"
|
||||
backup: "@SivanCola"
|
||||
status: active
|
||||
reviewed: 2026-10-01
|
||||
---
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: issue-fix
|
||||
description: Reproduce a repository issue, make the smallest correct fix, and draft a pull request from observed evidence.
|
||||
owner: @esengine
|
||||
backup: @SivanCola
|
||||
owner: "@esengine"
|
||||
backup: "@SivanCola"
|
||||
status: active
|
||||
reviewed: 2026-10-01
|
||||
---
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: release-note
|
||||
description: Draft a release note from user-selected changes, citing only verified behavior.
|
||||
owner: @esengine
|
||||
backup: @SivanCola
|
||||
owner: "@esengine"
|
||||
backup: "@SivanCola"
|
||||
status: active
|
||||
reviewed: 2026-09-29
|
||||
---
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package skill
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"reasonix/internal/base/testenv"
|
||||
)
|
||||
|
||||
func TestScenarioExamplesDiscoverWithoutInvalidFrontmatter(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
plugin string
|
||||
name string
|
||||
}{
|
||||
{plugin: "release-note-kit", name: "release-note"},
|
||||
{plugin: "issue-fix-kit", name: "issue-fix"},
|
||||
{plugin: "frontend-page-kit", name: "frontend-page"},
|
||||
{plugin: "api-notes-kit", name: "api-notes"},
|
||||
} {
|
||||
t.Run(tc.plugin, func(t *testing.T) {
|
||||
root := testenv.TempDir(t)
|
||||
source := filepath.Join("..", "..", "..", "examples", tc.plugin)
|
||||
if err := os.CopyFS(root, os.DirFS(source)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
skillsRoot := filepath.Join(root, "skills")
|
||||
store := New(Options{
|
||||
HomeDir: testenv.TempDir(t),
|
||||
CustomPaths: []string{skillsRoot},
|
||||
PluginPaths: map[string][]string{skillsRoot: {tc.plugin}},
|
||||
DisableBuiltins: true,
|
||||
})
|
||||
skills := store.SlashList()
|
||||
if len(skills) != 1 {
|
||||
t.Fatalf("discovered skills = %v, want one scenario skill", skills)
|
||||
}
|
||||
sk := skills[0]
|
||||
if sk.Name != tc.name || sk.SlashName() != tc.plugin+":"+tc.name {
|
||||
t.Fatalf("skill identity = %q / %q", sk.Name, sk.SlashName())
|
||||
}
|
||||
if sk.Description == "" || sk.Body == "" {
|
||||
t.Fatal("scenario skill lost its description or instructions")
|
||||
}
|
||||
if len(sk.Invalid) != 0 {
|
||||
t.Fatalf("scenario skill frontmatter diagnostics = %v", sk.Invalid)
|
||||
}
|
||||
if err := store.ValidateInvocation(sk); err != nil {
|
||||
t.Fatalf("scenario skill invocation: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -12,6 +12,8 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type docClass int
|
||||
@@ -168,7 +170,14 @@ func docMetadata(lines []string) (map[string]string, bool) {
|
||||
return meta, true
|
||||
}
|
||||
if key, value, ok := strings.Cut(line, ":"); ok {
|
||||
meta[strings.TrimSpace(key)] = strings.TrimSpace(value)
|
||||
value = strings.TrimSpace(value)
|
||||
if strings.HasPrefix(value, `"`) || strings.HasPrefix(value, "'") {
|
||||
var scalar string
|
||||
if err := yaml.Unmarshal([]byte(value), &scalar); err == nil {
|
||||
value = scalar
|
||||
}
|
||||
}
|
||||
meta[strings.TrimSpace(key)] = value
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
|
||||
@@ -87,21 +87,25 @@ func TestADocumentNamesItsOwnersAsCodeOwnersDoes(t *testing.T) {
|
||||
return "---\nowner: " + owner + "\nbackup: " + backup + "\nstatus: active\nreviewed: 2026-09-17\n---\n# T\n"
|
||||
}
|
||||
root := docRepo(t, map[string]string{
|
||||
".github/CODEOWNERS": "* @a @b\n/docs/ @b @a\n",
|
||||
"docs/good.md": header("@b", "@a"),
|
||||
"docs/swapped.md": header("@a", "@b"),
|
||||
"docs/bare.md": "# No header\n",
|
||||
"top.md": header("@a", "@b"),
|
||||
"README.md": "# Landing page, owned through CODEOWNERS only\n",
|
||||
"REASONIX.md": "# Read by a model verbatim\n",
|
||||
".github/CODEOWNERS": "* @a @b\n/docs/ @b @a\n",
|
||||
"docs/good.md": header("@b", "@a"),
|
||||
"docs/double.md": header(`"@b"`, `"@a"`),
|
||||
"docs/single.md": header("'@b'", "'@a'"),
|
||||
"docs/swapped.md": header("@a", "@b"),
|
||||
"docs/quoted-swap.md": header(`"@a"`, `"@b"`),
|
||||
"docs/broken.md": header(`"@b`, `"@a"`),
|
||||
"docs/bare.md": "# No header\n",
|
||||
"top.md": header("@a", "@b"),
|
||||
"README.md": "# Landing page, owned through CODEOWNERS only\n",
|
||||
"REASONIX.md": "# Read by a model verbatim\n",
|
||||
})
|
||||
got := ruleFindings(checkDocs(root), ruleDocOwner)
|
||||
flagged := map[string]string{}
|
||||
for _, f := range got {
|
||||
flagged[f.File] = f.Msg
|
||||
}
|
||||
if len(flagged) != 2 || flagged["docs/swapped.md"] == "" || flagged["docs/bare.md"] == "" {
|
||||
t.Fatalf("flagged = %v, want exactly the swapped owners and the missing header", flagged)
|
||||
if len(flagged) != 4 || flagged["docs/swapped.md"] == "" || flagged["docs/quoted-swap.md"] == "" || flagged["docs/broken.md"] == "" || flagged["docs/bare.md"] == "" {
|
||||
t.Fatalf("flagged = %v, want swapped owners, malformed quotes and the missing header", flagged)
|
||||
}
|
||||
if !strings.Contains(flagged["docs/swapped.md"], "CODEOWNERS line 2") {
|
||||
t.Fatalf("the finding must point at the rule it disagrees with: %s", flagged["docs/swapped.md"])
|
||||
|
||||
Reference in new issue
Block a user