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>
147 lines
5.4 KiB
JavaScript
147 lines
5.4 KiB
JavaScript
/**
|
|
* @import {ConstructName, Unsafe} from 'mdast-util-to-markdown'
|
|
*/
|
|
|
|
/**
|
|
* List of constructs that occur in phrasing (paragraphs, headings), but cannot
|
|
* contain things like attention (emphasis, strong), images, or links.
|
|
* So they sort of cancel each other out.
|
|
* Note: could use a better name.
|
|
*
|
|
* @type {Array<ConstructName>}
|
|
*/
|
|
const fullPhrasingSpans = [
|
|
'autolink',
|
|
'destinationLiteral',
|
|
'destinationRaw',
|
|
'reference',
|
|
'titleQuote',
|
|
'titleApostrophe'
|
|
]
|
|
|
|
/** @type {Array<Unsafe>} */
|
|
export const unsafe = [
|
|
{character: '\t', after: '[\\r\\n]', inConstruct: 'phrasing'},
|
|
{character: '\t', before: '[\\r\\n]', inConstruct: 'phrasing'},
|
|
{
|
|
character: '\t',
|
|
inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde']
|
|
},
|
|
{
|
|
character: '\r',
|
|
inConstruct: [
|
|
'codeFencedLangGraveAccent',
|
|
'codeFencedLangTilde',
|
|
'codeFencedMetaGraveAccent',
|
|
'codeFencedMetaTilde',
|
|
'destinationLiteral',
|
|
'headingAtx'
|
|
]
|
|
},
|
|
{
|
|
character: '\n',
|
|
inConstruct: [
|
|
'codeFencedLangGraveAccent',
|
|
'codeFencedLangTilde',
|
|
'codeFencedMetaGraveAccent',
|
|
'codeFencedMetaTilde',
|
|
'destinationLiteral',
|
|
'headingAtx'
|
|
]
|
|
},
|
|
{character: ' ', after: '[\\r\\n]', inConstruct: 'phrasing'},
|
|
{character: ' ', before: '[\\r\\n]', inConstruct: 'phrasing'},
|
|
{
|
|
character: ' ',
|
|
inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde']
|
|
},
|
|
// An exclamation mark can start an image, if it is followed by a link or
|
|
// a link reference.
|
|
{
|
|
character: '!',
|
|
after: '\\[',
|
|
inConstruct: 'phrasing',
|
|
notInConstruct: fullPhrasingSpans
|
|
},
|
|
// A quote can break out of a title.
|
|
{character: '"', inConstruct: 'titleQuote'},
|
|
// A number sign could start an ATX heading if it starts a line.
|
|
{atBreak: true, character: '#'},
|
|
{character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'},
|
|
// Dollar sign and percentage are not used in markdown.
|
|
// An ampersand could start a character reference.
|
|
{character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'},
|
|
// An apostrophe can break out of a title.
|
|
{character: "'", inConstruct: 'titleApostrophe'},
|
|
// A left paren could break out of a destination raw.
|
|
{character: '(', inConstruct: 'destinationRaw'},
|
|
// A left paren followed by `]` could make something into a link or image.
|
|
{
|
|
before: '\\]',
|
|
character: '(',
|
|
inConstruct: 'phrasing',
|
|
notInConstruct: fullPhrasingSpans
|
|
},
|
|
// A right paren could start a list item or break out of a destination
|
|
// raw.
|
|
{atBreak: true, before: '\\d+', character: ')'},
|
|
{character: ')', inConstruct: 'destinationRaw'},
|
|
// An asterisk can start thematic breaks, list items, emphasis, strong.
|
|
{atBreak: true, character: '*', after: '(?:[ \t\r\n*])'},
|
|
{character: '*', inConstruct: 'phrasing', notInConstruct: fullPhrasingSpans},
|
|
// A plus sign could start a list item.
|
|
{atBreak: true, character: '+', after: '(?:[ \t\r\n])'},
|
|
// A dash can start thematic breaks, list items, and setext heading
|
|
// underlines.
|
|
{atBreak: true, character: '-', after: '(?:[ \t\r\n-])'},
|
|
// A dot could start a list item.
|
|
{atBreak: true, before: '\\d+', character: '.', after: '(?:[ \t\r\n]|$)'},
|
|
// Slash, colon, and semicolon are not used in markdown for constructs.
|
|
// A less than can start html (flow or text) or an autolink.
|
|
// HTML could start with an exclamation mark (declaration, cdata, comment),
|
|
// slash (closing tag), question mark (instruction), or a letter (tag).
|
|
// An autolink also starts with a letter.
|
|
// Finally, it could break out of a destination literal.
|
|
{atBreak: true, character: '<', after: '[!/?A-Za-z]'},
|
|
{
|
|
character: '<',
|
|
after: '[!/?A-Za-z]',
|
|
inConstruct: 'phrasing',
|
|
notInConstruct: fullPhrasingSpans
|
|
},
|
|
{character: '<', inConstruct: 'destinationLiteral'},
|
|
// An equals to can start setext heading underlines.
|
|
{atBreak: true, character: '='},
|
|
// A greater than can start block quotes and it can break out of a
|
|
// destination literal.
|
|
{atBreak: true, character: '>'},
|
|
{character: '>', inConstruct: 'destinationLiteral'},
|
|
// Question mark and at sign are not used in markdown for constructs.
|
|
// A left bracket can start definitions, references, labels,
|
|
{atBreak: true, character: '['},
|
|
{character: '[', inConstruct: 'phrasing', notInConstruct: fullPhrasingSpans},
|
|
{character: '[', inConstruct: ['label', 'reference']},
|
|
// A backslash can start an escape (when followed by punctuation) or a
|
|
// hard break (when followed by an eol).
|
|
// Note: typical escapes are handled in `safe`!
|
|
{character: '\\', after: '[\\r\\n]', inConstruct: 'phrasing'},
|
|
// A right bracket can exit labels.
|
|
{character: ']', inConstruct: ['label', 'reference']},
|
|
// Caret is not used in markdown for constructs.
|
|
// An underscore can start emphasis, strong, or a thematic break.
|
|
{atBreak: true, character: '_'},
|
|
{character: '_', inConstruct: 'phrasing', notInConstruct: fullPhrasingSpans},
|
|
// A grave accent can start code (fenced or text), or it can break out of
|
|
// a grave accent code fence.
|
|
{atBreak: true, character: '`'},
|
|
{
|
|
character: '`',
|
|
inConstruct: ['codeFencedLangGraveAccent', 'codeFencedMetaGraveAccent']
|
|
},
|
|
{character: '`', inConstruct: 'phrasing', notInConstruct: fullPhrasingSpans},
|
|
// Left brace, vertical bar, right brace are not used in markdown for
|
|
// constructs.
|
|
// A tilde can start code (fenced).
|
|
{atBreak: true, character: '~'}
|
|
]
|