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:
Lucas committed 2026-10-23 08:22:04 -03:00
commit e989413018
76 files changed
+8386

No files matched your search

+907
View File
@@ -0,0 +1,907 @@
{
"version": 1,
"meta": {
"lastScanned": "2026-10-23T11:21:49.966Z",
"fileCount": 22,
"hits": 0,
"misses": 0,
"renderedHash": "2030278ebfc7a2591c4824586f15125940d579ecad61b4e8cb5a9a9bf6b3a399",
"storeUpdatedAt": "2026-10-23T11:21:49.967Z",
"rootHash": "77f386ab99dd2782"
},
"files": {
".gitignore": {
"description": "Git ignore rules",
"tokens": 24,
"hash": "465569a17f6c1fcd",
"size": 89,
"mtimeMs": 1792754328319.2644,
"updatedAt": "2026-10-23T11:21:49.944Z",
"source": "scan",
"importance": 0.1527
},
"AGENTS.md": {
"description": "OpenWolf",
"tokens": 75,
"hash": "e401f79554a8d796",
"size": 297,
"mtimeMs": 1792754075050.7603,
"updatedAt": "2026-10-23T11:21:49.944Z",
"source": "scan",
"importance": 0.1527
},
"Cargo.toml": {
"description": "Rust package manifest",
"tokens": 100,
"hash": "c445aa952b469eef",
"size": 351,
"mtimeMs": 1792754084001.563,
"updatedAt": "2026-10-23T11:21:49.945Z",
"source": "scan",
"importance": 0.1527
},
"CLAUDE.md": {
"description": "OpenWolf",
"tokens": 99,
"hash": "074d6b42b583729a",
"size": 395,
"mtimeMs": 1792754068779.6982,
"updatedAt": "2026-10-23T11:21:49.945Z",
"source": "scan",
"importance": 0.1527
},
"crates/sabia-cli/Cargo.toml": {
"description": "Rust package manifest",
"tokens": 125,
"hash": "dc1447c043cb895b",
"size": 436,
"mtimeMs": 1792754292996.8179,
"updatedAt": "2026-10-23T11:21:49.945Z",
"source": "scan",
"importance": 0.1527
},
"crates/sabia-cli/src/main.rs": {
"description": "Lista interfaces de rede e mostra quais são Wi-Fi.",
"tokens": 2193,
"hash": "2f37e8d34c3f1e7d",
"size": 7696,
"mtimeMs": 1792754462287.5278,
"updatedAt": "2026-10-23T11:21:49.945Z",
"source": "scan",
"symbols": [
{
"name": "web",
"kind": "section",
"startLine": 1,
"endLine": 1,
"tokens": 3
},
{
"name": "Cli",
"kind": "class",
"startLine": 12,
"endLine": 15,
"tokens": 16
},
{
"name": "Cmd",
"kind": "class",
"startLine": 18,
"endLine": 49,
"tokens": 285
},
{
"name": "IfaceAction",
"kind": "class",
"startLine": 52,
"endLine": 56,
"tokens": 43
},
{
"name": "OnOff",
"kind": "class",
"startLine": 59,
"endLine": 62,
"tokens": 9
},
{
"name": "audit_path",
"kind": "fn",
"startLine": 64,
"endLine": 66,
"tokens": 20
},
{
"name": "main",
"kind": "fn",
"startLine": 68,
"endLine": 74,
"tokens": 41
},
{
"name": "run",
"kind": "fn",
"startLine": 76,
"endLine": 216,
"tokens": 1643
}
],
"symbolSource": "ts",
"skeleton": "mod web;\nstruct Cli {\nenum Cmd {\nenum IfaceAction {\nenum OnOff {\nfn audit_path() -> PathBuf {\nfn main() {\nfn run(cli: Cli) -> sabia_core::Result<()> {",
"imports": [
"crates/sabia-cli/src/web/mod.rs"
],
"importance": 0.1527
},
"crates/sabia-cli/src/web/index.html": {
"description": "Sabiá",
"tokens": 1684,
"hash": "4344229aaa5e2db1",
"size": 6334,
"mtimeMs": 1792754445269.6348,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"importance": 0.1527
},
"crates/sabia-cli/src/web/mod.rs": {
"description": "Servidor local da interface: a mesma filosofia do Guará (`guara ui`) —",
"tokens": 2254,
"hash": "a6aa02205c19274e",
"size": 7896,
"mtimeMs": 1792754470284.2668,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"symbols": [
{
"name": "Session",
"kind": "class",
"startLine": 17,
"endLine": 20,
"tokens": 24
},
{
"name": "AppState",
"kind": "class",
"startLine": 23,
"endLine": 25,
"tokens": 19
},
{
"name": "serve",
"kind": "fn",
"startLine": 27,
"endLine": 47,
"tokens": 190
},
{
"name": "gen_token",
"kind": "fn",
"startLine": 49,
"endLine": 53,
"tokens": 52
},
{
"name": "open_browser",
"kind": "fn",
"startLine": 55,
"endLine": 57,
"tokens": 36
},
{
"name": "Request",
"kind": "class",
"startLine": 59,
"endLine": 64,
"tokens": 34
},
{
"name": "parse_request",
"kind": "fn",
"startLine": 66,
"endLine": 94,
"tokens": 286
},
{
"name": "urldecode",
"kind": "fn",
"startLine": 96,
"endLine": 98,
"tokens": 34
},
{
"name": "handle",
"kind": "fn",
"startLine": 100,
"endLine": 119,
"tokens": 227
},
{
"name": "respond",
"kind": "fn",
"startLine": 121,
"endLine": 131,
"tokens": 119
},
{
"name": "api",
"kind": "fn",
"startLine": 133,
"endLine": 174,
"tokens": 531
},
{
"name": "start_scan",
"kind": "fn",
"startLine": 176,
"endLine": 215,
"tokens": 439
},
{
"name": "stop_scan",
"kind": "fn",
"startLine": 217,
"endLine": 222,
"tokens": 60
}
],
"symbolSource": "ts",
"skeleton": "struct Session {\nstruct AppState {\npub fn serve(port: u16) -> sabia_core::Result<()> {\nfn gen_token() -> String {\nfn open_browser(url: &str) -> std::io::Result<()> {\nstruct Request {\nfn parse_request(stream: &mut TcpStream) -> std::io::Result<Request> {\nfn urldecode(s: &str) -> String {\nfn handle(mut stream: TcpStream, state: &Arc<AppState>, expected_token: &str) -> std::io::Result<()> {\nfn respond(stream: &mut TcpStream, code: u16, ctype: &str, body: &[u8]) -> std::io::Result<()> {\nfn api(state: &Arc<AppState>, req: &Request) -> String {\nfn start_scan(state: &Arc<AppState>, name: String) -> String {\nfn stop_scan(state: &Arc<AppState>, name: &str) {",
"importance": 0.2825
},
"crates/sabia-core/Cargo.toml": {
"description": "Rust package manifest",
"tokens": 190,
"hash": "09752951731f7901",
"size": 670,
"mtimeMs": 1792754101085.2576,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"importance": 0.1527
},
"crates/sabia-core/src/audit.rs": {
"description": "Trilha de auditoria encadeada por hash de toda ação sensível (ligar",
"tokens": 1151,
"hash": "5b60f2b256cb178b",
"size": 4052,
"mtimeMs": 1792754254667.1384,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"symbols": [
{
"name": "AuditEntry",
"kind": "class",
"startLine": 20,
"endLine": 27,
"tokens": 50
},
{
"name": "AuditLog",
"kind": "class",
"startLine": 29,
"endLine": 32,
"tokens": 22
},
{
"name": "AuditLog",
"kind": "section",
"startLine": 36,
"endLine": 114,
"tokens": 828
},
{
"name": "AuditLog.open",
"kind": "method",
"startLine": 37,
"endLine": 57,
"tokens": 214
},
{
"name": "AuditLog.record",
"kind": "method",
"startLine": 59,
"endLine": 83,
"tokens": 271
},
{
"name": "AuditLog.verify",
"kind": "method",
"startLine": 87,
"endLine": 113,
"tokens": 305
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs"
],
"importance": 0.1657
},
"crates/sabia-core/src/capture.rs": {
"description": "Captura crua de quadros 802.11 via `AF_PACKET`, sem depender de libpcap.",
"tokens": 1114,
"hash": "b2f202d231708f43",
"size": 3915,
"mtimeMs": 1792754351620.4128,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"symbols": [
{
"name": "RawCapture",
"kind": "class",
"startLine": 19,
"endLine": 21,
"tokens": 12
},
{
"name": "RawCapture",
"kind": "section",
"startLine": 23,
"endLine": 94,
"tokens": 726
},
{
"name": "RawCapture.open",
"kind": "method",
"startLine": 26,
"endLine": 58,
"tokens": 310
},
{
"name": "RawCapture.set_read_timeout",
"kind": "method",
"startLine": 62,
"endLine": 80,
"tokens": 184
},
{
"name": "RawCapture.recv",
"kind": "method",
"startLine": 83,
"endLine": 93,
"tokens": 126
},
{
"name": "AsRawFd",
"kind": "section",
"startLine": 96,
"endLine": 100,
"tokens": 26
},
{
"name": "AsRawFd.as_raw_fd",
"kind": "method",
"startLine": 97,
"endLine": 99,
"tokens": 16
},
{
"name": "Drop",
"kind": "section",
"startLine": 102,
"endLine": 106,
"tokens": 29
},
{
"name": "Drop.drop",
"kind": "method",
"startLine": 103,
"endLine": 105,
"tokens": 21
},
{
"name": "if_index",
"kind": "fn",
"startLine": 108,
"endLine": 115,
"tokens": 90
},
{
"name": "check_capabilities",
"kind": "fn",
"startLine": 119,
"endLine": 122,
"tokens": 28
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs"
],
"importance": 0.1657
},
"crates/sabia-core/src/dot11.rs": {
"description": "Parser mínimo de quadros 802.11 de gerenciamento (beacon, probe",
"tokens": 1655,
"hash": "f6ce71057b70544a",
"size": 5804,
"mtimeMs": 1792754184829.32,
"updatedAt": "2026-10-23T11:21:49.946Z",
"source": "scan",
"symbols": [
{
"name": "FrameKind",
"kind": "class",
"startLine": 5,
"endLine": 14,
"tokens": 41
},
{
"name": "Security",
"kind": "class",
"startLine": 17,
"endLine": 23,
"tokens": 20
},
{
"name": "ManagementInfo",
"kind": "class",
"startLine": 26,
"endLine": 30,
"tokens": 37
},
{
"name": "mac_to_string",
"kind": "fn",
"startLine": 32,
"endLine": 34,
"tokens": 44
},
{
"name": "Frame",
"kind": "class",
"startLine": 37,
"endLine": 46,
"tokens": 96
},
{
"name": "parse",
"kind": "fn",
"startLine": 48,
"endLine": 83,
"tokens": 389
},
{
"name": "bssid_str",
"kind": "method",
"startLine": 86,
"endLine": 88,
"tokens": 29
},
{
"name": "src_str",
"kind": "method",
"startLine": 90,
"endLine": 92,
"tokens": 28
},
{
"name": "management_info",
"kind": "method",
"startLine": 96,
"endLine": 162,
"tokens": 635
},
{
"name": "is_eapol",
"kind": "fn",
"startLine": 167,
"endLine": 183,
"tokens": 160
}
],
"symbolSource": "ts",
"importance": 0.2361
},
"crates/sabia-core/src/error.rs": {
"description": "[derive(Debug, thiserror::Error)]",
"tokens": 225,
"hash": "02139521fcac88db",
"size": 797,
"mtimeMs": 1792754108274.089,
"updatedAt": "2026-10-23T11:21:49.947Z",
"source": "scan",
"importance": 1
},
"crates/sabia-core/src/iface.rs": {
"description": "Descoberta de interfaces de rede e identificação das que são Wi-Fi.",
"tokens": 973,
"hash": "bc45dfdc47a527fc",
"size": 3427,
"mtimeMs": 1792754124447.7615,
"updatedAt": "2026-10-23T11:21:49.947Z",
"source": "scan",
"symbols": [
{
"name": "Interface",
"kind": "class",
"startLine": 11,
"endLine": 18,
"tokens": 59
},
{
"name": "Mode",
"kind": "class",
"startLine": 21,
"endLine": 25,
"tokens": 16
},
{
"name": "net_root",
"kind": "fn",
"startLine": 27,
"endLine": 29,
"tokens": 19
},
{
"name": "list_all",
"kind": "fn",
"startLine": 32,
"endLine": 44,
"tokens": 110
},
{
"name": "list_wireless",
"kind": "fn",
"startLine": 47,
"endLine": 49,
"tokens": 35
},
{
"name": "get",
"kind": "fn",
"startLine": 51,
"endLine": 57,
"tokens": 57
},
{
"name": "read_interface",
"kind": "fn",
"startLine": 59,
"endLine": 98,
"tokens": 372
},
{
"name": "read_wireless_mode",
"kind": "fn",
"startLine": 104,
"endLine": 110,
"tokens": 62
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs"
],
"importance": 0.2361
},
"crates/sabia-core/src/lib.rs": {
"description": "`sabia-core`: tudo que fala com o rádio Wi-Fi, interpreta quadros 802.11",
"tokens": 140,
"hash": "e65164872526b1e7",
"size": 495,
"mtimeMs": 1792754288188.87,
"updatedAt": "2026-10-23T11:21:49.947Z",
"source": "scan",
"imports": [
"crates/sabia-core/src/audit.rs",
"crates/sabia-core/src/dot11.rs",
"crates/sabia-core/src/error.rs",
"crates/sabia-core/src/iface.rs",
"crates/sabia-core/src/netlink.rs",
"crates/sabia-core/src/pcapwriter.rs",
"crates/sabia-core/src/radiotap.rs",
"crates/sabia-core/src/scan.rs",
"crates/sabia-core/src/update.rs",
"crates/sabia-core/src/capture.rs"
],
"importance": 0.1527
},
"crates/sabia-core/src/netlink.rs": {
"description": "Controle de modo (managed/monitor) e canal via `iw`.",
"tokens": 996,
"hash": "6a27b03cef2c283e",
"size": 3500,
"mtimeMs": 1792754142459.2986,
"updatedAt": "2026-10-23T11:21:49.947Z",
"source": "scan",
"symbols": [
{
"name": "run",
"kind": "fn",
"startLine": 13,
"endLine": 34,
"tokens": 246
},
{
"name": "iw_dev_type",
"kind": "fn",
"startLine": 36,
"endLine": 49,
"tokens": 123
},
{
"name": "supported_channels",
"kind": "fn",
"startLine": 52,
"endLine": 80,
"tokens": 294
},
{
"name": "set_monitor_mode",
"kind": "fn",
"startLine": 83,
"endLine": 89,
"tokens": 84
},
{
"name": "set_channel",
"kind": "fn",
"startLine": 92,
"endLine": 95,
"tokens": 42
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs",
"crates/sabia-core/src/iface.rs"
],
"importance": 0.1657
},
"crates/sabia-core/src/pcapwriter.rs": {
"description": "Escritor de arquivos `.pcap` (formato clássico, link-type 127 =",
"tokens": 507,
"hash": "2d6921c66f9e7506",
"size": 1781,
"mtimeMs": 1792754240112.29,
"updatedAt": "2026-10-23T11:21:49.947Z",
"source": "scan",
"symbols": [
{
"name": "PcapWriter",
"kind": "class",
"startLine": 13,
"endLine": 15,
"tokens": 15
},
{
"name": "PcapWriter",
"kind": "section",
"startLine": 17,
"endLine": 47,
"tokens": 379
},
{
"name": "PcapWriter.create",
"kind": "method",
"startLine": 18,
"endLine": 30,
"tokens": 186
},
{
"name": "PcapWriter.write_frame",
"kind": "method",
"startLine": 33,
"endLine": 41,
"tokens": 140
},
{
"name": "PcapWriter.flush",
"kind": "method",
"startLine": 43,
"endLine": 46,
"tokens": 26
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs"
],
"importance": 0.1657
},
"crates/sabia-core/src/radiotap.rs": {
"description": "Parser mínimo de cabeçalho Radiotap — só os campos que usamos",
"tokens": 881,
"hash": "3dc5e23c73e7e66a",
"size": 3104,
"mtimeMs": 1792754360436.5854,
"updatedAt": "2026-10-23T11:21:49.948Z",
"source": "scan",
"symbols": [
{
"name": "RadiotapInfo",
"kind": "class",
"startLine": 6,
"endLine": 10,
"tokens": 34
},
{
"name": "parse",
"kind": "fn",
"startLine": 20,
"endLine": 94,
"tokens": 626
},
{
"name": "freq_to_channel",
"kind": "fn",
"startLine": 96,
"endLine": 103,
"tokens": 73
}
],
"symbolSource": "ts",
"importance": 0.2361
},
"crates/sabia-core/src/scan.rs": {
"description": "Agregação de quadros capturados em uma tabela de APs e clientes vistos,",
"tokens": 1128,
"hash": "bcd7f984398bfdc4",
"size": 3963,
"mtimeMs": 1792754229534.2896,
"updatedAt": "2026-10-23T11:21:49.948Z",
"source": "scan",
"symbols": [
{
"name": "AccessPoint",
"kind": "class",
"startLine": 11,
"endLine": 20,
"tokens": 76
},
{
"name": "ScanTable",
"kind": "class",
"startLine": 23,
"endLine": 25,
"tokens": 18
},
{
"name": "ScanTable",
"kind": "section",
"startLine": 27,
"endLine": 102,
"tokens": 842
},
{
"name": "ScanTable.new",
"kind": "method",
"startLine": 28,
"endLine": 30,
"tokens": 16
},
{
"name": "ScanTable.ingest",
"kind": "method",
"startLine": 36,
"endLine": 95,
"tokens": 696
},
{
"name": "ScanTable.access_points",
"kind": "method",
"startLine": 97,
"endLine": 101,
"tokens": 57
},
{
"name": "security_label",
"kind": "fn",
"startLine": 104,
"endLine": 112,
"tokens": 77
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/dot11.rs",
"crates/sabia-core/src/radiotap.rs"
],
"importance": 0.1657
},
"crates/sabia-core/src/update.rs": {
"description": "Auto-atualização simples: verifica a última release no GitHub, baixa o",
"tokens": 1772,
"hash": "03ad228ca62475e3",
"size": 6236,
"mtimeMs": 1792754282046.0845,
"updatedAt": "2026-10-23T11:21:49.948Z",
"source": "scan",
"symbols": [
{
"name": "Release",
"kind": "class",
"startLine": 18,
"endLine": 21,
"tokens": 19
},
{
"name": "Asset",
"kind": "class",
"startLine": 24,
"endLine": 27,
"tokens": 20
},
{
"name": "UpdateStatus",
"kind": "class",
"startLine": 30,
"endLine": 34,
"tokens": 38
},
{
"name": "curl_text",
"kind": "fn",
"startLine": 36,
"endLine": 48,
"tokens": 152
},
{
"name": "curl_download",
"kind": "fn",
"startLine": 50,
"endLine": 61,
"tokens": 138
},
{
"name": "asset_name_for_platform",
"kind": "fn",
"startLine": 63,
"endLine": 73,
"tokens": 91
},
{
"name": "check",
"kind": "fn",
"startLine": 77,
"endLine": 99,
"tokens": 260
},
{
"name": "apply",
"kind": "fn",
"startLine": 103,
"endLine": 162,
"tokens": 693
},
{
"name": "find_binary",
"kind": "fn",
"startLine": 164,
"endLine": 173,
"tokens": 109
}
],
"symbolSource": "ts",
"imports": [
"crates/sabia-core/src/error.rs"
],
"importance": 0.1657
},
"GEMINI.md": {
"description": "OpenWolf",
"tokens": 75,
"hash": "e401f79554a8d796",
"size": 297,
"mtimeMs": 1792754075057.7603,
"updatedAt": "2026-10-23T11:21:49.948Z",
"source": "scan",
"importance": 0.1527
},
"README.md": {
"description": "Project documentation",
"tokens": 462,
"hash": "04a8387e4a13cf9f",
"size": 1887,
"mtimeMs": 1792754508878.1196,
"updatedAt": "2026-10-23T11:21:49.949Z",
"source": "scan",
"importance": 0.1527
}
},
"preamble": [
"> Project structure index. Auto-maintained by OpenWolf hooks and daemon.",
"> Run `openwolf scan` to generate, or wait for the first Claude Code session.",
"> Status: Pending initial scan"
]
}