Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/analyze/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func GetGraph(ctx context.Context, cfg *config.Config, dir string, force bool) (

client := api.New(cfg)
spin = ui.Start("Uploading and analyzing repository…")
ir, err := client.AnalyzeShards(ctx, zipPath, "analyze-"+hash[:16])
ir, err := client.AnalyzeShards(ctx, zipPath, "analyze-"+hash[:16], nil)
spin.Stop()
if err != nil {
return nil, hash, err
Expand Down
20 changes: 18 additions & 2 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"time"
Expand Down Expand Up @@ -115,11 +116,26 @@ func (c *Client) pollLoop(ctx context.Context, post func() (*JobResponse, error)
return job, nil
}

// PreviousDomain holds domain name + subdomain count for seeding the LLM prompt.
type PreviousDomain struct {
Name string `json:"name"`
SubdomainCount int `json:"subdomainCount"`
}

// AnalyzeShards uploads a repository ZIP and runs the full analysis pipeline,
// returning the complete ShardIR response with full Node/Relationship data
// required for sidecar rendering (IDs, labels, properties preserved).
func (c *Client) AnalyzeShards(ctx context.Context, zipPath, idempotencyKey string) (*ShardIR, error) {
job, err := c.pollUntilComplete(ctx, zipPath, idempotencyKey)
// If previousDomains is non-nil, passes them as a query param to seed domain names.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix comment mismatch on the trigger condition.

Line 128 says "non-nil", but the code sends previousDomains only when the slice is non-empty (len(previousDomains) > 0). That wording can mislead future readers.

✏️ Suggested doc fix
-// If previousDomains is non-nil, passes them as a query param to seed domain names.
+// If previousDomains is non-empty, passes them as a query param to seed domain names.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If previousDomains is non-nil, passes them as a query param to seed domain names.
// If previousDomains is non-empty, passes them as a query param to seed domain names.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/api/client.go` at line 128, Update the comment that currently reads
"If previousDomains is non-nil, passes them as a query param to seed domain
names." to accurately reflect the actual trigger used in the code: only send
previousDomains when the slice has elements (len(previousDomains) > 0). Locate
the comment near the code that checks previousDomains and sends it as a query
parameter (look for the previousDomains variable and the conditional that builds
the query) and change the wording to mention "non-empty slice" or
"len(previousDomains) > 0" so it matches the implementation.

func (c *Client) AnalyzeShards(ctx context.Context, zipPath, idempotencyKey string, previousDomains []PreviousDomain) (*ShardIR, error) {
endpoint := analyzeEndpoint
if len(previousDomains) > 0 {
pd, err := json.Marshal(previousDomains)
if err == nil {
endpoint += "?previousDomains=" + url.QueryEscape(string(pd))
}
}
post := func() (*JobResponse, error) { return c.postZipTo(ctx, zipPath, idempotencyKey, endpoint) }
job, err := c.pollLoop(ctx, post)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/shards/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func (d *Daemon) fullGenerate(ctx context.Context) error {
}
defer os.Remove(zipPath)

ir, err := d.client.AnalyzeShards(ctx, zipPath, idemKey)
ir, err := d.client.AnalyzeShards(ctx, zipPath, idemKey, nil)
if err != nil {
return err
}
Expand Down Expand Up @@ -251,7 +251,7 @@ func (d *Daemon) incrementalUpdate(ctx context.Context, changedFiles []string) {
}
defer os.Remove(zipPath)

ir, err := d.client.AnalyzeShards(ctx, zipPath, "incremental-"+idemKey[:8])
ir, err := d.client.AnalyzeShards(ctx, zipPath, "incremental-"+idemKey[:8], nil)
if err != nil {
d.logf("Incremental API error: %v", err)
return
Expand Down
16 changes: 15 additions & 1 deletion internal/shards/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,25 @@ func Generate(ctx context.Context, cfg *config.Config, dir string, opts Generate
}
defer os.Remove(zipPath)

// Read previous domains from cache for LLM seeding (stabilizes names across refreshes)
var prevDomains []api.PreviousDomain
if data, readErr := os.ReadFile(cacheFile); readErr == nil {
var prev api.ShardIR
if json.Unmarshal(data, &prev) == nil && len(prev.Domains) > 0 {
for _, d := range prev.Domains {
prevDomains = append(prevDomains, api.PreviousDomain{
Name: d.Name,
SubdomainCount: len(d.Subdomains),
})
}
}
}

client := api.New(cfg)
idemKey := newUUID()

spin = ui.Start("Uploading and analyzing repository…")
ir, err := client.AnalyzeShards(ctx, zipPath, "shards-"+idemKey[:8])
ir, err := client.AnalyzeShards(ctx, zipPath, "shards-"+idemKey[:8], prevDomains)
spin.Stop()
if err != nil {
return err
Expand Down
Loading