返回 DeepSeek-Reasonix
descriptor.go
根目录 / internal / shellrun / descriptor.go
1 package shellrun
2
3 import (
4 "path/filepath"
5 "runtime"
6 "strings"
7
8 "reasonix/internal/sandbox"
9 "reasonix/internal/tool"
10 )
11
12 // DescriptorFromShell builds a partial ShellExecution from a resolved sandbox
13 // Shell. It fills identity fields only; callers set state/phase after the run.
14 func DescriptorFromShell(sh sandbox.Shell) *tool.ShellExecution {
15 ex := &tool.ShellExecution{
16 Kind: "shell",
17 Platform: platformName(),
18 SupportsAndAnd: sh.SupportsChaining(),
19 }
20 name, version := classifyShell(sh)
21 ex.Shell = name
22 if version != "" {
23 ex.ShellVersion = version
24 }
25 return ex
26 }
27
28 // DisplayName returns the human-facing shell label for cards and CLI lines.
29 func DisplayName(ex *tool.ShellExecution) string {
30 if ex == nil {
31 return "bash"
32 }
33 switch ex.Shell {
34 case tool.ShellNameGitBash:
35 return "Git Bash"
36 case tool.ShellNamePowerShell:
37 return "Windows PowerShell"
38 case tool.ShellNamePwsh:
39 return "PowerShell 7+"
40 case tool.ShellNameBash:
41 return "bash"
42 default:
43 if ex.Shell != "" {
44 return ex.Shell
45 }
46 return "bash"
47 }
48 }
49
50 // classifyShell maps a resolved Shell to contract names.
51 // powershell.exe → powershell / 5.1; pwsh → pwsh / 7+; Git for Windows bash → git-bash.
52 func classifyShell(sh sandbox.Shell) (name, version string) {
53 base := strings.ToLower(filepath.Base(sh.Path))
54 base = strings.TrimSuffix(base, ".exe")
55 switch sh.Kind {
56 case sandbox.ShellPowerShell:
57 if base == "pwsh" || sh.SupportsChaining() {
58 return tool.ShellNamePwsh, tool.ShellVersionPS7
59 }
60 return tool.ShellNamePowerShell, tool.ShellVersionPS51
61 default:
62 if isGitBashPath(sh.Path) {
63 return tool.ShellNameGitBash, ""
64 }
65 return tool.ShellNameBash, ""
66 }
67 }
68
69 func isGitBashPath(path string) bool {
70 if path == "" {
71 return false
72 }
73 // Normalize separators so both "Git\bin\bash.exe" and "Git/bin/bash" match.
74 norm := strings.ToLower(strings.ReplaceAll(path, "\\", "/"))
75 return strings.Contains(norm, "/git/") && strings.Contains(norm, "bash")
76 }
77
78 func platformName() string {
79 switch runtime.GOOS {
80 case "windows":
81 return "windows"
82 case "darwin":
83 return "darwin"
84 default:
85 return "linux"
86 }
87 }
88
88 lines GO