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:
@@ -1,6 +1,6 @@
|
||||
// Package mcp implements an MCP HTTP handler for the ingestion service.
|
||||
// Exposed tools: brain_query, brain_write, brain_index, brain_ingest,
|
||||
// brain_ingest_raw, brain_answer, brain_classify, session_log.
|
||||
// Exposed tools: brain_query, brain_write, brain_index, brain_tunnel,
|
||||
// brain_ingest, brain_ingest_raw, brain_answer, brain_classify, session_log.
|
||||
package mcp
|
||||
|
||||
import (
|
||||
@@ -139,6 +139,8 @@ func (s *Server) handleCall(ctx context.Context, name string, args json.RawMessa
|
||||
return s.brainWrite(ctx, args)
|
||||
case "brain_index":
|
||||
return s.brainIndex(ctx, args)
|
||||
case "brain_tunnel":
|
||||
return s.brainTunnel(ctx, args)
|
||||
case "brain_ingest_raw":
|
||||
return s.brainIngestRaw(ctx, args)
|
||||
case "brain_ingest":
|
||||
|
||||
Reference in New Issue
Block a user