save development progress

This commit is contained in:
StellaOps Bot
2025-12-25 23:09:58 +02:00
parent d71853ad7e
commit aa70af062e
351 changed files with 37683 additions and 150156 deletions

View File

@@ -0,0 +1,18 @@
{
"schemaVersion": "1.0",
"id": "stellaops.notify.connector.email",
"displayName": "StellaOps Email Notify Connector",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Notify.Connectors.Email.dll"
},
"capabilities": [
"notify-connector",
"email"
],
"metadata": {
"org.stellaops.notify.channel.type": "email"
}
}

View File

@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"id": "stellaops.notify.connector.slack",
"displayName": "StellaOps Slack Notify Connector",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Notify.Connectors.Slack.dll"
},
"capabilities": [
"notify-connector",
"slack"
],
"metadata": {
"org.stellaops.notify.channel.type": "slack",
"org.stellaops.notify.connector.requiredScopes": "chat:write,chat:write.public"
}
}

View File

@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"id": "stellaops.notify.connector.teams",
"displayName": "StellaOps Teams Notify Connector",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Notify.Connectors.Teams.dll"
},
"capabilities": [
"notify-connector",
"teams"
],
"metadata": {
"org.stellaops.notify.channel.type": "teams",
"org.stellaops.notify.connector.cardVersion": "1.5"
}
}

View File

@@ -0,0 +1,18 @@
{
"schemaVersion": "1.0",
"id": "stellaops.notify.connector.webhook",
"displayName": "StellaOps Webhook Notify Connector",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Notify.Connectors.Webhook.dll"
},
"capabilities": [
"notify-connector",
"webhook"
],
"metadata": {
"org.stellaops.notify.channel.type": "webhook"
}
}

View File

@@ -0,0 +1,22 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.bun",
"displayName": "StellaOps Bun Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Bun.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Bun.BunAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"bun",
"npm"
],
"metadata": {
"org.stellaops.analyzer.language": "bun",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,21 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.deno",
"displayName": "StellaOps Deno Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Deno.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Deno.DenoAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"deno"
],
"metadata": {
"org.stellaops.analyzer.language": "deno",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,23 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.dotnet",
"displayName": "StellaOps .NET Analyzer (preview)",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.DotNet.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.DotNet.DotNetAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"dotnet",
"nuget"
],
"metadata": {
"org.stellaops.analyzer.language": "dotnet",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true",
"org.stellaops.analyzer.status": "preview"
}
}

View File

@@ -0,0 +1,23 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.go",
"displayName": "StellaOps Go Analyzer (preview)",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Go.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Go.GoAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"golang",
"go"
],
"metadata": {
"org.stellaops.analyzer.language": "go",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true",
"org.stellaops.analyzer.status": "preview"
}
}

View File

@@ -0,0 +1,22 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.java",
"displayName": "StellaOps Java / Maven Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Java.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Java.JavaLanguageAnalyzer"
},
"capabilities": [
"language-analyzer",
"java",
"maven"
],
"metadata": {
"org.stellaops.analyzer.language": "java",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,22 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.node",
"displayName": "StellaOps Node.js Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Node.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Node.NodeAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"node",
"npm"
],
"metadata": {
"org.stellaops.analyzer.language": "node",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,22 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.php",
"displayName": "StellaOps PHP Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Php.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Php.PhpAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"php",
"composer"
],
"metadata": {
"org.stellaops.analyzer.language": "php",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,23 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.python",
"displayName": "StellaOps Python Analyzer (preview)",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Python.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Python.PythonAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"python",
"pypi"
],
"metadata": {
"org.stellaops.analyzer.language": "python",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true",
"org.stellaops.analyzer.status": "preview"
}
}

View File

@@ -0,0 +1,24 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.ruby",
"displayName": "StellaOps Ruby Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Ruby.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Ruby.RubyAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"ruby",
"rubygems",
"bundler"
],
"metadata": {
"org.stellaops.analyzer.language": "ruby",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true",
"org.stellaops.analyzer.runtime-capture": "optional"
}
}

View File

@@ -0,0 +1,23 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.rust",
"displayName": "StellaOps Rust Analyzer (preview)",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Rust.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Rust.RustAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"rust",
"cargo"
],
"metadata": {
"org.stellaops.analyzer.language": "rust",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true",
"org.stellaops.analyzer.status": "preview"
}
}

View File

@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzers.os.apk",
"displayName": "StellaOps Alpine APK Analyzer",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.OS.Apk.dll"
},
"capabilities": [
"os-analyzer",
"apk"
],
"metadata": {
"org.stellaops.analyzer.kind": "os",
"org.stellaops.analyzer.id": "apk"
}
}

View File

@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzers.os.dpkg",
"displayName": "StellaOps Debian dpkg Analyzer",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.OS.Dpkg.dll"
},
"capabilities": [
"os-analyzer",
"dpkg"
],
"metadata": {
"org.stellaops.analyzer.kind": "os",
"org.stellaops.analyzer.id": "dpkg"
}
}

View File

@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzers.os.rpm",
"displayName": "StellaOps RPM Analyzer",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.OS.Rpm.dll"
},
"capabilities": [
"os-analyzer",
"rpm"
],
"metadata": {
"org.stellaops.analyzer.kind": "os",
"org.stellaops.analyzer.id": "rpm"
}
}

View File

@@ -0,0 +1,35 @@
{
"schemaVersion": "1.0",
"id": "stellaops.sbom-indexer",
"displayName": "StellaOps SBOM BuildX Generator",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"executable": "StellaOps.Scanner.Sbomer.BuildXPlugin.dll",
"arguments": [
"handshake"
]
},
"capabilities": [
"generator",
"sbom"
],
"cas": {
"protocol": "filesystem",
"defaultRoot": "cas",
"compression": "zstd"
},
"image": {
"name": "stellaops/sbom-indexer",
"digest": null,
"platforms": [
"linux/amd64",
"linux/arm64"
]
},
"metadata": {
"org.stellaops.plugin.kind": "buildx-generator",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,35 @@
{
"schemaVersion": "1.0",
"id": "stellaops.sbom-indexer",
"displayName": "StellaOps SBOM BuildX Generator",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"executable": "StellaOps.Scanner.Sbomer.BuildXPlugin.dll",
"arguments": [
"handshake"
]
},
"capabilities": [
"generator",
"sbom"
],
"cas": {
"protocol": "filesystem",
"defaultRoot": "cas",
"compression": "zstd"
},
"image": {
"name": "stellaops/sbom-indexer",
"digest": null,
"platforms": [
"linux/amd64",
"linux/arm64"
]
},
"metadata": {
"org.stellaops.plugin.kind": "buildx-generator",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,191 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v10.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v10.0": {
"StellaOps.Scanner.EntryTrace/1.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
"Microsoft.Extensions.Logging.Abstractions": "9.0.0",
"Microsoft.Extensions.Options": "9.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "9.0.0",
"StellaOps.Plugin": "1.0.0"
},
"runtime": {
"StellaOps.Scanner.EntryTrace.dll": {}
}
},
"Microsoft.Extensions.Configuration.Abstractions/9.0.0": {
"dependencies": {
"Microsoft.Extensions.Primitives": "9.0.0"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.Configuration.Binder/9.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Configuration.Binder.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/9.0.0": {
"runtime": {
"lib/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.Logging.Abstractions/9.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.Options/9.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
"Microsoft.Extensions.Primitives": "9.0.0"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Options.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.Options.ConfigurationExtensions/9.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0",
"Microsoft.Extensions.Configuration.Binder": "9.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
"Microsoft.Extensions.Options": "9.0.0",
"Microsoft.Extensions.Primitives": "9.0.0"
},
"runtime": {
"lib/net9.0/Microsoft.Extensions.Options.ConfigurationExtensions.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"Microsoft.Extensions.Primitives/9.0.0": {
"runtime": {
"lib/net9.0/Microsoft.Extensions.Primitives.dll": {
"assemblyVersion": "9.0.0.0",
"fileVersion": "9.0.24.52809"
}
}
},
"StellaOps.DependencyInjection/1.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0"
},
"runtime": {
"StellaOps.DependencyInjection.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
},
"StellaOps.Plugin/1.0.0": {
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
"Microsoft.Extensions.Logging.Abstractions": "9.0.0",
"StellaOps.DependencyInjection": "1.0.0"
},
"runtime": {
"StellaOps.Plugin.dll": {
"assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"StellaOps.Scanner.EntryTrace/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.Extensions.Configuration.Abstractions/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-lqvd7W3FGKUO1+ZoUEMaZ5XDJeWvjpy2/M/ptCGz3tXLD4HWVaSzjufsAsjemasBEg+2SxXVtYVvGt5r2nKDlg==",
"path": "microsoft.extensions.configuration.abstractions/9.0.0",
"hashPath": "microsoft.extensions.configuration.abstractions.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Configuration.Binder/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-RiScL99DcyngY9zJA2ROrri7Br8tn5N4hP4YNvGdTN/bvg1A3dwvDOxHnNZ3Im7x2SJ5i4LkX1uPiR/MfSFBLQ==",
"path": "microsoft.extensions.configuration.binder/9.0.0",
"hashPath": "microsoft.extensions.configuration.binder.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.DependencyInjection.Abstractions/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+6f2qv2a3dLwd5w6JanPIPs47CxRbnk+ZocMJUhv9NxP88VlOcJYZs9jY+MYSjxvady08bUZn6qgiNh7DadGgg==",
"path": "microsoft.extensions.dependencyinjection.abstractions/9.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Logging.Abstractions/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-g0UfujELzlLbHoVG8kPKVBaW470Ewi+jnptGS9KUi6jcb+k2StujtK3m26DFSGGwQ/+bVgZfsWqNzlP6YOejvw==",
"path": "microsoft.extensions.logging.abstractions/9.0.0",
"hashPath": "microsoft.extensions.logging.abstractions.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Options/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-y2146b3jrPI3Q0lokKXdKLpmXqakYbDIPDV6r3M8SqvSf45WwOTzkyfDpxnZXJsJQEpAsAqjUq5Pu8RCJMjubg==",
"path": "microsoft.extensions.options/9.0.0",
"hashPath": "microsoft.extensions.options.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Options.ConfigurationExtensions/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Ob3FXsXkcSMQmGZi7qP07EQ39kZpSBlTcAZLbJLdI4FIf0Jug8biv2HTavWmnTirchctPlq9bl/26CXtQRguzA==",
"path": "microsoft.extensions.options.configurationextensions/9.0.0",
"hashPath": "microsoft.extensions.options.configurationextensions.9.0.0.nupkg.sha512"
},
"Microsoft.Extensions.Primitives/9.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-N3qEBzmLMYiASUlKxxFIISP4AiwuPTHF5uCh+2CWSwwzAJiIYx0kBJsS30cp1nvhSySFAVi30jecD307jV+8Kg==",
"path": "microsoft.extensions.primitives/9.0.0",
"hashPath": "microsoft.extensions.primitives.9.0.0.nupkg.sha512"
},
"StellaOps.DependencyInjection/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"StellaOps.Plugin/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -0,0 +1,22 @@
{
"schemaVersion": "1.0",
"id": "stellaops.entrytrace.analyzers",
"displayName": "StellaOps EntryTrace Analyzer Pack",
"version": "0.1.0-alpha",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"executable": "StellaOps.Scanner.EntryTrace.dll",
"arguments": [
"handshake"
]
},
"capabilities": [
"entrytrace",
"analyzer"
],
"metadata": {
"org.stellaops.plugin.kind": "entrytrace-analyzer",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,31 @@
{
"schemaVersion": "1.0",
"id": "stellaops.analyzer.lang.node",
"displayName": "StellaOps Node Analyzer",
"version": "0.1.0",
"requiresRestart": true,
"entryPoint": {
"type": "dotnet",
"assembly": "StellaOps.Scanner.Analyzers.Lang.Node.dll",
"typeName": "StellaOps.Scanner.Analyzers.Lang.Node.NodeAnalyzerPlugin"
},
"capabilities": [
"language-analyzer",
"node",
"npm",
"pnpm",
"pnp",
"runtime-optional"
],
"hooks": {
"runtime": {
"cjs": "runtime-hooks/runtime-require-hook.js",
"esm": "runtime-hooks/runtime-esm-loader.mjs"
}
},
"metadata": {
"org.stellaops.analyzer.language": "node",
"org.stellaops.analyzer.kind": "language",
"org.stellaops.restart.required": "true"
}
}

View File

@@ -0,0 +1,61 @@
// Runtime ESM loader for StellaOps Scanner runtime evidence
// Usage: node --experimental-loader=./runtime-esm-loader.mjs app.mjs
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import { fileURLToPath, pathToFileURL } from 'url';
const outPath = process.env.SCANNER_NODE_RUNTIME_OUT || path.join(process.cwd(), 'node-runtime-evidence.ndjson');
const root = process.env.SCANNER_NODE_ROOT || process.cwd();
const loaderId = hashLoaderId(import.meta.url);
function hashLoaderId(value) {
return crypto.createHash('sha256').update(value || '').digest('hex');
}
function scrub(p) {
if (!p) return p;
try {
const absolute = p.startsWith('file:') ? fileURLToPath(p) : p;
const rel = path.relative(root, absolute);
return rel.startsWith('..') ? p : rel.split(path.sep).join('/');
} catch {
return p;
}
}
function emit(record) {
try {
fs.appendFileSync(outPath, JSON.stringify(record) + '\n');
} catch {
// best-effort: ignore write failures
}
}
export async function resolve(specifier, context, next) {
const parent = context.parentURL ? scrub(context.parentURL) : undefined;
const target = scrub(specifier);
emit({
type: 'edge',
from: parent,
to: target,
reason: 'runtime-import',
loaderId
});
return next(specifier, context, next);
}
export async function load(url, context, next) {
const pathOrUrl = scrub(url);
emit({
type: 'component',
path: pathOrUrl,
reason: 'runtime-load',
loaderId
});
return next(url, context, next);
}

View File

@@ -0,0 +1,49 @@
// Runtime require hook for StellaOps Scanner runtime evidence
// Usage: node -r ./runtime-require-hook.js app.js
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const outPath = process.env.SCANNER_NODE_RUNTIME_OUT || path.join(process.cwd(), 'node-runtime-evidence.ndjson');
const root = process.env.SCANNER_NODE_ROOT || process.cwd();
function hashLoaderId(value) {
return crypto.createHash('sha256').update(value || '').digest('hex');
}
function scrub(p) {
if (!p) return p;
try {
const rel = path.relative(root, p);
return rel.startsWith('..') ? p : rel.split(path.sep).join('/');
} catch {
return p;
}
}
function emit(record) {
try {
fs.appendFileSync(outPath, JSON.stringify(record) + '\n');
} catch {
// best-effort: ignore write failures
}
}
const originalLoad = module.constructor._load;
module.constructor._load = function (request, parent, isMain) {
const from = parent && parent.filename ? scrub(parent.filename) : undefined;
const to = scrub(request);
const loaderId = hashLoaderId(__filename);
emit({
type: 'edge',
from,
to,
reason: 'runtime-require',
loaderId,
isMain: !!isMain
});
return originalLoad.apply(this, arguments);
};