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>
86 lines
2.3 KiB
JavaScript
86 lines
2.3 KiB
JavaScript
"use strict";
|
|
var USE_TYPEDARRAY = (typeof Uint8Array !== "undefined") && (typeof Uint16Array !== "undefined") && (typeof Uint32Array !== "undefined");
|
|
|
|
var pako = require("pako");
|
|
var utils = require("./utils");
|
|
var GenericWorker = require("./stream/GenericWorker");
|
|
|
|
var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";
|
|
|
|
exports.magic = "\x08\x00";
|
|
|
|
/**
|
|
* Create a worker that uses pako to inflate/deflate.
|
|
* @constructor
|
|
* @param {String} action the name of the pako function to call : either "Deflate" or "Inflate".
|
|
* @param {Object} options the options to use when (de)compressing.
|
|
*/
|
|
function FlateWorker(action, options) {
|
|
GenericWorker.call(this, "FlateWorker/" + action);
|
|
|
|
this._pako = null;
|
|
this._pakoAction = action;
|
|
this._pakoOptions = options;
|
|
// the `meta` object from the last chunk received
|
|
// this allow this worker to pass around metadata
|
|
this.meta = {};
|
|
}
|
|
|
|
utils.inherits(FlateWorker, GenericWorker);
|
|
|
|
/**
|
|
* @see GenericWorker.processChunk
|
|
*/
|
|
FlateWorker.prototype.processChunk = function (chunk) {
|
|
this.meta = chunk.meta;
|
|
if (this._pako === null) {
|
|
this._createPako();
|
|
}
|
|
this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);
|
|
};
|
|
|
|
/**
|
|
* @see GenericWorker.flush
|
|
*/
|
|
FlateWorker.prototype.flush = function () {
|
|
GenericWorker.prototype.flush.call(this);
|
|
if (this._pako === null) {
|
|
this._createPako();
|
|
}
|
|
this._pako.push([], true);
|
|
};
|
|
/**
|
|
* @see GenericWorker.cleanUp
|
|
*/
|
|
FlateWorker.prototype.cleanUp = function () {
|
|
GenericWorker.prototype.cleanUp.call(this);
|
|
this._pako = null;
|
|
};
|
|
|
|
/**
|
|
* Create the _pako object.
|
|
* TODO: lazy-loading this object isn't the best solution but it's the
|
|
* quickest. The best solution is to lazy-load the worker list. See also the
|
|
* issue #446.
|
|
*/
|
|
FlateWorker.prototype._createPako = function () {
|
|
this._pako = new pako[this._pakoAction]({
|
|
raw: true,
|
|
level: this._pakoOptions.level || -1 // default compression
|
|
});
|
|
var self = this;
|
|
this._pako.onData = function(data) {
|
|
self.push({
|
|
data : data,
|
|
meta : self.meta
|
|
});
|
|
};
|
|
};
|
|
|
|
exports.compressWorker = function (compressionOptions) {
|
|
return new FlateWorker("Deflate", compressionOptions);
|
|
};
|
|
exports.uncompressWorker = function () {
|
|
return new FlateWorker("Inflate", {});
|
|
};
|