diff --git a/cmd/dev/cmd_bundles.go b/cmd/dev/cmd_bundles.go index e35f4e3..cb9d8c2 100644 --- a/cmd/dev/cmd_bundles.go +++ b/cmd/dev/cmd_bundles.go @@ -2,10 +2,9 @@ package dev import ( "context" + "fmt" - agentic "forge.lthn.ai/core/agent/pkg/lifecycle" - "forge.lthn.ai/core/go/pkg/core" - "forge.lthn.ai/core/go-scm/git" + "dappco.re/go/core" ) // WorkBundle contains the Core instance for dev work operations. @@ -16,71 +15,52 @@ type WorkBundle struct { // WorkBundleOptions configures the work bundle. type WorkBundleOptions struct { RegistryPath string - AllowEdit bool // Allow agentic to use Write/Edit tools } // NewWorkBundle creates a bundle for dev work operations. -// Includes: dev (orchestration), git, agentic services. +// Includes: dev (orchestration) service. func NewWorkBundle(opts WorkBundleOptions) (*WorkBundle, error) { - c, err := core.New( - core.WithService(NewService(ServiceOptions{ + c := core.New() + + svc := &Service{ + ServiceRuntime: core.NewServiceRuntime(c, ServiceOptions{ RegistryPath: opts.RegistryPath, - })), - core.WithService(git.NewService(git.ServiceOptions{})), - core.WithService(agentic.NewService(agentic.ServiceOptions{ - AllowEdit: opts.AllowEdit, - })), - core.WithServiceLock(), - ) - if err != nil { - return nil, err + }), } + c.Service("dev", core.Service{ + OnStart: func() core.Result { + c.RegisterTask(svc.handleTask) + return core.Result{OK: true} + }, + }) + + c.LockEnable() + c.LockApply() + return &WorkBundle{Core: c}, nil } // Start initialises the bundle services. func (b *WorkBundle) Start(ctx context.Context) error { - return b.Core.ServiceStartup(ctx, nil) + return resultError(b.Core.ServiceStartup(ctx, nil)) } // Stop shuts down the bundle services. func (b *WorkBundle) Stop(ctx context.Context) error { - return b.Core.ServiceShutdown(ctx) + return resultError(b.Core.ServiceShutdown(ctx)) } -// StatusBundle contains the Core instance for status-only operations. -type StatusBundle struct { - Core *core.Core -} - -// StatusBundleOptions configures the status bundle. -type StatusBundleOptions struct { - RegistryPath string -} - -// NewStatusBundle creates a bundle for status-only operations. -// Includes: dev (orchestration), git services. No agentic - commits not available. -func NewStatusBundle(opts StatusBundleOptions) (*StatusBundle, error) { - c, err := core.New( - core.WithService(NewService(ServiceOptions(opts))), - core.WithService(git.NewService(git.ServiceOptions{})), - // No agentic service - TaskCommit will be unhandled - core.WithServiceLock(), - ) - if err != nil { - return nil, err +// resultError extracts an error from a failed core.Result, returning nil on success. +func resultError(r core.Result) error { + if !r.OK { + if err, ok := r.Value.(error); ok { + return err + } + if r.Value != nil { + return fmt.Errorf("service operation failed: %v", r.Value) + } + return fmt.Errorf("service operation failed") } - - return &StatusBundle{Core: c}, nil -} - -// Start initialises the bundle services. -func (b *StatusBundle) Start(ctx context.Context) error { - return b.Core.ServiceStartup(ctx, nil) -} - -// Stop shuts down the bundle services. -func (b *StatusBundle) Stop(ctx context.Context) error { - return b.Core.ServiceShutdown(ctx) + return nil } diff --git a/cmd/dev/cmd_commit.go b/cmd/dev/cmd_commit.go index a16ad17..b0c92bd 100644 --- a/cmd/dev/cmd_commit.go +++ b/cmd/dev/cmd_commit.go @@ -117,7 +117,7 @@ func runCommit(registryPath string, all bool) error { for _, s := range dirtyRepos { cli.Print("%s %s\n", dimStyle.Render(i18n.T("cmd.dev.committing")), s.Name) - if err := claudeCommit(ctx, s.Path, s.Name, registryPath); err != nil { + if err := doCommit(ctx, s.Path, false); err != nil { cli.Print(" %s %s\n", errorStyle.Render("x"), err) failed++ } else { @@ -192,7 +192,7 @@ func runCommitSingleRepo(ctx context.Context, repoPath string, all bool) error { cli.Blank() // Commit - if err := claudeCommit(ctx, repoPath, repoName, ""); err != nil { + if err := doCommit(ctx, repoPath, false); err != nil { cli.Print(" %s %s\n", errorStyle.Render("x"), err) return err } diff --git a/cmd/dev/cmd_push.go b/cmd/dev/cmd_push.go index 95556ce..86d5285 100644 --- a/cmd/dev/cmd_push.go +++ b/cmd/dev/cmd_push.go @@ -206,7 +206,7 @@ func runPushSingleRepo(ctx context.Context, repoPath string, force bool) error { // Use edit-enabled commit if only untracked files (may need .gitignore fix) var err error if s.Modified == 0 && s.Staged == 0 && s.Untracked > 0 { - err = claudeEditCommit(ctx, repoPath, repoName, "") + err = doCommit(ctx, repoPath, true) } else { err = runCommitSingleRepo(ctx, repoPath, false) } diff --git a/cmd/dev/cmd_work.go b/cmd/dev/cmd_work.go index 6eea8f7..1208b0b 100644 --- a/cmd/dev/cmd_work.go +++ b/cmd/dev/cmd_work.go @@ -3,15 +3,12 @@ package dev import ( "cmp" "context" - "os" - "os/exec" "slices" "strings" "forge.lthn.ai/core/cli/pkg/cli" - agentic "forge.lthn.ai/core/agent/pkg/lifecycle" - "forge.lthn.ai/core/go-scm/git" "forge.lthn.ai/core/go-i18n" + "forge.lthn.ai/core/go-scm/git" ) // Work command flags @@ -57,42 +54,30 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { defer func() { _ = bundle.Stop(ctx) }() // Load registry and get paths - paths, names, err := func() ([]string, map[string]string, error) { - reg, _, err := loadRegistryWithConfig(registryPath) - if err != nil { - return nil, nil, err - } - var paths []string - names := make(map[string]string) - for _, repo := range reg.List() { - if repo.IsGitRepo() { - paths = append(paths, repo.Path) - names[repo.Path] = repo.Name - } - } - return paths, names, nil - }() + reg, _, err := loadRegistryWithConfig(registryPath) if err != nil { return err } + var paths []string + names := make(map[string]string) + for _, repo := range reg.List() { + if repo.IsGitRepo() { + paths = append(paths, repo.Path) + names[repo.Path] = repo.Name + } + } + if len(paths) == 0 { cli.Text(i18n.T("cmd.dev.no_git_repos")) return nil } - // QUERY git status - result, handled, err := bundle.Core.QUERY(git.QueryStatus{ + // Query git status directly + statuses := git.Status(ctx, git.StatusOptions{ Paths: paths, Names: names, }) - if !handled { - return cli.Err("git service not available") - } - if err != nil { - return err - } - statuses := result.([]git.RepoStatus) // Sort by repo name for consistent output slices.SortFunc(statuses, func(a, b git.RepoStatus) int { @@ -125,15 +110,7 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { cli.Blank() for _, s := range dirtyRepos { - // PERFORM commit via agentic service - _, handled, err := bundle.Core.PERFORM(agentic.TaskCommit{ - Path: s.Path, - Name: s.Name, - }) - if !handled { - cli.Print(" %s %s: %s\n", warningStyle.Render("!"), s.Name, "agentic service not available") - continue - } + err := doCommit(ctx, s.Path, false) if err != nil { cli.Print(" %s %s: %s\n", errorStyle.Render("x"), s.Name, err) } else { @@ -141,12 +118,11 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { } } - // Re-QUERY status after commits - result, _, _ = bundle.Core.QUERY(git.QueryStatus{ + // Re-query status after commits + statuses = git.Status(ctx, git.StatusOptions{ Paths: paths, Names: names, }) - statuses = result.([]git.RepoStatus) // Rebuild ahead repos list aheadRepos = nil @@ -187,18 +163,11 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { cli.Blank() - // PERFORM push for each repo + // Push each repo directly var divergedRepos []git.RepoStatus for _, s := range aheadRepos { - _, handled, err := bundle.Core.PERFORM(git.TaskPush{ - Path: s.Path, - Name: s.Name, - }) - if !handled { - cli.Print(" %s %s: %s\n", errorStyle.Render("x"), s.Name, "git service not available") - continue - } + err := git.Push(ctx, s.Path) if err != nil { if git.IsNonFastForward(err) { cli.Print(" %s %s: %s\n", warningStyle.Render("!"), s.Name, i18n.T("cmd.dev.push.diverged")) @@ -220,8 +189,8 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { for _, s := range divergedRepos { cli.Print(" %s %s...\n", dimStyle.Render("↓"), s.Name) - // PERFORM pull - _, _, err := bundle.Core.PERFORM(git.TaskPull{Path: s.Path, Name: s.Name}) + // Pull directly + err := git.Pull(ctx, s.Path) if err != nil { cli.Print(" %s %s: %s\n", errorStyle.Render("x"), s.Name, err) continue @@ -229,8 +198,8 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { cli.Print(" %s %s...\n", dimStyle.Render("↑"), s.Name) - // PERFORM push - _, _, err = bundle.Core.PERFORM(git.TaskPush{Path: s.Path, Name: s.Name}) + // Push directly + err = git.Push(ctx, s.Path) if err != nil { cli.Print(" %s %s: %s\n", errorStyle.Render("x"), s.Name, err) continue @@ -318,28 +287,3 @@ func printStatusTable(statuses []git.RepoStatus) { } } -// claudeCommit shells out to claude for committing (legacy helper for other commands) -func claudeCommit(ctx context.Context, repoPath, repoName, registryPath string) error { - prompt := agentic.Prompt("commit") - - cmd := exec.CommandContext(ctx, "claude", "-p", prompt, "--allowedTools", "Bash,Read,Glob,Grep") - cmd.Dir = repoPath - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - - return cmd.Run() -} - -// claudeEditCommit shells out to claude with edit permissions (legacy helper) -func claudeEditCommit(ctx context.Context, repoPath, repoName, registryPath string) error { - prompt := agentic.Prompt("commit") - - cmd := exec.CommandContext(ctx, "claude", "-p", prompt, "--allowedTools", "Bash,Read,Write,Edit,Glob,Grep") - cmd.Dir = repoPath - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - - return cmd.Run() -} diff --git a/cmd/dev/service.go b/cmd/dev/service.go index 64e6cd4..272a6e1 100644 --- a/cmd/dev/service.go +++ b/cmd/dev/service.go @@ -1,32 +1,14 @@ package dev import ( - "cmp" "context" - "slices" - "strings" + "os" + "os/exec" - "forge.lthn.ai/core/cli/pkg/cli" + "dappco.re/go/core" agentic "forge.lthn.ai/core/agent/pkg/lifecycle" - "forge.lthn.ai/core/go-scm/git" - "forge.lthn.ai/core/go/pkg/core" ) -// Tasks for dev service - -// TaskWork runs the full dev workflow: status, commit, push. -type TaskWork struct { - RegistryPath string - StatusOnly bool - AutoCommit bool - AutoPush bool -} - -// TaskStatus displays git status for all repos. -type TaskStatus struct { - RegistryPath string -} - // ServiceOptions for configuring the dev service. type ServiceOptions struct { RegistryPath string @@ -37,256 +19,24 @@ type Service struct { *core.ServiceRuntime[ServiceOptions] } -// NewService creates a dev service factory. -func NewService(opts ServiceOptions) func(*core.Core) (any, error) { - return func(c *core.Core) (any, error) { - return &Service{ - ServiceRuntime: core.NewServiceRuntime(c, opts), - }, nil - } +func (s *Service) handleTask(_ *core.Core, _ core.Task) core.Result { + return core.Result{} } -// OnStartup registers task handlers. -func (s *Service) OnStartup(ctx context.Context) error { - s.Core().RegisterTask(s.handleTask) - return nil -} - -func (s *Service) handleTask(c *core.Core, t core.Task) (any, bool, error) { - switch m := t.(type) { - case TaskWork: - err := s.runWork(m) - return nil, true, err - - case TaskStatus: - err := s.runStatus(m) - return nil, true, err - } - return nil, false, nil -} - -func (s *Service) runWork(task TaskWork) error { - // Load registry - paths, names, err := s.loadRegistry(task.RegistryPath) - if err != nil { - return err - } - - if len(paths) == 0 { - cli.Println("No git repositories found") - return nil - } - - // QUERY git status - result, handled, err := s.Core().QUERY(git.QueryStatus{ - Paths: paths, - Names: names, - }) - if !handled { - return cli.Err("git service not available") - } - if err != nil { - return err - } - statuses := result.([]git.RepoStatus) - - // Sort by name - slices.SortFunc(statuses, func(a, b git.RepoStatus) int { - return cmp.Compare(a.Name, b.Name) - }) - - // Display status table - s.printStatusTable(statuses) - - // Collect dirty and ahead repos - var dirtyRepos []git.RepoStatus - var aheadRepos []git.RepoStatus - - for _, st := range statuses { - if st.Error != nil { - continue - } - if st.IsDirty() { - dirtyRepos = append(dirtyRepos, st) - } - if st.HasUnpushed() { - aheadRepos = append(aheadRepos, st) - } - } - - // Auto-commit dirty repos if requested - if task.AutoCommit && len(dirtyRepos) > 0 { - cli.Blank() - cli.Println("Committing changes...") - cli.Blank() - - for _, repo := range dirtyRepos { - _, handled, err := s.Core().PERFORM(agentic.TaskCommit{ - Path: repo.Path, - Name: repo.Name, - }) - if !handled { - // Agentic service not available - skip silently - cli.Print(" - %s: agentic service not available\n", repo.Name) - continue - } - if err != nil { - cli.Print(" x %s: %s\n", repo.Name, err) - } else { - cli.Print(" v %s\n", repo.Name) - } - } - - // Re-query status after commits - result, _, _ = s.Core().QUERY(git.QueryStatus{ - Paths: paths, - Names: names, - }) - statuses = result.([]git.RepoStatus) - - // Rebuild ahead repos list - aheadRepos = nil - for _, st := range statuses { - if st.Error == nil && st.HasUnpushed() { - aheadRepos = append(aheadRepos, st) - } - } - } - - // If status only, we're done - if task.StatusOnly { - if len(dirtyRepos) > 0 && !task.AutoCommit { - cli.Blank() - cli.Println("Use --commit flag to auto-commit dirty repos") - } - return nil - } - - // Push repos with unpushed commits - if len(aheadRepos) == 0 { - cli.Blank() - cli.Println("All repositories are up to date") - return nil - } - - cli.Blank() - cli.Print("%d repos with unpushed commits:\n", len(aheadRepos)) - for _, st := range aheadRepos { - cli.Print(" %s: %d commits\n", st.Name, st.Ahead) - } - - if !task.AutoPush { - cli.Blank() - cli.Print("Push all? [y/N] ") - var answer string - _, _ = cli.Scanln(&answer) - if strings.ToLower(answer) != "y" { - cli.Println("Aborted") - return nil - } - } - - cli.Blank() - - // Push each repo - for _, st := range aheadRepos { - _, handled, err := s.Core().PERFORM(git.TaskPush{ - Path: st.Path, - Name: st.Name, - }) - if !handled { - cli.Print(" x %s: git service not available\n", st.Name) - continue - } - if err != nil { - if git.IsNonFastForward(err) { - cli.Print(" ! %s: branch has diverged\n", st.Name) - } else { - cli.Print(" x %s: %s\n", st.Name, err) - } - } else { - cli.Print(" v %s\n", st.Name) - } - } - - return nil -} - -func (s *Service) runStatus(task TaskStatus) error { - paths, names, err := s.loadRegistry(task.RegistryPath) - if err != nil { - return err - } - - if len(paths) == 0 { - cli.Println("No git repositories found") - return nil - } - - result, handled, err := s.Core().QUERY(git.QueryStatus{ - Paths: paths, - Names: names, - }) - if !handled { - return cli.Err("git service not available") - } - if err != nil { - return err - } - - statuses := result.([]git.RepoStatus) - slices.SortFunc(statuses, func(a, b git.RepoStatus) int { - return cmp.Compare(a.Name, b.Name) - }) - - s.printStatusTable(statuses) - return nil -} - -func (s *Service) loadRegistry(registryPath string) ([]string, map[string]string, error) { - reg, _, err := loadRegistryWithConfig(registryPath) - if err != nil { - return nil, nil, err - } - - var paths []string - names := make(map[string]string) - - for _, repo := range reg.List() { - if repo.IsGitRepo() { - paths = append(paths, repo.Path) - names[repo.Path] = repo.Name - } - } - - return paths, names, nil -} - -func (s *Service) printStatusTable(statuses []git.RepoStatus) { - // Calculate column widths - nameWidth := 4 // "Repo" - for _, st := range statuses { - if len(st.Name) > nameWidth { - nameWidth = len(st.Name) - } - } - - // Print header - cli.Print("%-*s %8s %9s %6s %5s\n", - nameWidth, "Repo", "Modified", "Untracked", "Staged", "Ahead") - - // Print separator - cli.Text(strings.Repeat("-", nameWidth+2+10+11+8+7)) - - // Print rows - for _, st := range statuses { - if st.Error != nil { - cli.Print("%-*s error: %s\n", nameWidth, st.Name, st.Error) - continue - } - - cli.Print("%-*s %8d %9d %6d %5d\n", - nameWidth, st.Name, - st.Modified, st.Untracked, st.Staged, st.Ahead) - } +// doCommit shells out to claude for AI-assisted commit. +func doCommit(ctx context.Context, repoPath string, allowEdit bool) error { + prompt := agentic.Prompt("commit") + + tools := "Bash,Read,Glob,Grep" + if allowEdit { + tools = "Bash,Read,Write,Edit,Glob,Grep" + } + + cmd := exec.CommandContext(ctx, "claude", "-p", prompt, "--allowedTools", tools) + cmd.Dir = repoPath + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + + return cmd.Run() } diff --git a/go.mod b/go.mod index c75452c..e6beb04 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.26.0 require ( code.gitea.io/sdk/gitea v0.23.2 - forge.lthn.ai/core/agent v0.3.2 - forge.lthn.ai/core/cli v0.3.5 - forge.lthn.ai/core/go v0.3.1 - forge.lthn.ai/core/go-container v0.1.5 - forge.lthn.ai/core/go-i18n v0.1.6 - forge.lthn.ai/core/go-io v0.1.5 + dappco.re/go/core v0.4.7 + forge.lthn.ai/core/agent v0.3.3 + forge.lthn.ai/core/cli v0.3.7 + forge.lthn.ai/core/go-container v0.1.7 + forge.lthn.ai/core/go-i18n v0.1.7 + forge.lthn.ai/core/go-io v0.1.7 forge.lthn.ai/core/go-log v0.0.4 - forge.lthn.ai/core/go-scm v0.3.4 + forge.lthn.ai/core/go-scm v0.3.6 github.com/kluctl/go-embed-python v0.0.0-3.13.1-20241219-1 github.com/stretchr/testify v1.11.1 golang.org/x/term v0.41.0 @@ -21,9 +21,10 @@ require ( require ( codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2 v2.2.0 // indirect - forge.lthn.ai/core/config v0.1.6 // indirect - forge.lthn.ai/core/go-inference v0.1.5 // indirect - forge.lthn.ai/core/go-store v0.1.8 // indirect + forge.lthn.ai/core/config v0.1.8 // indirect + forge.lthn.ai/core/go v0.3.3 // indirect + forge.lthn.ai/core/go-inference v0.1.6 // indirect + forge.lthn.ai/core/go-store v0.1.9 // indirect github.com/42wim/httpsig v1.2.3 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -77,5 +78,5 @@ require ( modernc.org/libc v1.70.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.46.2 // indirect + modernc.org/sqlite v1.47.0 // indirect ) diff --git a/go.sum b/go.sum index 03c5d20..1f1d7ba 100644 --- a/go.sum +++ b/go.sum @@ -2,28 +2,30 @@ code.gitea.io/sdk/gitea v0.23.2 h1:iJB1FDmLegwfwjX8gotBDHdPSbk/ZR8V9VmEJaVsJYg= code.gitea.io/sdk/gitea v0.23.2/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2 v2.2.0 h1:HTCWpzyWQOHDWt3LzI6/d2jvUDsw/vgGRWm/8BTvcqI= codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2 v2.2.0/go.mod h1:ZglEEDj+qkxYUb+SQIeqGtFxQrbaMYqIOgahNKb7uxs= -forge.lthn.ai/core/agent v0.3.2 h1:KMtHpQl28PGaulrsoysS6szEiklKK8aDiGzHMWAI1ms= -forge.lthn.ai/core/agent v0.3.2/go.mod h1:Yf7m03wD0mogHouV7tDEZVHbq4jGJOf67tNjbhd6P6M= -forge.lthn.ai/core/cli v0.3.5 h1:P7yK0DmSA1QnUMFuCjJZf/fk/akKPIxopQ6OwD8Sar8= -forge.lthn.ai/core/cli v0.3.5/go.mod h1:SeArHx+hbpX5iZqgASCD7Q1EDoc6uaaGiGBotmNzIx4= -forge.lthn.ai/core/config v0.1.6 h1:TSynnKJpoXpvsS//TSnwVH31GyMJF/lbT/oIiMaODNk= -forge.lthn.ai/core/config v0.1.6/go.mod h1:AIm7VlO/h4s1LmGSn0HZb+RqAbhmZFJppVGivcsJmGE= -forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= -forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= -forge.lthn.ai/core/go-container v0.1.5 h1:EWSg0nlMeeGV+KQenRn8XSqJBu2VHdafELIuvFwregc= -forge.lthn.ai/core/go-container v0.1.5/go.mod h1:WdG6PMdscBhUj1AV/Sur4Zc+VakQRN2ejOmLCpaggcg= -forge.lthn.ai/core/go-i18n v0.1.6 h1:Z9h6sEZsgJmWlkkq3ZPZyfgWipeeqN5lDCpzltpamHU= -forge.lthn.ai/core/go-i18n v0.1.6/go.mod h1:C6CbwdN7sejTx/lbutBPrxm77b8paMHBO6uHVLHOdqQ= -forge.lthn.ai/core/go-inference v0.1.5 h1:Az/Euv1DusJQJz/Eca0Ey7sVXQkFLPHW0TBrs9g+Qwg= -forge.lthn.ai/core/go-inference v0.1.5/go.mod h1:jfWz+IJX55wAH98+ic6FEqqGB6/P31CHlg7VY7pxREw= -forge.lthn.ai/core/go-io v0.1.5 h1:+XJ1YhaGGFLGtcNbPtVlndTjk+pO0Ydi2hRDj5/cHOM= -forge.lthn.ai/core/go-io v0.1.5/go.mod h1:FRtXSsi8W+U9vewCU+LBAqqbIj3wjXA4dBdSv3SAtWI= +dappco.re/go/core v0.4.7 h1:KmIA/2lo6rl1NMtLrKqCWfMlUqpDZYH3q0/d10dTtGA= +dappco.re/go/core v0.4.7/go.mod h1:f2/tBZ3+3IqDrg2F5F598llv0nmb/4gJVCFzM5geE4A= +forge.lthn.ai/core/agent v0.3.3 h1:lGpoD5OgvdJ5z+qofw8fBWkDB186QM7I2jjXEbtzSdA= +forge.lthn.ai/core/agent v0.3.3/go.mod h1:UnrGApmKd/GzHEFcgy/tYuSfeJwxRx8UsxPhTjU5Ntw= +forge.lthn.ai/core/cli v0.3.7 h1:1GrbaGg0wDGHr6+klSbbGyN/9sSbHvFbdySJznymhwg= +forge.lthn.ai/core/cli v0.3.7/go.mod h1:DBUppJkA9P45ZFGgI2B8VXw1rAZxamHoI/KG7fRvTNs= +forge.lthn.ai/core/config v0.1.8 h1:xP2hys7T94QGVF/OTh84/Zr5Dm/dL/0vzjht8zi+LOg= +forge.lthn.ai/core/config v0.1.8/go.mod h1:8epZrkwoCt+5ayrqdinOUU/+w6UoxOyv9ZrdgVOgYfQ= +forge.lthn.ai/core/go v0.3.3 h1:kYYZ2nRYy0/Be3cyuLJspRjLqTMxpckVyhb/7Sw2gd0= +forge.lthn.ai/core/go v0.3.3/go.mod h1:Cp4ac25pghvO2iqOu59t1GyngTKVOzKB5/VPdhRi9CQ= +forge.lthn.ai/core/go-container v0.1.7 h1:+/6NIu7OWyK2LSi2obnFF5fVpWhKiWduMiEkmnbZS6U= +forge.lthn.ai/core/go-container v0.1.7/go.mod h1:k0z4yhfZC05bYB5ANdpDFC3AcefnOWJvosXSBSydjs4= +forge.lthn.ai/core/go-i18n v0.1.7 h1:aHkAoc3W8fw3RPNvw/UszQbjyFWXHszzbZgty3SwyAA= +forge.lthn.ai/core/go-i18n v0.1.7/go.mod h1:0VDjwtY99NSj2iqwrI09h5GUsJeM9s48MLkr+/Dn4G8= +forge.lthn.ai/core/go-inference v0.1.6 h1:ce42zC0zO8PuISUyAukAN1NACEdWp5wF1mRgnh5+58E= +forge.lthn.ai/core/go-inference v0.1.6/go.mod h1:jfWz+IJX55wAH98+ic6FEqqGB6/P31CHlg7VY7pxREw= +forge.lthn.ai/core/go-io v0.1.7 h1:Tdb6sqh+zz1lsGJaNX9RFWM6MJ/RhSAyxfulLXrJsbk= +forge.lthn.ai/core/go-io v0.1.7/go.mod h1:8lRLFk4Dnp5cR/Cyzh9WclD5566TbpdRgwcH7UZLWn4= forge.lthn.ai/core/go-log v0.0.4 h1:KTuCEPgFmuM8KJfnyQ8vPOU1Jg654W74h8IJvfQMfv0= forge.lthn.ai/core/go-log v0.0.4/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= -forge.lthn.ai/core/go-scm v0.3.4 h1:McZvp2gI3wEPCF/jim8O4F1+Vp477N81TUiiklTq5hw= -forge.lthn.ai/core/go-scm v0.3.4/go.mod h1:AOrx4CEmV8/Q73Cvd2LkbFniYGpk46mticpYmK5MnJA= -forge.lthn.ai/core/go-store v0.1.8 h1:jeFqxilifa/hXtQqCeXX/+Vwy6M/XZE7uCP8XQ0ercw= -forge.lthn.ai/core/go-store v0.1.8/go.mod h1:DJocTeTCjFBPn5ppQT/IDheFJhOfwlHeoxEUtDH07zE= +forge.lthn.ai/core/go-scm v0.3.6 h1:LFNx8Fs82mrpxro/MPUM6tMiD4DqPmdu83UknXztQjc= +forge.lthn.ai/core/go-scm v0.3.6/go.mod h1:IWFIYDfRH0mtRdqY5zV06l/RkmkPpBM6FcbKWhg1Qa8= +forge.lthn.ai/core/go-store v0.1.9 h1:DGO2sUo2i/csWbhw7zxU7oyGF2FJT72/8w47GhZ1joM= +forge.lthn.ai/core/go-store v0.1.9/go.mod h1:VNnHh94TMD3+L+sSgvxn0GHtDKhJR8FD6JiuIuRtjuk= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -143,8 +145,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= -github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -206,8 +208,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.46.2 h1:gkXQ6R0+AjxFC/fTDaeIVLbNLNrRoOK7YYVz5BKhTcE= -modernc.org/sqlite v1.46.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= +modernc.org/sqlite v1.47.0 h1:R1XyaNpoW4Et9yly+I2EeX7pBza/w+pmYee/0HJDyKk= +modernc.org/sqlite v1.47.0/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=