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>
120 lines
4.4 KiB
JavaScript
120 lines
4.4 KiB
JavaScript
import { patchFocus } from '../document/patchFocus.js';
|
|
import { prepareDocument } from '../document/prepareDocument.js';
|
|
import { dispatchEvent, dispatchUIEvent } from '../event/dispatchEvent.js';
|
|
import { attachClipboardStubToView } from '../utils/dataTransfer/Clipboard.js';
|
|
import { getWindow } from '../utils/misc/getWindow.js';
|
|
import { getDocumentFromNode } from '../utils/misc/getDocumentFromNode.js';
|
|
import { setLevelRef, ApiLevel } from '../utils/misc/level.js';
|
|
import { wait } from '../utils/misc/wait.js';
|
|
import { PointerEventsCheckLevel } from '../options.js';
|
|
import '@testing-library/dom';
|
|
import { defaultKeyMap } from '../keyboard/keyMap.js';
|
|
import { defaultKeyMap as defaultKeyMap$1 } from '../pointer/keyMap.js';
|
|
import { System } from '../system/index.js';
|
|
import { userEventApi } from './api.js';
|
|
import { wrapAsync } from './wrapAsync.js';
|
|
|
|
/**
|
|
* Default options applied when API is called per `userEvent.anyApi()`
|
|
*/ const defaultOptionsDirect = {
|
|
applyAccept: true,
|
|
autoModify: true,
|
|
delay: 0,
|
|
document: globalThis.document,
|
|
keyboardMap: defaultKeyMap,
|
|
pointerMap: defaultKeyMap$1,
|
|
pointerEventsCheck: PointerEventsCheckLevel.EachApiCall,
|
|
skipAutoClose: false,
|
|
skipClick: false,
|
|
skipHover: false,
|
|
writeToClipboard: false,
|
|
advanceTimers: ()=>Promise.resolve()
|
|
};
|
|
/**
|
|
* Default options applied when API is called per `userEvent().anyApi()`
|
|
*/ const defaultOptionsSetup = {
|
|
...defaultOptionsDirect,
|
|
writeToClipboard: true
|
|
};
|
|
function createConfig(options = {}, defaults = defaultOptionsSetup, node) {
|
|
const document = getDocument(options, node, defaults);
|
|
return {
|
|
...defaults,
|
|
...options,
|
|
document
|
|
};
|
|
}
|
|
/**
|
|
* Start a "session" with userEvent.
|
|
* All APIs returned by this function share an input device state and a default configuration.
|
|
*/ function setupMain(options = {}) {
|
|
const config = createConfig(options);
|
|
prepareDocument(config.document);
|
|
patchFocus(getWindow(config.document).HTMLElement);
|
|
var _config_document_defaultView;
|
|
const view = (_config_document_defaultView = config.document.defaultView) !== null && _config_document_defaultView !== undefined ? _config_document_defaultView : /* istanbul ignore next */ globalThis.window;
|
|
attachClipboardStubToView(view);
|
|
return createInstance(config).api;
|
|
}
|
|
/**
|
|
* Setup in direct call per `userEvent.anyApi()`
|
|
*/ function setupDirect({ keyboardState, pointerState, ...options } = {}, node) {
|
|
const config = createConfig(options, defaultOptionsDirect, node);
|
|
prepareDocument(config.document);
|
|
patchFocus(getWindow(config.document).HTMLElement);
|
|
var _ref;
|
|
const system = (_ref = pointerState !== null && pointerState !== undefined ? pointerState : keyboardState) !== null && _ref !== undefined ? _ref : new System();
|
|
return {
|
|
api: createInstance(config, system).api,
|
|
system
|
|
};
|
|
}
|
|
/**
|
|
* Create a set of callbacks with different default settings but the same state.
|
|
*/ function setupSub(options) {
|
|
return createInstance({
|
|
...this.config,
|
|
...options
|
|
}, this.system).api;
|
|
}
|
|
function wrapAndBindImpl(instance, impl) {
|
|
function method(...args) {
|
|
setLevelRef(instance, ApiLevel.Call);
|
|
return wrapAsync(()=>impl.apply(instance, args).then(async (ret)=>{
|
|
await wait(instance.config);
|
|
return ret;
|
|
}));
|
|
}
|
|
Object.defineProperty(method, 'name', {
|
|
get: ()=>impl.name
|
|
});
|
|
return method;
|
|
}
|
|
function createInstance(config, system = new System()) {
|
|
const instance = {};
|
|
Object.assign(instance, {
|
|
config,
|
|
dispatchEvent: dispatchEvent.bind(instance),
|
|
dispatchUIEvent: dispatchUIEvent.bind(instance),
|
|
system,
|
|
levelRefs: {},
|
|
...userEventApi
|
|
});
|
|
return {
|
|
instance,
|
|
api: {
|
|
...Object.fromEntries(Object.entries(userEventApi).map(([name, api])=>[
|
|
name,
|
|
wrapAndBindImpl(instance, api)
|
|
])),
|
|
setup: setupSub.bind(instance)
|
|
}
|
|
};
|
|
}
|
|
function getDocument(options, node, defaults) {
|
|
var _options_document, _ref;
|
|
return (_ref = (_options_document = options.document) !== null && _options_document !== undefined ? _options_document : node && getDocumentFromNode(node)) !== null && _ref !== undefined ? _ref : defaults.document;
|
|
}
|
|
|
|
export { createConfig, createInstance, setupDirect, setupMain, setupSub };
|