- app.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.3 KiB
name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url, params, output
| name | lang | domain | version | description | tags | uses_functions | uses_types | framework | entry_point | dir_path | repo_url | params | output | |||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fn_match | go | infra | 0.1.0 | Fuzzy matcher entre un comando shell o snippet heredoc y funciones del registry. Devuelve las top-N funciones mas probables que cubren ese patron, con score normalizado. Consumido por el hook PreToolUse para sugerir funciones del registry en vez de codigo inline. |
|
cmd/fn/match.go | apps/fn_match |
|
JSON o texto con las top-N funciones del registry ordenadas por score descendente. Score 1.0 = mejor match; resto son relativos al top. |
Ejemplo
# Arg posicional — JSON por defecto
./fn match "taskkill.exe /IM registry_dashboard.exe /F"
# Texto legible
./fn match --format text --top 5 "rsync -avz src/ user@host:/opt/app"
# Stdin pipe (util en hooks)
echo "curl -sf https://api.example.com/health | jq .status" | ./fn match
# Subir umbral para matches muy seguros solamente
./fn match --min-score 0.7 "encrypt file sha256"
Salida JSON:
{
"query": "taskkill.exe /IM registry_dashboard.exe /F",
"top": [
{
"id": "deploy_cpp_exe_to_windows_bash_infra",
"score": 1,
"signature": "deploy_cpp_exe_to_windows(app_name: string, app_dir: string) -> void",
"snippet": "Copia el .exe de Windows... Mata el proceso si esta corriendo (taskkill.exe pre-autorizado)..."
}
],
"high_confidence": false
}
Cuando usarla
Hook PreToolUse (uso principal): El hook intercepta comandos Bash antes de ejecutarse. Si el comando supera el umbral de score, el hook inyecta en el contexto:
USE: deploy_cpp_exe_to_windows_bash_infra [score=1.000] instead of inline
Debug manual: Para entender por que Claude escribe cierto patron inline repetidamente, correr fn match con ese patron y ver si el registry ya cubre el caso.
Auditoria de gaps: Si fn match devuelve top: [] para un patron que aparece >3 veces en sesiones, ese patron es candidato a nueva funcion del registry.
Pipeline interno
- Tokenize: split por no-alfanumericos + eliminacion de flags (
-v,/F), paths absolutos (conserva basename sin extension), numeros puros, tokens < 3 chars, y stopwords del dominio (registry,function,app,file,get,set, ...). - FTS5 query:
tok1 OR tok2 OR ...sobrefunctions_ftsconbm25(). Resultado: hasta 50 candidatos con rank BM25. - Fetch metadata: segundo query
SELECT ... FROM functions WHERE id IN (...)para obtener name, signature, description, tags. - Re-score aditivo: cada token suma su mejor boost de campo (
name=+3.0,tags=+2.0,signature=+1.5,description=+1.0). No multiplicativo — evita que tokens genericos saturen todos los resultados a 1.0. - Language penalty: si query tiene markers Python (
def,import,class) y el hit es bash → x0.5. Si tiene markers bash (curl,rsync,taskkill,exe) y hit es py → x0.5. - Normalizar: el top score raw se convierte en 1.0; el resto es relativo.
- Filtrar y limitar:
--min-scoredescarta ruido;--top Nlimita salida. - High confidence flag:
top[0].score / top[1].score > 1.5→"high_confidence": true.
Gotchas
Latencia: 6-7ms en WSL2 con 1255 funciones indexadas. Sin daemon — proceso fresh por invocacion. Bien por debajo del objetivo de 50ms.
FTS5 WAL: La conexion se abre en modo lectura normal (no mode=ro) porque bm25() con WAL no checkpointed falla con "missing row from content table". El binario nunca escribe.
FTS5 rebuild: Si fn match devuelve top: [] para queries que deberias matchear, el indice FTS5 puede estar desincronizado. Solucion:
// Rebuild manual del indice:
INSERT INTO functions_fts(functions_fts, rank) VALUES('rebuild', NULL);
INSERT INTO types_fts(types_fts, rank) VALUES('rebuild', NULL);
INSERT INTO unit_tests_fts(unit_tests_fts, rank) VALUES('rebuild', NULL);
O simplemente ./fn index — reindexar regenera el FTS5.
Stopwords del dominio: Tokens como registry, function, app, file, get, set se descartan del tokenizer porque matchean cientos de funciones igualmente y no aportan señal. Si un query solo tiene stopwords, fn match retorna error "no significant tokens".
Scores normalizados: El score 1.0 no significa "match perfecto" — es el mejor candidato relativo al batch. Un high_confidence: false con score 1.0 significa que el segundo candidato es similar. Para gates en hooks usar high_confidence: true como criterio.
Implementacion: cmd/fn/match.go en el modulo raiz fn-registry. Se compila junto al binario fn principal — no es un binario separado. Invocar como ./fn match ....
Capability growth log
- v1.0.0 (2026-05-14): scoring multiplicativo inicial — todos los hits clampean a 1.0 cuando varios tokens matchean
- v1.1.0 (2026-05-14): scoring aditivo por token con normalizacion relativa + stopwords del dominio. FTS5 rebuild fix. Latencia: 6-7ms