diff --git a/pkg/agentic/brain_seed_memory.go b/pkg/agentic/brain_seed_memory.go index 2935fc7..7de0ea7 100644 --- a/pkg/agentic/brain_seed_memory.go +++ b/pkg/agentic/brain_seed_memory.go @@ -90,7 +90,7 @@ func (s *PrepSubsystem) cmdBrainSeedMemoryLike(options core.Options, commandName } if output.Files == 0 { - core.Print(nil, "No MEMORY.md files found in: %s", output.Path) + core.Print(nil, "No markdown memory files found in: %s", output.Path) return core.Result{Value: output, OK: true} } @@ -243,8 +243,22 @@ func brainSeedMemoryFiles(scanPath string) []string { } } + if fs.IsFile(scanPath) { + if brainSeedMemoryFile(scanPath) { + add(scanPath) + } + sort.Strings(files) + return files + } + if brainSeedMemoryHasGlobMeta(scanPath) { for _, path := range core.PathGlob(scanPath) { + if fs.IsFile(path) { + if brainSeedMemoryFile(path) { + add(path) + } + continue + } walk(path) } } else { @@ -258,6 +272,10 @@ func brainSeedMemoryHasGlobMeta(path string) bool { return core.Contains(path, "*") || core.Contains(path, "?") || core.Contains(path, "[") } +func brainSeedMemoryFile(path string) bool { + return core.PathBase(path) == "MEMORY.md" || core.Lower(core.PathExt(path)) == ".md" +} + func brainSeedMemorySections(content string) []brainSeedMemorySection { lines := core.Split(content, "\n") var sections []brainSeedMemorySection diff --git a/pkg/agentic/brain_seed_memory_test.go b/pkg/agentic/brain_seed_memory_test.go index 5b8f837..c64384c 100644 --- a/pkg/agentic/brain_seed_memory_test.go +++ b/pkg/agentic/brain_seed_memory_test.go @@ -156,6 +156,48 @@ func TestBrainSeedMemory_CmdBrainIngest_Good(t *testing.T) { assert.Equal(t, "architecture", bodies[0]["type"]) } +func TestBrainSeedMemory_CmdBrainSeedMemory_Good_DirectMarkdownFile(t *testing.T) { + home := t.TempDir() + t.Setenv("CORE_HOME", home) + + memoryFile := core.JoinPath(home, "notes.md") + require.True(t, fs.Write(memoryFile, "# Memory\n\n## Convention\nUse named actions.\n").OK) + + var bodies []map[string]any + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "/v1/brain/remember", r.URL.Path) + bodyResult := core.ReadAll(r.Body) + require.True(t, bodyResult.OK) + var payload map[string]any + require.True(t, core.JSONUnmarshalString(bodyResult.Value.(string), &payload).OK) + bodies = append(bodies, payload) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"success":true,"memory":{"id":"mem-1"}}`)) + })) + defer srv.Close() + + subsystem := &PrepSubsystem{ + brainURL: srv.URL, + brainKey: "brain-key", + } + + result := subsystem.cmdBrainSeedMemory(core.NewOptions( + core.Option{Key: "workspace", Value: "42"}, + core.Option{Key: "path", Value: memoryFile}, + )) + + require.True(t, result.OK) + output, ok := result.Value.(BrainSeedMemoryOutput) + require.True(t, ok) + assert.Equal(t, 1, output.Files) + assert.Equal(t, 1, output.Imported) + assert.Equal(t, 0, output.Skipped) + assert.Equal(t, memoryFile, output.Path) + require.Len(t, bodies, 1) + assert.Equal(t, "convention", bodies[0]["type"]) + assert.Contains(t, bodies[0]["content"].(string), "Use named actions.") +} + func TestBrainSeedMemory_CmdBrainSeedMemory_Bad_MissingWorkspace(t *testing.T) { subsystem := &PrepSubsystem{brainURL: "https://example.com", brainKey: "brain-key"}