tftsr-devops_investigation/node_modules/esprima/bin/esparse.js
Shaun Arman 8839075805 feat: initial implementation of TFTSR IT Triage & RCA application
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>
2026-03-14 22:36:25 -05:00

140 lines
4.8 KiB
JavaScript
Executable File

#!/usr/bin/env node
/*
Copyright JS Foundation and other contributors, https://js.foundation/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*jslint sloppy:true node:true rhino:true */
var fs, esprima, fname, forceFile, content, options, syntax;
if (typeof require === 'function') {
fs = require('fs');
try {
esprima = require('esprima');
} catch (e) {
esprima = require('../');
}
} else if (typeof load === 'function') {
try {
load('esprima.js');
} catch (e) {
load('../esprima.js');
}
}
// Shims to Node.js objects when running under Rhino.
if (typeof console === 'undefined' && typeof process === 'undefined') {
console = { log: print };
fs = { readFileSync: readFile };
process = { argv: arguments, exit: quit };
process.argv.unshift('esparse.js');
process.argv.unshift('rhino');
}
function showUsage() {
console.log('Usage:');
console.log(' esparse [options] [file.js]');
console.log();
console.log('Available options:');
console.log();
console.log(' --comment Gather all line and block comments in an array');
console.log(' --loc Include line-column location info for each syntax node');
console.log(' --range Include index-based range for each syntax node');
console.log(' --raw Display the raw value of literals');
console.log(' --tokens List all tokens in an array');
console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)');
console.log(' -v, --version Shows program version');
console.log();
process.exit(1);
}
options = {};
process.argv.splice(2).forEach(function (entry) {
if (forceFile || entry === '-' || entry.slice(0, 1) !== '-') {
if (typeof fname === 'string') {
console.log('Error: more than one input file.');
process.exit(1);
} else {
fname = entry;
}
} else if (entry === '-h' || entry === '--help') {
showUsage();
} else if (entry === '-v' || entry === '--version') {
console.log('ECMAScript Parser (using Esprima version', esprima.version, ')');
console.log();
process.exit(0);
} else if (entry === '--comment') {
options.comment = true;
} else if (entry === '--loc') {
options.loc = true;
} else if (entry === '--range') {
options.range = true;
} else if (entry === '--raw') {
options.raw = true;
} else if (entry === '--tokens') {
options.tokens = true;
} else if (entry === '--tolerant') {
options.tolerant = true;
} else if (entry === '--') {
forceFile = true;
} else {
console.log('Error: unknown option ' + entry + '.');
process.exit(1);
}
});
// Special handling for regular expression literal since we need to
// convert it to a string literal, otherwise it will be decoded
// as object "{}" and the regular expression would be lost.
function adjustRegexLiteral(key, value) {
if (key === 'value' && value instanceof RegExp) {
value = value.toString();
}
return value;
}
function run(content) {
syntax = esprima.parse(content, options);
console.log(JSON.stringify(syntax, adjustRegexLiteral, 4));
}
try {
if (fname && (fname !== '-' || forceFile)) {
run(fs.readFileSync(fname, 'utf-8'));
} else {
var content = '';
process.stdin.resume();
process.stdin.on('data', function(chunk) {
content += chunk;
});
process.stdin.on('end', function() {
run(content);
});
}
} catch (e) {
console.log('Error: ' + e.message);
process.exit(1);
}