Implements Phases 1-8 of the TFTSR implementation plan. Rust backend (Tauri 2.x, src-tauri/): - Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama - PII detection engine: 11 regex patterns with overlap resolution - SQLCipher AES-256 encrypted database with 10 versioned migrations - 28 Tauri IPC commands for triage, analysis, document, and system ops - Ollama: hardware probe, model recommendations, pull/delete with events - RCA and blameless post-mortem Markdown document generators - PDF export via printpdf - Audit log: SHA-256 hash of every external data send - Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2) Frontend (React 18 + TypeScript + Vite, src/): - 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings - 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives - 3 Zustand stores: session, settings (persisted), history - Type-safe tauriCommands.ts matching Rust backend types exactly - 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs) DevOps: - .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push - .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload Verified: - cargo check: zero errors - tsc --noEmit: zero errors - vitest run: 13/13 unit tests passing Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
189 lines
4.0 KiB
JavaScript
189 lines
4.0 KiB
JavaScript
function isBuffer(value) {
|
|
return Buffer.isBuffer(value) || value instanceof Uint8Array
|
|
}
|
|
|
|
function isEncoding(encoding) {
|
|
return Buffer.isEncoding(encoding)
|
|
}
|
|
|
|
function alloc(size, fill, encoding) {
|
|
return Buffer.alloc(size, fill, encoding)
|
|
}
|
|
|
|
function allocUnsafe(size) {
|
|
return Buffer.allocUnsafe(size)
|
|
}
|
|
|
|
function allocUnsafeSlow(size) {
|
|
return Buffer.allocUnsafeSlow(size)
|
|
}
|
|
|
|
function byteLength(string, encoding) {
|
|
return Buffer.byteLength(string, encoding)
|
|
}
|
|
|
|
function compare(a, b) {
|
|
return Buffer.compare(a, b)
|
|
}
|
|
|
|
function concat(buffers, totalLength) {
|
|
return Buffer.concat(buffers, totalLength)
|
|
}
|
|
|
|
function copy(source, target, targetStart, start, end) {
|
|
return toBuffer(source).copy(target, targetStart, start, end)
|
|
}
|
|
|
|
function equals(a, b) {
|
|
return toBuffer(a).equals(b)
|
|
}
|
|
|
|
function fill(buffer, value, offset, end, encoding) {
|
|
return toBuffer(buffer).fill(value, offset, end, encoding)
|
|
}
|
|
|
|
function from(value, encodingOrOffset, length) {
|
|
return Buffer.from(value, encodingOrOffset, length)
|
|
}
|
|
|
|
function includes(buffer, value, byteOffset, encoding) {
|
|
return toBuffer(buffer).includes(value, byteOffset, encoding)
|
|
}
|
|
|
|
function indexOf(buffer, value, byfeOffset, encoding) {
|
|
return toBuffer(buffer).indexOf(value, byfeOffset, encoding)
|
|
}
|
|
|
|
function lastIndexOf(buffer, value, byteOffset, encoding) {
|
|
return toBuffer(buffer).lastIndexOf(value, byteOffset, encoding)
|
|
}
|
|
|
|
function swap16(buffer) {
|
|
return toBuffer(buffer).swap16()
|
|
}
|
|
|
|
function swap32(buffer) {
|
|
return toBuffer(buffer).swap32()
|
|
}
|
|
|
|
function swap64(buffer) {
|
|
return toBuffer(buffer).swap64()
|
|
}
|
|
|
|
function toBuffer(buffer) {
|
|
if (Buffer.isBuffer(buffer)) return buffer
|
|
return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength)
|
|
}
|
|
|
|
function toString(buffer, encoding, start, end) {
|
|
return toBuffer(buffer).toString(encoding, start, end)
|
|
}
|
|
|
|
function write(buffer, string, offset, length, encoding) {
|
|
return toBuffer(buffer).write(string, offset, length, encoding)
|
|
}
|
|
|
|
function readDoubleBE(buffer, offset) {
|
|
return toBuffer(buffer).readDoubleBE(offset)
|
|
}
|
|
|
|
function readDoubleLE(buffer, offset) {
|
|
return toBuffer(buffer).readDoubleLE(offset)
|
|
}
|
|
|
|
function readFloatBE(buffer, offset) {
|
|
return toBuffer(buffer).readFloatBE(offset)
|
|
}
|
|
|
|
function readFloatLE(buffer, offset) {
|
|
return toBuffer(buffer).readFloatLE(offset)
|
|
}
|
|
|
|
function readInt32BE(buffer, offset) {
|
|
return toBuffer(buffer).readInt32BE(offset)
|
|
}
|
|
|
|
function readInt32LE(buffer, offset) {
|
|
return toBuffer(buffer).readInt32LE(offset)
|
|
}
|
|
|
|
function readUInt32BE(buffer, offset) {
|
|
return toBuffer(buffer).readUInt32BE(offset)
|
|
}
|
|
|
|
function readUInt32LE(buffer, offset) {
|
|
return toBuffer(buffer).readUInt32LE(offset)
|
|
}
|
|
|
|
function writeDoubleBE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeDoubleBE(value, offset)
|
|
}
|
|
|
|
function writeDoubleLE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeDoubleLE(value, offset)
|
|
}
|
|
|
|
function writeFloatBE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeFloatBE(value, offset)
|
|
}
|
|
|
|
function writeFloatLE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeFloatLE(value, offset)
|
|
}
|
|
|
|
function writeInt32BE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeInt32BE(value, offset)
|
|
}
|
|
|
|
function writeInt32LE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeInt32LE(value, offset)
|
|
}
|
|
|
|
function writeUInt32BE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeUInt32BE(value, offset)
|
|
}
|
|
|
|
function writeUInt32LE(buffer, value, offset) {
|
|
return toBuffer(buffer).writeUInt32LE(value, offset)
|
|
}
|
|
|
|
module.exports = {
|
|
isBuffer,
|
|
isEncoding,
|
|
alloc,
|
|
allocUnsafe,
|
|
allocUnsafeSlow,
|
|
byteLength,
|
|
compare,
|
|
concat,
|
|
copy,
|
|
equals,
|
|
fill,
|
|
from,
|
|
includes,
|
|
indexOf,
|
|
lastIndexOf,
|
|
swap16,
|
|
swap32,
|
|
swap64,
|
|
toBuffer,
|
|
toString,
|
|
write,
|
|
readDoubleBE,
|
|
readDoubleLE,
|
|
readFloatBE,
|
|
readFloatLE,
|
|
readInt32BE,
|
|
readInt32LE,
|
|
readUInt32BE,
|
|
readUInt32LE,
|
|
writeDoubleBE,
|
|
writeDoubleLE,
|
|
writeFloatBE,
|
|
writeFloatLE,
|
|
writeInt32BE,
|
|
writeInt32LE,
|
|
writeUInt32BE,
|
|
writeUInt32LE
|
|
}
|