feat(brain): cross-wing tunnels — bidirectional wikilinks + auto-detect
Adds the `brain_tunnel` MCP tool and auto-tunnel behaviour for `brain_write`, so concepts that appear in multiple wings become navigable from any of them. New surface in package brain: - WriteTunnel(brainDir, src, tgt) — appends a `## See also` bidirectional wikilink between two notes in different wings. Idempotent (link not duplicated on re-call) and reuses an existing See also section. - DetectTunnels(brainDir, content) — walks brain/wiki/, returns TunnelCandidates for notes whose title appears in content. Tags whole-word case-insensitive hits as Exact=true and substring-only hits as Exact=false. - AutoTunnel(brainDir, src, content) — wraps DetectTunnels: writes cross-wing exact matches, stages fuzzy matches into brain/raw/tunnel-candidates-<YYYY-MM-DD>.md for human review. MCP wiring: - `brain_tunnel` tool: explicit manual link (source, target). - `brain_write` with wing+hall now triggers AutoTunnel on the new content. Failures are logged and never abort the primary write. readTitleAndCreated also humanises the slug fallback (hyphens → spaces) so titleless notes participate in content matching. Closes hyperguild#16. Tests: idempotency, same-wing rejection, missing-note rejection, See-also reuse, exact/fuzzy detection, slug fallback, MCP tool happy path, auto-tunnel hook (cross-wing exact → linked; same-wing → skipped; fuzzy → candidates file).
This commit is contained in:
@@ -55,7 +55,8 @@ func TestServerToolsList(t *testing.T) {
|
||||
names = append(names, t.(map[string]any)["name"].(string))
|
||||
}
|
||||
assert.ElementsMatch(t, []string{
|
||||
"brain_query", "brain_write", "brain_index", "brain_ingest_raw", "brain_ingest",
|
||||
"brain_query", "brain_write", "brain_index", "brain_tunnel",
|
||||
"brain_ingest_raw", "brain_ingest",
|
||||
"brain_answer", "brain_classify", "session_log",
|
||||
}, names)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user