mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
fix(pluginpkg): finish rendering package data inside host sentences as literals
Skill shadow and unselected warnings, the migrated and remediation sentences (plugin name), the persist-status warning, manifest read warnings and the strict-decode error now show package data through ShownLocator or ShownIdentity.
This commit is contained in:
1 parent
5047e081bc
commit
60f37ee7c6
7 files changed
+54
-10
No files matched your search
@@ -83,7 +83,7 @@ func (t *Tool) applySkillRoot(req request, act *action) error {
|
||||
}
|
||||
}
|
||||
if registeredPath == "" {
|
||||
act.Warnings = append(act.Warnings, fmt.Sprintf("skill %q registered from %s is not selected in this workspace; current selection is %s", name, act.Source, sk.Path))
|
||||
act.Warnings = append(act.Warnings, unselectedSkillWarning(name, act.Source, sk.Path))
|
||||
continue
|
||||
}
|
||||
act.Discoverable = true
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package installsource
|
||||
|
||||
import "fmt"
|
||||
|
||||
func shadowedSkillWarning(name, installed, selected string) string {
|
||||
return fmt.Sprintf("skill %q installed at %s is shadowed in this workspace by %s", name, hostLiteral(installed), hostLiteral(selected))
|
||||
}
|
||||
|
||||
func unselectedSkillWarning(name, source, selected string) string {
|
||||
return fmt.Sprintf("skill %q registered from %s is not selected in this workspace; current selection is %s", name, hostLiteral(source), hostLiteral(selected))
|
||||
}
|
||||
@@ -11,3 +11,14 @@ func TestSkippedMarketplaceWarningShowsAnUnterminatedEscapeInsteadOfEatingIt(t *
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSkillSentencesShowPathsAsLiterals(t *testing.T) {
|
||||
for _, got := range []string{
|
||||
shadowedSkillWarning("s", "/a\x1b]0;", "/b\x1b]0;"),
|
||||
unselectedSkillWarning("s", "/a\x1b]0;", "/b\x1b]0;"),
|
||||
} {
|
||||
if strings.ContainsRune(got, 0x1b) || strings.Count(got, `\u{1b}]0;`) != 2 {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ func (t *Tool) verifySkill(scope, name string, act *action) error {
|
||||
}
|
||||
installedPath := config.CanonicalSkillPath(act.CanonicalPath)
|
||||
if config.CanonicalSkillPath(sk.Path) != installedPath {
|
||||
act.Warnings = append(act.Warnings, fmt.Sprintf("skill %q installed at %s is shadowed in this workspace by %s", name, act.CanonicalPath, sk.Path))
|
||||
act.Warnings = append(act.Warnings, shadowedSkillWarning(name, act.CanonicalPath, sk.Path))
|
||||
} else {
|
||||
act.Discoverable = true
|
||||
for _, listed := range store.List() {
|
||||
|
||||
@@ -12,6 +12,14 @@ import (
|
||||
"reasonix/internal/base/textutil"
|
||||
)
|
||||
|
||||
func migratedWarning(name string) string {
|
||||
return fmt.Sprintf("%s: automatically migrated managed manifest to %s (backup: %s.bak)", textutil.ShownIdentity(name), ManifestAPIVersionV2, NativeManifest)
|
||||
}
|
||||
|
||||
func migrateRemediation(name string) string {
|
||||
return fmt.Sprintf("reasonix plugin migrate %s --to-v2", textutil.ShownIdentity(name))
|
||||
}
|
||||
|
||||
// incompatibleWarning writes the whole sentence first and shows the error as a
|
||||
// literal: its text can come from the package's own manifest.
|
||||
func incompatibleWarning(name string, err error, remediation string) string {
|
||||
@@ -42,7 +50,7 @@ func LoadInstalled(reasonixHome string) ([]InstalledPackage, []string) {
|
||||
var migrated bool
|
||||
pkg, pkgWarnings, migrated, err = migrateManagedManifest(root)
|
||||
if migrated {
|
||||
warnings = append(warnings, fmt.Sprintf("%s: automatically migrated managed manifest to %s (backup: %s.bak)", installed.Name, ManifestAPIVersionV2, NativeManifest))
|
||||
warnings = append(warnings, migratedWarning(installed.Name))
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
@@ -52,7 +60,7 @@ func LoadInstalled(reasonixHome string) ([]InstalledPackage, []string) {
|
||||
}
|
||||
remediation := "repair or reinstall the plugin"
|
||||
if errors.Is(err, ErrMissingAPIVersion) {
|
||||
remediation = fmt.Sprintf("reasonix plugin migrate %s --to-v2", installed.Name)
|
||||
remediation = migrateRemediation(installed.Name)
|
||||
}
|
||||
warnings = append(warnings, incompatibleWarning(installed.Name, err, remediation))
|
||||
continue
|
||||
@@ -63,7 +71,7 @@ func LoadInstalled(reasonixHome string) ([]InstalledPackage, []string) {
|
||||
out = append(out, InstalledPackage{Installed: installed, Package: pkg, Warnings: pkgWarnings})
|
||||
}
|
||||
if err := persistStatusVerdicts(reasonixHome, verdicts); err != nil {
|
||||
warnings = append(warnings, "persist plugin compatibility status: "+err.Error())
|
||||
warnings = append(warnings, "persist plugin compatibility status: "+textutil.ShownLocator(err.Error()))
|
||||
}
|
||||
sort.SliceStable(out, func(i, j int) bool { return out[i].Installed.Name < out[j].Installed.Name })
|
||||
return out, warnings
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package pluginpkg
|
||||
|
||||
import (
|
||||
"reasonix/internal/base/textutil"
|
||||
"reasonix/internal/ext/extensioncontract"
|
||||
"regexp"
|
||||
|
||||
@@ -96,7 +97,7 @@ func strictDecode(data []byte, v any, path string) error {
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
dec.DisallowUnknownFields()
|
||||
if err := dec.Decode(v); err != nil {
|
||||
return fmt.Errorf("%s: %w", path, err)
|
||||
return fmt.Errorf("%s: %s", path, textutil.ShownLocator(err.Error()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -493,20 +494,20 @@ func validateV1Paths(root string, m *Manifest) ([]string, error) {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q does not exist", kind, rel))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q is not readable: %v", kind, rel, err))
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q is not readable: %s", kind, rel, textutil.ShownLocator(err.Error())))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
resolved, err := filepath.EvalSymlinks(abs)
|
||||
if err != nil {
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q cannot be resolved: %v", kind, rel, err))
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q cannot be resolved: %s", kind, rel, textutil.ShownLocator(err.Error())))
|
||||
return nil
|
||||
}
|
||||
if !pathWithinRoot(resolvedRoot, resolved) {
|
||||
return fmt.Errorf("%s path %q escapes the plugin root through a symlink", kind, rel)
|
||||
}
|
||||
if info, err := os.Stat(abs); err != nil {
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q is not readable: %v", kind, rel, err))
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q is not readable: %s", kind, rel, textutil.ShownLocator(err.Error())))
|
||||
} else if !info.IsDir() {
|
||||
warnings = append(warnings, fmt.Sprintf("%s path %q is not a directory; declare the containing directory instead", kind, rel))
|
||||
}
|
||||
@@ -539,7 +540,7 @@ func validateV1Paths(root string, m *Manifest) ([]string, error) {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
warnings = append(warnings, fmt.Sprintf("themes path %q does not exist", pattern))
|
||||
} else {
|
||||
warnings = append(warnings, fmt.Sprintf("themes path %q is not readable: %v", pattern, err))
|
||||
warnings = append(warnings, fmt.Sprintf("themes path %q is not readable: %s", pattern, textutil.ShownLocator(err.Error())))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -40,3 +40,16 @@ func TestIncompatibleWarningShowsTheErrorAsALiteralAndKeepsItsRemediation(t *tes
|
||||
t.Fatalf("the sentence lost its tail: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstalledNameAndDecodeErrorsAreShownAsLiterals(t *testing.T) {
|
||||
requireShown(t, migratedWarning("demo"+unterminated))
|
||||
requireShown(t, migrateRemediation("demo"+unterminated))
|
||||
var v struct{}
|
||||
err := strictDecode([]byte(`{"bad`+unterminated+`": 1}`), &v, "plugin.json")
|
||||
if err == nil {
|
||||
t.Fatal("an unknown field must fail")
|
||||
}
|
||||
if strings.ContainsRune(err.Error(), 0x1b) {
|
||||
t.Fatalf("a raw escape reached the decode error: %q", err.Error())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user