refactor(monorepo): extract inbox and orch runtimes
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package inbox
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"ai-workflow-skill/packages/coord-core/protocol"
|
||||
"ai-workflow-skill/packages/coord-core/store"
|
||||
)
|
||||
|
||||
func Execute(args []string, stdout, stderr io.Writer) int {
|
||||
cmd := NewRootCmd()
|
||||
cmd.SetOut(stdout)
|
||||
cmd.SetErr(stderr)
|
||||
cmd.SetArgs(args)
|
||||
|
||||
if err := cmd.Execute(); err != nil {
|
||||
jsonOutput := hasJSONFlag(args)
|
||||
renderError(stdout, stderr, jsonOutput, err)
|
||||
return exitCodeForError(err)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func exitCodeForError(err error) int {
|
||||
var cliErr *protocol.CLIError
|
||||
if errors.As(err, &cliErr) {
|
||||
return cliErr.ExitCode
|
||||
}
|
||||
|
||||
switch {
|
||||
case isUsageError(err):
|
||||
return 30
|
||||
case errors.Is(err, store.ErrLeaseConflict):
|
||||
return 20
|
||||
case errors.Is(err, store.ErrThreadNotFound), errors.Is(err, store.ErrMessageNotFound):
|
||||
return 40
|
||||
case errors.Is(err, store.ErrInvalidInput), errors.Is(err, store.ErrInvalidState), errors.Is(err, store.ErrNoActiveLease):
|
||||
return 30
|
||||
default:
|
||||
return 50
|
||||
}
|
||||
}
|
||||
|
||||
func errorCodeForError(err error) string {
|
||||
var cliErr *protocol.CLIError
|
||||
if errors.As(err, &cliErr) {
|
||||
return cliErr.Code
|
||||
}
|
||||
|
||||
switch {
|
||||
case isUsageError(err):
|
||||
return "invalid_input"
|
||||
case errors.Is(err, store.ErrLeaseConflict):
|
||||
return "lease_conflict"
|
||||
case errors.Is(err, store.ErrThreadNotFound), errors.Is(err, store.ErrMessageNotFound):
|
||||
return "not_found"
|
||||
case errors.Is(err, store.ErrInvalidInput):
|
||||
return "invalid_input"
|
||||
case errors.Is(err, store.ErrInvalidState), errors.Is(err, store.ErrNoActiveLease):
|
||||
return "invalid_state"
|
||||
default:
|
||||
return "internal_error"
|
||||
}
|
||||
}
|
||||
|
||||
func renderError(stdout, stderr io.Writer, jsonOutput bool, err error) {
|
||||
message := errorMessage(err)
|
||||
if jsonOutput {
|
||||
_ = protocol.WriteJSON(stdout, protocol.Error{
|
||||
OK: false,
|
||||
Error: protocol.ErrorPayload{
|
||||
Code: errorCodeForError(err),
|
||||
Message: message,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintln(stderr, message)
|
||||
}
|
||||
|
||||
func errorMessage(err error) string {
|
||||
var cliErr *protocol.CLIError
|
||||
if errors.As(err, &cliErr) {
|
||||
return cliErr.Message
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
func hasJSONFlag(args []string) bool {
|
||||
for _, arg := range args {
|
||||
if arg == "--json" {
|
||||
return true
|
||||
}
|
||||
if strings.HasPrefix(arg, "--json=") {
|
||||
return !strings.HasSuffix(arg, "=false")
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isUsageError(err error) bool {
|
||||
message := err.Error()
|
||||
return strings.HasPrefix(message, "required flag(s)") ||
|
||||
strings.HasPrefix(message, "unknown flag:") ||
|
||||
strings.HasPrefix(message, "unknown command ") ||
|
||||
strings.Contains(message, " accepts ") ||
|
||||
strings.Contains(message, "invalid argument ")
|
||||
}
|
||||
Reference in New Issue
Block a user