mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-03 20:13:03 +00:00
update
This commit is contained in:
+78
-26
@@ -1,25 +1,32 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yourorg/devour/internal/scraper"
|
||||
"github.com/yourorg/devour/internal/search"
|
||||
"github.com/yourorg/devour/internal/storage"
|
||||
)
|
||||
|
||||
var pushCmd = &cobra.Command{
|
||||
Use: "push <path>",
|
||||
Short: "Push documents to remote MCP server",
|
||||
Long: `Push local documents to a remote Devour MCP server.
|
||||
Short: "Import local documents into Devour storage/index",
|
||||
Long: `Push local documents into your Devour local workspace.
|
||||
|
||||
Useful for:
|
||||
- Syncing local documentation to a shared server
|
||||
- Backing up indexed content
|
||||
- Contributing to a team knowledge base
|
||||
Current stable behavior:
|
||||
- local ingest into docs storage
|
||||
- local reindex for query/ask/status
|
||||
|
||||
Remote push is experimental and not enabled by default.
|
||||
|
||||
Examples:
|
||||
devour push ./docs
|
||||
devour push ./docs --server http://devour.company.com
|
||||
devour push ./docs --server http://localhost:8080 --project my-project`,
|
||||
devour push ./docs --project my-project`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: runPush,
|
||||
}
|
||||
@@ -30,33 +37,78 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
pushCmd.Flags().StringVar(&pushServer, "server", "", "remote Devour server URL")
|
||||
pushCmd.Flags().StringVarP(&pushProject, "project", "p", "", "project name on remote server")
|
||||
pushCmd.Flags().StringVar(&pushServer, "server", "", "remote Devour server URL (experimental)")
|
||||
pushCmd.Flags().StringVarP(&pushProject, "project", "p", "", "project name label")
|
||||
}
|
||||
|
||||
func runPush(cmd *cobra.Command, args []string) error {
|
||||
path := args[0]
|
||||
|
||||
if pushServer == "" {
|
||||
// Try to get from config
|
||||
pushServer = "http://localhost:8080"
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return fmt.Errorf("path does not exist: %s", path)
|
||||
}
|
||||
|
||||
fmt.Printf("📤 Pushing to: %s\n", pushServer)
|
||||
fmt.Printf(" Path: %s\n", path)
|
||||
if pushProject != "" {
|
||||
fmt.Printf(" Project: %s\n", pushProject)
|
||||
cfg, err := loadAppConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Implement actual push logic
|
||||
// 1. Scan path for documents
|
||||
// 2. Connect to remote server
|
||||
// 3. Upload documents
|
||||
// 4. Wait for indexing confirmation
|
||||
server := strings.TrimSpace(pushServer)
|
||||
if server != "" && !isLocalServer(server) {
|
||||
return fmt.Errorf("remote push is experimental and not enabled in this build; use local push without --server")
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("⚠️ Push functionality not yet implemented")
|
||||
fmt.Println(" Remote server support coming soon")
|
||||
projectName := strings.TrimSpace(pushProject)
|
||||
if projectName == "" {
|
||||
projectName = "local-push"
|
||||
}
|
||||
|
||||
fmt.Printf("📤 Ingesting local docs from: %s\n", path)
|
||||
fmt.Printf(" Project: %s\n", projectName)
|
||||
fmt.Printf(" Target docs dir: %s\n", cfg.Storage.DocsDir)
|
||||
|
||||
s := scraper.NewScraper(scraper.SourceTypeLocal, toScraperConfig(cfg, 0))
|
||||
if s == nil {
|
||||
return fmt.Errorf("local scraper not available")
|
||||
}
|
||||
|
||||
docs, err := s.Scrape(context.Background(), &scraper.Source{
|
||||
Name: projectName,
|
||||
Type: scraper.SourceTypeLocal,
|
||||
Path: path,
|
||||
Include: []string{`.*`},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("local ingest failed: %w", err)
|
||||
}
|
||||
|
||||
saved, err := storage.SaveDocuments(docs, storage.SaveOptions{
|
||||
Format: "json",
|
||||
OutputDir: cfg.Storage.DocsDir,
|
||||
AllowEmpty: false,
|
||||
PrintWriter: nil,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("save docs failed: %w", err)
|
||||
}
|
||||
|
||||
engine := search.NewEngine(cfg)
|
||||
stats, err := engine.Rebuild(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("reindex failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("\n✓ Push complete")
|
||||
fmt.Printf(" Documents imported: %d\n", saved.Count)
|
||||
fmt.Printf(" Index docs: %d\n", stats.Documents)
|
||||
fmt.Printf(" Index path: %s\n", stats.IndexPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func isLocalServer(raw string) bool {
|
||||
u, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
host := strings.ToLower(u.Hostname())
|
||||
return host == "" || host == "localhost" || host == "127.0.0.1"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user