Esqueleto inicial: sabia-core + sabia-cli + UI local, OpenWolf
- sabia-core: descoberta de interfaces, controle de modo monitor/canal via iw (ponte até ter nl80211 nativo), captura crua 802.11 via AF_PACKET (sem libpcap), parsing de radiotap e quadros de gerenciamento (beacon/probe/EAPOL), agregação em tabela de APs/ clientes, escrita de .pcap, trilha de auditoria encadeada por hash, auto-atualização via GitHub releases (curl, sem dependências de rede extras) - sabia-cli: `sabia iface`, `sabia scan`, `sabia update`, `sabia audit-verify`, `sabia ui` (servidor local + navegador, protegido por token, mesma filosofia do Guará) - OpenWolf inicializado para memória de projeto entre agentes
This commit is contained in:
commit
e989413018
76 files changed
+8386
No files matched your search
@@ -0,0 +1,41 @@
|
||||
import { persistRead, reconcileReads } from "./event-journal.js"
|
||||
import * as crypto from "node:crypto"
|
||||
import * as fs from "node:fs"
|
||||
import * as path from "node:path"
|
||||
import { getWolfDir, writeJSON, readJSON, normalizePath, estimateTokens, sessionFilePath } from "./fs.js"
|
||||
import { lookupEntry } from "./anatomy.js"
|
||||
import type { PartialSessionState } from "./types.js"
|
||||
|
||||
export function handlePostRead(directory: string, sessionId: string, filePath: string, content: string, ranged = false, observationId?: string): void {
|
||||
if (ranged) return
|
||||
filePath=path.resolve(directory,filePath)
|
||||
const wolfDir = getWolfDir(directory)
|
||||
if (!fs.existsSync(wolfDir)) return
|
||||
|
||||
const hooksDir = path.join(wolfDir, "hooks")
|
||||
const sessionFile = sessionFilePath(hooksDir, sessionId)
|
||||
const normalizedFile = normalizePath(filePath)
|
||||
|
||||
const projectDir = normalizePath(directory)
|
||||
const rel=path.relative(directory,filePath)
|
||||
if (!rel || rel==='..' || rel.startsWith('..'+path.sep) || path.isAbsolute(rel) || rel.split(path.sep)[0]==='.wolf') return
|
||||
|
||||
const ext = path.extname(filePath).toLowerCase()
|
||||
const codeExts = new Set([".ts", ".js", ".tsx", ".jsx", ".py", ".rs", ".go", ".java", ".c", ".cpp", ".css", ".json", ".yaml", ".yml"])
|
||||
const proseExts = new Set([".md", ".txt", ".rst"])
|
||||
const type = codeExts.has(ext) ? "code" : proseExts.has(ext) ? "prose" : "mixed"
|
||||
|
||||
let tokens = content ? estimateTokens(content, type as "code" | "prose" | "mixed") : 0
|
||||
|
||||
// Fallback: if the tool output had no content, use the anatomy token estimate
|
||||
if (tokens === 0) {
|
||||
const entry = lookupEntry(wolfDir, projectDir, normalizedFile)
|
||||
if (entry) tokens = entry.tokens
|
||||
}
|
||||
|
||||
let fingerprint: string | undefined
|
||||
let mtime=0
|
||||
try {const current=fs.readFileSync(filePath,"utf8");if(current===content){fingerprint=crypto.createHash("sha256").update(current).digest("hex");mtime=fs.statSync(filePath).mtimeMs}}catch{}
|
||||
persistRead(sessionFile,{id:observationId ?? crypto.randomUUID(),file:normalizedFile,at:new Date().toISOString(),tokens,fingerprint,mtime})
|
||||
reconcileReads(sessionFile)
|
||||
}
|
||||
Reference in new issue
Block a user