fix(ax): make workspace extraction Result-native
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
e826d672b0
commit
b8466fb56d
6 changed files with 84 additions and 48 deletions
|
|
@ -224,8 +224,11 @@ func (s *PrepSubsystem) cmdExtract(opts core.Options) core.Result {
|
|||
}
|
||||
|
||||
core.Print(nil, "extracting template %q to %s", tmpl, target)
|
||||
if err := lib.ExtractWorkspace(tmpl, target, data); err != nil {
|
||||
return core.Result{Value: err, OK: false}
|
||||
if result := lib.ExtractWorkspace(tmpl, target, data); !result.OK {
|
||||
if err, ok := result.Value.(error); ok {
|
||||
return core.Result{Value: core.E("agentic.cmdExtract", core.Concat("extract workspace template ", tmpl), err), OK: false}
|
||||
}
|
||||
return core.Result{Value: core.E("agentic.cmdExtract", core.Concat("extract workspace template ", tmpl), nil), OK: false}
|
||||
}
|
||||
|
||||
fsys := s.Core().Fs()
|
||||
|
|
|
|||
|
|
@ -466,12 +466,17 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
|
|||
}
|
||||
|
||||
// Extract default workspace template (go.work etc.)
|
||||
lib.ExtractWorkspace("default", wsDir, &lib.WorkspaceData{
|
||||
if result := lib.ExtractWorkspace("default", wsDir, &lib.WorkspaceData{
|
||||
Repo: input.Repo,
|
||||
Branch: "",
|
||||
Task: input.Task,
|
||||
Agent: input.Agent,
|
||||
})
|
||||
}); !result.OK {
|
||||
if err, ok := result.Value.(error); ok {
|
||||
return nil, PrepOutput{}, core.E("prepWorkspace", "extract default workspace template", err)
|
||||
}
|
||||
return nil, PrepOutput{}, core.E("prepWorkspace", "extract default workspace template", nil)
|
||||
}
|
||||
|
||||
if !resumed {
|
||||
// Clone repo into repo/
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
// r := lib.Task("code/review") // r.Value.(string)
|
||||
// r := lib.Persona("secops/dev") // r.Value.(string)
|
||||
// r := lib.Flow("go") // r.Value.(string)
|
||||
// lib.ExtractWorkspace("default", "/tmp/ws", data)
|
||||
// r := lib.ExtractWorkspace("default", "/tmp/ws", data)
|
||||
// core.Println(r.OK)
|
||||
package lib
|
||||
|
||||
import (
|
||||
|
|
@ -264,32 +265,51 @@ type WorkspaceData struct {
|
|||
// ExtractWorkspace creates an agent workspace from a template.
|
||||
// Template names: "default", "security", "review".
|
||||
//
|
||||
// lib.ExtractWorkspace("default", "/tmp/ws", &lib.WorkspaceData{
|
||||
// r := lib.ExtractWorkspace("default", "/tmp/ws", &lib.WorkspaceData{
|
||||
// Repo: "go-io", Task: "fix tests", Agent: "codex",
|
||||
// })
|
||||
func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) error {
|
||||
// core.Println(r.OK)
|
||||
func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) core.Result {
|
||||
if result := ensureMounted(); !result.OK {
|
||||
if err, ok := result.Value.(error); ok {
|
||||
return err
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", tmplName), err),
|
||||
OK: false,
|
||||
}
|
||||
}
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", tmplName), nil),
|
||||
OK: false,
|
||||
}
|
||||
return core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", tmplName), nil)
|
||||
}
|
||||
|
||||
r := workspaceFS.Sub(tmplName)
|
||||
if !r.OK {
|
||||
if err, ok := r.Value.(error); ok {
|
||||
return err
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", tmplName), err),
|
||||
OK: false,
|
||||
}
|
||||
}
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", tmplName), nil),
|
||||
OK: false,
|
||||
}
|
||||
return core.E("ExtractWorkspace", core.Concat("template not found: ", tmplName), nil)
|
||||
}
|
||||
result := core.Extract(r.Value.(*core.Embed).FS(), targetDir, data)
|
||||
if !result.OK {
|
||||
if err, ok := result.Value.(error); ok {
|
||||
return err
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", tmplName), err),
|
||||
OK: false,
|
||||
}
|
||||
}
|
||||
return core.Result{
|
||||
Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", tmplName), nil),
|
||||
OK: false,
|
||||
}
|
||||
return core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", tmplName), nil)
|
||||
}
|
||||
return nil
|
||||
return core.Result{Value: targetDir, OK: true}
|
||||
}
|
||||
|
||||
// WorkspaceFile reads a single file from a workspace template.
|
||||
|
|
|
|||
|
|
@ -103,9 +103,9 @@ func ExampleExtractWorkspace() {
|
|||
dir := (&core.Fs{}).NewUnrestricted().TempDir("example-ws")
|
||||
defer (&core.Fs{}).NewUnrestricted().DeleteAll(dir)
|
||||
|
||||
err := ExtractWorkspace("default", dir, &WorkspaceData{
|
||||
r := ExtractWorkspace("default", dir, &WorkspaceData{
|
||||
Repo: "go-io", Task: "fix tests",
|
||||
})
|
||||
core.Println(err == nil)
|
||||
core.Println(r.OK)
|
||||
// Output: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,30 @@ func corruptLibMountForTest(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func requireExtractWorkspaceOK(t *testing.T, result core.Result) string {
|
||||
t.Helper()
|
||||
if !result.OK {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", result.Value)
|
||||
}
|
||||
path, ok := result.Value.(string)
|
||||
if !ok {
|
||||
t.Fatalf("ExtractWorkspace returned %T, want string", result.Value)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func requireExtractWorkspaceError(t *testing.T, result core.Result) error {
|
||||
t.Helper()
|
||||
if result.OK {
|
||||
t.Fatalf("ExtractWorkspace unexpectedly succeeded: %#v", result.Value)
|
||||
}
|
||||
err, ok := result.Value.(error)
|
||||
if !ok {
|
||||
t.Fatalf("ExtractWorkspace returned %T, want error", result.Value)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// --- Prompt ---
|
||||
|
||||
func TestLib_Prompt_Good(t *testing.T) {
|
||||
|
|
@ -489,10 +513,7 @@ func TestLib_ExtractWorkspace_Good(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
for _, name := range []string{"CODEX.md", "CLAUDE.md", "PROMPT.md", "TODO.md", "CONTEXT.md", "go.work"} {
|
||||
if !testFs.Exists(core.JoinPath(dir, name)) {
|
||||
|
|
@ -505,10 +526,7 @@ func TestLib_ExtractWorkspaceSubdirs_Good(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
refDir := core.JoinPath(dir, ".core", "reference")
|
||||
if !testFs.IsDir(refDir) {
|
||||
|
|
@ -535,10 +553,7 @@ func TestLib_ExtractWorkspaceTemplate_Good(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "my-repo", Task: "fix the bug"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
r := testFs.Read(core.JoinPath(dir, "TODO.md"))
|
||||
if !r.OK {
|
||||
|
|
@ -550,27 +565,18 @@ func TestLib_ExtractWorkspaceTemplate_Good(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestLib_ExtractWorkspace_Bad(t *testing.T) {
|
||||
err := ExtractWorkspace("missing-template", t.TempDir(), &WorkspaceData{Repo: "test-repo"})
|
||||
if err == nil {
|
||||
t.Fatal("ExtractWorkspace should fail for an unknown template")
|
||||
}
|
||||
requireExtractWorkspaceError(t, ExtractWorkspace("missing-template", t.TempDir(), &WorkspaceData{Repo: "test-repo"}))
|
||||
}
|
||||
|
||||
func TestLib_ExtractWorkspace_Ugly(t *testing.T) {
|
||||
err := ExtractWorkspace("default", t.TempDir(), nil)
|
||||
if err == nil {
|
||||
t.Fatal("ExtractWorkspace should fail when template data is nil")
|
||||
}
|
||||
requireExtractWorkspaceError(t, ExtractWorkspace("default", t.TempDir(), nil))
|
||||
}
|
||||
|
||||
func TestLib_ExtractWorkspace_Good_AXConventions(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "align AX docs"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
r := testFs.Read(core.JoinPath(dir, "CODEX.md"))
|
||||
if !r.OK {
|
||||
|
|
@ -624,9 +630,7 @@ func TestLib_ExtractWorkspace_Good_ReferenceHeaders(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "carry SPDX headers into workspace references"}
|
||||
|
||||
if err := ExtractWorkspace("default", dir, data); err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
refDir := core.JoinPath(dir, ".core", "reference")
|
||||
goFiles := core.PathGlob(core.JoinPath(refDir, "*.go"))
|
||||
|
|
@ -643,9 +647,7 @@ func TestLib_ExtractWorkspace_Good_ReferenceUsageExamples(t *testing.T) {
|
|||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "carry AX usage examples into workspace references"}
|
||||
|
||||
if err := ExtractWorkspace("default", dir, data); err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
requireExtractWorkspaceOK(t, ExtractWorkspace("default", dir, data))
|
||||
|
||||
cases := map[string][]string{
|
||||
core.JoinPath(dir, ".core", "reference", "array.go"): {
|
||||
|
|
|
|||
|
|
@ -134,9 +134,15 @@ func (s *Service) scaffoldTemplate(opts Options, projType ProjectType, tmplName
|
|||
return core.Result{Value: opts.Path, OK: true}
|
||||
}
|
||||
|
||||
if err := lib.ExtractWorkspace(tmplName, opts.Path, data); err != nil {
|
||||
if result := lib.ExtractWorkspace(tmplName, opts.Path, data); !result.OK {
|
||||
if err, ok := result.Value.(error); ok {
|
||||
return core.Result{
|
||||
Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", tmplName), err),
|
||||
OK: false,
|
||||
}
|
||||
}
|
||||
return core.Result{
|
||||
Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", tmplName), err),
|
||||
Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", tmplName), nil),
|
||||
OK: false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue