sfscanner 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/v2/metadata-output.ts", "../../src/v2/commands.ts", "../../../scanner-core/src/canonical-json.ts", "../../../scanner-core/src/policy/rule-catalog.ts", "../../src/v2/contracts.ts", "../../src/v2/config.ts", "../../../../contracts/stable-order.ts", "../../src/v2/metadata-validation.ts"],
4
+ "sourcesContent": ["import { readFileSync } from 'node:fs';\nimport type {\n CliExplainDocumentV2,\n CliMetadataDocumentV2,\n CliProfilesDocumentV2,\n CliRulesDocumentV2,\n CliVersionDocumentV2,\n} from './commands';\nimport {\n explainDocumentV2,\n isAdmittedConfigPathV2,\n profilesDocumentV2,\n rulesDocumentV2,\n runCommandV2,\n validateConfigDocumentV2,\n versionDocumentV2,\n} from './commands';\nimport type { CliCommandV2 } from './arguments';\nimport { validateDocumentShape } from './metadata-validation';\n\nexport type MetadataFormatV2 = 'json' | 'table';\nexport type MetadataOutputOptionsV2 = Readonly<{ color?: boolean; configDirectory?: string }>;\n\nfunction formatTable(headers: readonly string[], rows: readonly (readonly string[])[]): string {\n const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)));\n const sep = widths.map((w) => '-'.repeat(w)).join(' ');\n const formatRow = (cells: readonly string[]) => cells.map((c, i) => c.padEnd(widths[i]!)).join(' ');\n const body = rows.map(formatRow).join('\\n');\n return `${formatRow(headers)}\\n${sep}${body ? `\\n${body}` : ''}\\n`;\n}\n\nfunction renderExplainTable(doc: CliExplainDocumentV2): string {\n const { rule: r, prose: p } = doc;\n const steps = p.remediationSteps.map((s, i) => ` ${i + 1}. ${s}`).join('\\n');\n const ev = doc.evidenceProperties.length ? doc.evidenceProperties.join(', ') : 'none';\n return [`Rule: ${r.ruleId} (${r.severity}, ${r.confidence}, ${r.effect})`, `Title: ${p.title}`, `Message: ${p.message}`, `Explanation: ${p.explanation}`, `Why it matters: ${p.whyItMatters}`, `Possible impact: ${p.possibleImpact}`, `Remediation: ${p.remediation}`, `Remediation steps:\\n${steps}`, `Evidence properties: ${ev}`].join('\\n\\n') + '\\n';\n}\n\nexport function renderMetadataTableV2(document: CliMetadataDocumentV2, _options?: MetadataOutputOptionsV2): string {\n validateDocumentShape(document);\n if (document.schemaVersion === 'n8n-scan-rules-v2') return formatTable(['Rule ID', 'Severity', 'Confidence', 'Effect', 'CWE'], document.rules.map((r) => [r.ruleId, r.severity, r.confidence, r.effect, r.cweIds.join(',') || '-']));\n if (document.schemaVersion === 'n8n-scan-explain-v2') return renderExplainTable(document);\n if (document.schemaVersion === 'n8n-scan-profiles-v2') return formatTable(['Profile', 'Version', 'Admitted', 'Capabilities', 'Digest'], document.profiles.map((p) => [p.id, p.version, p.admitted ? 'yes' : 'no', String(p.capabilities.length), p.digest.slice(0, 16)]));\n if (document.schemaVersion === 'n8n-scan-version-v2') return [`${document.name} v${document.cliVersion} (mode: ${document.mode})`, `Engine: ${document.engine.id} v${document.engine.version} (${document.engine.buildDigest.slice(0, 16)})`, `Config schema: ${document.configSchema}`, `Ruleset digest: ${document.rulesetDigest.slice(0, 16)}`, `Semantics digest: ${document.semanticsDigest.slice(0, 16)}`].join('\\n') + '\\n';\n return 'Configuration is valid.\\n';\n}\n\nexport function serializeMetadataJsonV2(document: CliMetadataDocumentV2): string {\n validateDocumentShape(document);\n return `${JSON.stringify(document, null, 2)}\\n`;\n}\n\nexport function serializeMetadataV2(document: CliMetadataDocumentV2, format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): string {\n if (format === 'table') return renderMetadataTableV2(document, options);\n if (format === 'json') return serializeMetadataJsonV2(document);\n throw new TypeError('Invalid format');\n}\n\nexport function emitRulesDocumentV2(format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): string { return serializeMetadataV2(rulesDocumentV2(), format, options); }\nexport function emitExplainDocumentV2(ruleId: string, format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): Readonly<{ ok: true; output: string } | { ok: false; code: 'USAGE'; message: string }> {\n const res = explainDocumentV2(ruleId); if (!res.ok) return res;\n return Object.freeze({ ok: true as const, output: serializeMetadataV2(res.document, format, options) });\n}\nexport function emitProfilesDocumentV2(format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): string { return serializeMetadataV2(profilesDocumentV2(), format, options); }\nexport function emitVersionDocumentV2(format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): string { return serializeMetadataV2(versionDocumentV2(), format, options); }\nexport function emitConfigValidationDocumentV2(input: unknown, format: MetadataFormatV2 = 'json', options?: MetadataOutputOptionsV2): Readonly<{ ok: true; output: string } | { ok: false; code: 'USAGE'; message: string }> {\n const res = validateConfigDocumentV2(input, options?.configDirectory); if (!res.ok) return res;\n return Object.freeze({ ok: true as const, output: serializeMetadataV2(res.document, format, options) });\n}\n\nexport function emitMetadataCommandResultV2(command: CliCommandV2, configInput?: unknown, options?: MetadataOutputOptionsV2): Readonly<{ ok: true; output: string } | { ok: false; code: 'USAGE'; message: string }> {\n if (command.kind === 'scan') return Object.freeze({ ok: false as const, code: 'USAGE', message: 'Scan command is not a metadata command.' });\n if (command.kind === 'validate-config') {\n if (!isAdmittedConfigPathV2(command.path)) {\n return Object.freeze({ ok: false as const, code: 'USAGE', message: 'Configuration path is not admitted.' });\n }\n let input = configInput;\n if (input === undefined) {\n try { input = readFileSync(command.path, 'utf8'); } catch { return Object.freeze({ ok: false, code: 'USAGE', message: 'Configuration could not be read.' }); }\n }\n const res = validateConfigDocumentV2(input, options?.configDirectory);\n if (!res.ok) return res;\n return Object.freeze({ ok: true as const, output: serializeMetadataV2(res.document, command.format, options) });\n }\n const res = runCommandV2(command, configInput, options?.configDirectory);\n if (!res.ok) return res;\n if ('command' in res) return Object.freeze({ ok: false as const, code: 'USAGE', message: 'Unexpected scan command.' });\n return Object.freeze({ ok: true as const, output: serializeMetadataV2(res.document, command.format, options) });\n}\n", "import { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { canonicalizeJson } from '@hub/scanner-core/canonical-json';\nimport { betaDefaultRuleCatalog, type RuleCatalogEntry } from '@hub/scanner-core/rule-catalog';\nimport { ADMITTED_PROFILE_V2, BUILTIN_LIMITS_AUTHORITY_V2, BUILTIN_RULESET_AUTHORITY_V2, BUILTIN_SEMANTICS_AUTHORITY_V2, loadExplicitConfig } from './config';\nimport type { CliCommandV2 } from './arguments';\n\nexport type CliRuleSummaryV2 = Readonly<{ ruleId: string; revision: string; effect: 'SCORING' | 'REPORT_ONLY'; severity: RuleCatalogEntry['defaultSeverity']; confidence: RuleCatalogEntry['defaultConfidence']; capabilityId: string; evidenceSchemaId: string; remediationId: string; cweIds: readonly string[]; owaspAgenticIds: readonly string[] }>;\nexport type CliArtifactIdentityV2 = Readonly<{ profile: { id: string; version: string }; ruleset: { id: string; version: string; digest: string; signatureStatus: 'VERIFIED' | 'UNVERIFIED' }; semantics: { id: string; version: string; digest: string }; target: { edition: 'UNKNOWN'; deployment: 'UNKNOWN'; role: 'UNKNOWN'; taskRunner: 'UNKNOWN'; communityPackages: readonly never[]; configuration: readonly never[]; contextDigest: string }; limits: { schemaVersion: 'scanner-limits-v2'; digest: string } }>;\nexport type CliRulesDocumentV2 = Readonly<{ schemaVersion: 'n8n-scan-rules-v2'; tool: ToolV2; artifacts: CliArtifactIdentityV2; rules: readonly CliRuleSummaryV2[] }>;\nexport type CliExplainDocumentV2 = Readonly<{ schemaVersion: 'n8n-scan-explain-v2'; tool: ToolV2; artifacts: CliArtifactIdentityV2; rule: CliRuleSummaryV2; prose: ProseV2; evidenceProperties: readonly string[]; provenance: { packDigest: string; semanticsDigest: string } }>;\nexport type CliProfileSummaryV2 = Readonly<{ id: string; version: string; admitted: boolean; advertised: boolean; digest: string; scoringPolicyVersion: string; capabilities: readonly CapabilityV2[] }>;\nexport type CliProfilesDocumentV2 = Readonly<{ schemaVersion: 'n8n-scan-profiles-v2'; tool: ToolV2; profiles: readonly CliProfileSummaryV2[] }>;\nexport type CliVersionDocumentV2 = Readonly<{ schemaVersion: 'n8n-scan-version-v2'; name: 'n8n-scan'; cliVersion: string; engine: { id: 'secureflow-scanner'; version: '2.0.0'; buildDigest: string }; resultSchemas: readonly ['scanner-result-v1', 'scanner-result-v2']; configSchema: 'n8n-scan-config-v2'; rulesetDigest: string; semanticsDigest: string; trustStoreDigest: string; mode: 'offline' }>;\nexport type CliConfigValidationDocumentV2 = Readonly<{ schemaVersion: 'n8n-scan-config-validation-v2'; valid: true; artifacts: CliArtifactIdentityV2 }>;\nexport type CliMetadataDocumentV2 = CliRulesDocumentV2 | CliExplainDocumentV2 | CliProfilesDocumentV2 | CliVersionDocumentV2 | CliConfigValidationDocumentV2;\nexport type CliCommandResultV2 = Readonly<{ ok: true; document: CliMetadataDocumentV2 } | { ok: true; command: Extract<CliCommandV2, { kind: 'scan' }> } | { ok: false; code: 'USAGE'; message: string }>;\n\ntype ToolV2 = Readonly<{ name: 'n8n-scan'; version: string; buildDigest: string }>;\ntype ProseV2 = Readonly<{ title: string; message: string; explanation: string; whyItMatters: string; possibleImpact: string; remediation: string; remediationSteps: readonly string[] }>;\ntype CapabilityV2 = Readonly<{ id: string; version: string; required: boolean; dependsOn: readonly string[]; ruleIds: readonly string[] }>;\nconst CLI_VERSION = '0.1.0';\nconst hash = (value: unknown): string => createHash('sha256').update(canonicalizeJson(value)).digest('hex');\nconst targetBody = Object.freeze({ edition: 'UNKNOWN' as const, deployment: 'UNKNOWN' as const, role: 'UNKNOWN' as const, taskRunner: 'UNKNOWN' as const, communityPackages: Object.freeze([]), configuration: Object.freeze([]) });\nconst TOOL: ToolV2 = Object.freeze({ name: 'n8n-scan', version: CLI_VERSION, buildDigest: hash({ engine: 'secureflow-scanner', version: '2.0.0', profile: ADMITTED_PROFILE_V2, ruleset: BUILTIN_RULESET_AUTHORITY_V2.digest, semantics: BUILTIN_SEMANTICS_AUTHORITY_V2.digest }) });\nconst EVIDENCE: Record<string, readonly string[]> = { N8N_EXECUTE_COMMAND: ['nodeType'], N8N_CODE_NODE: ['nodeType'], RAW_AUTH_HEADER: ['header', 'literalValue'], RAW_SECRET_INDICATOR: ['parameterPath', 'secretKind', 'indicator', 'hasLiteralValue'], UNAPPROVED_DOMAIN: ['hostname'], UNKNOWN_NODE_PACKAGE: ['nodeType', 'nodePackage'], WEBHOOK_EXPOSURE: ['authentication'] };\nconst EVIDENCE_SCHEMA: Record<string, string> = { N8N_EXECUTE_COMMAND: 'v1.node-type', N8N_CODE_NODE: 'v1.node-type', RAW_AUTH_HEADER: 'v1.auth-header', RAW_SECRET_INDICATOR: 'v1.secret-indicator', UNAPPROVED_DOMAIN: 'v1.domain', UNKNOWN_NODE_PACKAGE: 'v1.node-package', WEBHOOK_EXPOSURE: 'v1.webhook-auth' };\nconst PROSE: Record<string, ProseV2> = {\n N8N_EXECUTE_COMMAND: { title: 'Execute Command node can run shell commands', message: 'This workflow can execute shell commands.', explanation: 'The Execute Command node allows the workflow to launch shell commands from the n8n runtime environment.', whyItMatters: 'Shell command access can cross from workflow automation into the host or worker environment that runs n8n.', possibleImpact: 'A malicious or compromised workflow path could lead to command execution, file access, lateral movement, or service disruption.', remediation: 'Remove the Execute Command node or isolate it behind strict approval.', remediationSteps: ['Remove the Execute Command node when shell access is not explicitly required.', 'Replace shell logic with a narrow, reviewed integration or managed service call.', 'If it must remain, isolate the workflow runner and require manual approval before execution.'] },\n N8N_CODE_NODE: { title: 'Custom code node requires security review', message: 'This workflow contains custom script execution.', explanation: 'Code and legacy Function nodes can transform data with arbitrary JavaScript inside the workflow runtime.', whyItMatters: 'Custom code is harder to audit than declarative node configuration and may handle secrets or external data.', possibleImpact: 'Unsafe code can leak data, mishandle credentials, or create behavior that reviewers cannot understand from node settings alone.', remediation: 'Review the code path, remove unnecessary scripting, and require approval.', remediationSteps: ['Review the node source code for secret access, outbound requests, and unsafe parsing.', 'Move repeatable logic into a reviewed service or reusable library when possible.', 'Require approval for changes to custom code nodes in production workflows.'] },\n RAW_AUTH_HEADER: { title: 'Raw Authorization header may expose credentials', message: 'This node configures a raw Authorization header.', explanation: 'The workflow parameters appear to define an Authorization header directly instead of using managed n8n credentials.', whyItMatters: 'Raw credential material in node parameters is easier to copy, persist, log, or expose in exported workflow JSON.', possibleImpact: 'API keys or bearer tokens can be leaked through workflow exports, scan history, logs, or support bundles.', remediation: 'Use n8n credentials or a managed secret reference instead of raw headers.', remediationSteps: ['Move the secret into n8n credentials or an approved secret manager.', 'Rotate any token that has already been stored in raw workflow JSON.', 'Re-scan after replacing the raw header with a managed credential reference.'] },\n RAW_SECRET_INDICATOR: { title: 'Workflow parameters contain raw secret material', message: 'This node contains a parameter that looks like a raw secret.', explanation: 'The scanner found a parameter key or value pattern commonly used for tokens, passwords, API keys, cookies, or credentials.', whyItMatters: 'Raw secrets in workflow JSON can be exposed through exports, scan history, logs, backups, or support bundles.', possibleImpact: 'An exposed token or password can allow unauthorized access to connected systems even if the workflow itself is not malicious.', remediation: 'Move the value into n8n credentials or an approved secret manager, then rotate any exposed secret.', remediationSteps: ['Move the raw value into n8n credentials or an approved secret manager.', 'Rotate the secret if it has already been exported, shared, or stored in history.', 'Re-scan the workflow after replacing the raw value with a managed credential reference.'] },\n UNAPPROVED_DOMAIN: { title: 'External domain is outside the approved allowlist', message: 'This workflow calls a domain outside the approved allowlist.', explanation: 'The node parameters contain a URL whose hostname is not present in the approved domain list supplied for this scan.', whyItMatters: 'Unexpected outbound domains can indicate data exfiltration, shadow integrations, or environment drift.', possibleImpact: 'Workflow data may be sent to an unreviewed third party or an endpoint that is not covered by enterprise controls.', remediation: 'Add the domain to the approved list or replace the external call.', remediationSteps: ['Confirm the business owner and purpose for the external domain.', 'Add the domain to the approved list only after security and compliance review.', 'Replace the call if the destination is unnecessary or untrusted.'] },\n UNKNOWN_NODE_PACKAGE: { title: 'Node package is not from an official n8n namespace', message: 'This workflow uses a community or custom node package.', explanation: 'The node type does not start with an official n8n package namespace, so it comes from a community or custom package.', whyItMatters: 'Community and custom packages can add supply-chain, maintenance, and permission risks that differ from core nodes.', possibleImpact: 'A vulnerable or unmaintained package could process sensitive workflow data or run unexpected code.', remediation: 'Review the package source, version, permissions, and maintenance status.', remediationSteps: ['Verify the package source, maintainer, and version history.', 'Check whether the node requires credentials or broad runtime permissions.', 'Pin approved versions and remove packages that are not actively maintained.'] },\n WEBHOOK_EXPOSURE: { title: 'Webhook trigger lacks clear authentication', message: 'This webhook does not show a clear authentication marker.', explanation: 'The webhook node appears to accept inbound requests without an explicit authentication mode in the workflow parameters.', whyItMatters: 'Unauthenticated inbound endpoints can be abused for spam, data injection, or unexpected workflow execution.', possibleImpact: 'External callers may trigger automations, create records, or send data into connected systems without authorization.', remediation: 'Require webhook authentication or place the endpoint behind trusted controls.', remediationSteps: ['Enable webhook authentication in n8n when the endpoint is not intentionally public.', 'Place the endpoint behind a gateway, allowlist, or rate limiter for production use.', 'Monitor webhook usage for unexpected request volume or payloads.'] },\n};\nconst CAPABILITIES: readonly CapabilityV2[] = Object.freeze([\n { id: 'source-normalization', version: '2.0.0', required: true, dependsOn: [], ruleIds: [] }, { id: 'workflow-insights', version: '2.0.0', required: true, dependsOn: ['source-normalization'], ruleIds: [] },\n { id: 'structural-policies', version: '2.0.0', required: true, dependsOn: ['source-normalization'], ruleIds: Object.freeze(betaDefaultRuleCatalog.map(({ policyId }) => policyId)) }, { id: 'assessment', version: '2.0.0', required: true, dependsOn: ['workflow-insights', 'structural-policies'], ruleIds: [] }, { id: 'presentation-facts', version: '2.0.0', required: true, dependsOn: ['assessment'], ruleIds: [] },\n]);\nconst HARDENED_CAPABILITIES: readonly CapabilityV2[] = Object.freeze([\n CAPABILITIES[0]!, CAPABILITIES[1]!, CAPABILITIES[2]!,\n { id: 'expression-security', version: '2.0.0', required: false, dependsOn: ['source-normalization'], ruleIds: [] },\n { id: 'javascript-security', version: '2.0.0', required: false, dependsOn: ['source-normalization'], ruleIds: ['JAVASCRIPT_DYNAMIC_EXECUTION'] },\n { id: 'python-security', version: '2.0.0', required: false, dependsOn: ['source-normalization'], ruleIds: ['PYTHON_DYNAMIC_EXECUTION'] },\n { id: 'graph-semantics', version: '2.0.0', required: false, dependsOn: ['source-normalization'], ruleIds: [] },\n { id: 'taint-confidentiality', version: '2.0.0', required: false, dependsOn: ['graph-semantics', 'expression-security', 'javascript-security', 'python-security'], ruleIds: [] },\n { id: 'taint-integrity', version: '2.0.0', required: false, dependsOn: ['graph-semantics', 'expression-security', 'javascript-security', 'python-security'], ruleIds: ['TAINTED_COMMAND', 'TAINTED_SQL_QUERY', 'TAINTED_REQUEST_URL', 'TAINTED_FILE_PATH', 'TAINTED_CODE_INPUT', 'TAINTED_REQUEST_HEADER', 'TAINTED_AI_PROMPT'] },\n { id: 'agentic-control', version: '2.0.0', required: false, dependsOn: ['graph-semantics', 'taint-confidentiality', 'taint-integrity'], ruleIds: ['AI_AGENT_UNGATED_TOOL'] },\n CAPABILITIES[3]!, CAPABILITIES[4]!,\n]);\n\nfunction artifacts(profile = ADMITTED_PROFILE_V2.id): CliArtifactIdentityV2 { const target = Object.freeze({ ...targetBody, contextDigest: hash(targetBody) }); return Object.freeze({ profile: Object.freeze({ id: profile, version: '2.0.0' }), ruleset: Object.freeze({ ...BUILTIN_RULESET_AUTHORITY_V2 }), semantics: Object.freeze({ ...BUILTIN_SEMANTICS_AUTHORITY_V2 }), target, limits: Object.freeze({ schemaVersion: 'scanner-limits-v2', digest: BUILTIN_LIMITS_AUTHORITY_V2.digest }) }); }\nfunction ruleSummary(entry: RuleCatalogEntry): CliRuleSummaryV2 { const capabilityId = 'structural-policies'; return Object.freeze({ ruleId: entry.policyId, revision: '1', effect: entry.policyEffect === 'REPORT_ONLY' ? 'REPORT_ONLY' : 'SCORING', severity: entry.defaultSeverity, confidence: entry.defaultConfidence, capabilityId, evidenceSchemaId: EVIDENCE_SCHEMA[entry.policyId] ?? 'v1.policy', remediationId: 'r', cweIds: Object.freeze([...entry.cweIds].sort()), owaspAgenticIds: Object.freeze([...(entry.owaspAgenticIds ?? [])].sort()) }); }\nexport function rulesDocumentV2(): CliRulesDocumentV2 { return Object.freeze({ schemaVersion: 'n8n-scan-rules-v2', tool: TOOL, artifacts: artifacts(), rules: Object.freeze(betaDefaultRuleCatalog.map(ruleSummary)) }); }\nexport function explainDocumentV2(ruleId: string): Readonly<{ ok: true; document: CliExplainDocumentV2 } | { ok: false; code: 'USAGE'; message: string }> { const entry = betaDefaultRuleCatalog.find((item) => item.policyId === ruleId); const prose = PROSE[ruleId]; if (!entry || !prose) return Object.freeze({ ok: false as const, code: 'USAGE', message: 'Unknown rule.' }); const rule = ruleSummary(entry); return Object.freeze({ ok: true as const, document: Object.freeze({ schemaVersion: 'n8n-scan-explain-v2', tool: TOOL, artifacts: artifacts(), rule, prose: Object.freeze({ ...prose, remediationSteps: Object.freeze([...prose.remediationSteps]) }), evidenceProperties: Object.freeze([...(EVIDENCE[ruleId] ?? [])]), provenance: Object.freeze({ packDigest: BUILTIN_RULESET_AUTHORITY_V2.digest, semanticsDigest: BUILTIN_SEMANTICS_AUTHORITY_V2.digest }) }) }); }\nexport function profilesDocumentV2(): CliProfilesDocumentV2 { const body = (id: string, admitted: boolean, capabilities: readonly CapabilityV2[], advertised = true) => Object.freeze({ id, version: '2.0.0', admitted, advertised, digest: hash({ schemaVersion: 'scanner-profile-v2', id, version: '2.0.0', capabilities, scoringPolicyVersion: 'secureflow-risk-v2@2.0.0' }), scoringPolicyVersion: 'secureflow-risk-v2@2.0.0', capabilities: Object.freeze(capabilities.map((item) => Object.freeze({ ...item, dependsOn: Object.freeze([...item.dependsOn]), ruleIds: Object.freeze([...item.ruleIds]) }))) }); return Object.freeze({ schemaVersion: 'n8n-scan-profiles-v2', tool: TOOL, profiles: Object.freeze([body('beta-default', true, CAPABILITIES), body('beta-hardened', false, HARDENED_CAPABILITIES)]) }); }\nexport function versionDocumentV2(): CliVersionDocumentV2 { return Object.freeze({ schemaVersion: 'n8n-scan-version-v2', name: 'n8n-scan', cliVersion: CLI_VERSION, engine: Object.freeze({ id: 'secureflow-scanner', version: '2.0.0', buildDigest: TOOL.buildDigest }), resultSchemas: Object.freeze(['scanner-result-v1', 'scanner-result-v2']) as CliVersionDocumentV2['resultSchemas'], configSchema: 'n8n-scan-config-v2', rulesetDigest: BUILTIN_RULESET_AUTHORITY_V2.digest, semanticsDigest: BUILTIN_SEMANTICS_AUTHORITY_V2.digest, trustStoreDigest: hash({ schemaVersion: 'scanner-trust-store-v2', version: '2.0.0', keys: [] }), mode: 'offline' }); }\nexport function validateConfigDocumentV2(input: unknown, configDirectory?: string): Readonly<{ ok: true; document: CliConfigValidationDocumentV2 } | { ok: false; code: 'USAGE'; message: string }> { const result = loadExplicitConfig(input, { configDirectory }); if (!result.ok) return Object.freeze({ ok: false, code: 'USAGE', message: 'Configuration is invalid.' }); return Object.freeze({ ok: true, document: Object.freeze({ schemaVersion: 'n8n-scan-config-validation-v2', valid: true, artifacts: artifacts() }) }); }\nexport function isAdmittedConfigPathV2(path: unknown): path is string {\n if (typeof path !== 'string' || path.length === 0 || path.length > 4096 || /[\\u0000-\\u001f\\u007f]/.test(path)) return false;\n const normalized = path.replaceAll('\\\\', '/');\n if (/^(?:[a-z][a-z\\d+.-]*:|\\/|[a-z]:|\\\\\\\\)/i.test(normalized) || /(?:^|\\/)\\.\\.(?:\\/|$)/.test(normalized) || /(?:^|\\/)%2e(?:%2e)?(?:\\/|$)/i.test(normalized)) return false;\n return normalized.split('/').some((part) => part !== '' && part !== '.');\n}\nexport function runCommandV2(command: CliCommandV2, configInput?: unknown, configDirectory?: string): CliCommandResultV2 {\n if (command.kind === 'scan') return command.profile === 'beta-default' ? Object.freeze({ ok: true, command }) : Object.freeze({ ok: false, code: 'USAGE', message: 'Profile is not admitted.' });\n if (command.kind === 'rules') return Object.freeze({ ok: true, document: rulesDocumentV2() });\n if (command.kind === 'profiles') return Object.freeze({ ok: true, document: profilesDocumentV2() });\n if (command.kind === 'version') return Object.freeze({ ok: true, document: versionDocumentV2() });\n if (command.kind === 'explain') return explainDocumentV2(command.ruleId);\n if (!isAdmittedConfigPathV2(command.path)) return Object.freeze({ ok: false, code: 'USAGE', message: 'Configuration path is not admitted.' });\n let input = configInput;\n if (input === undefined) {\n try { input = readFileSync(command.path, 'utf8'); } catch { return Object.freeze({ ok: false, code: 'USAGE', message: 'Configuration could not be read.' }); }\n }\n return validateConfigDocumentV2(input, configDirectory);\n}\n", "/**\n * Serialize JSON-compatible values with locale-independent object ordering.\n * Arrays retain their input order; they are never treated as sets.\n */\nexport function canonicalizeJson(value: unknown): string {\n return encodeCanonical(value, new Set<object>());\n}\n\n/** Encode the canonical representation using the platform's UTF-8 encoder. */\nexport function canonicalJsonBytes(value: unknown): Uint8Array {\n return new TextEncoder().encode(canonicalizeJson(value));\n}\n\nfunction encodeCanonical(value: unknown, seen: Set<object>): string {\n if (value === null) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) throw new TypeError('Cannot encode non-finite number as canonical JSON');\n return JSON.stringify(Object.is(value, -0) ? 0 : value);\n }\n if (typeof value !== 'object' || value === undefined) {\n throw new TypeError(`Cannot encode ${typeof value} as canonical JSON`);\n }\n if (seen.has(value)) throw new TypeError('Cannot encode cyclic value as canonical JSON');\n seen.add(value);\n\n try {\n if (Array.isArray(value)) return encodeArray(value, seen);\n return encodeObject(value as Record<string, unknown>, seen);\n } finally {\n seen.delete(value);\n }\n}\n\nfunction encodeArray(value: readonly unknown[], seen: Set<object>): string {\n const values = Array.from({ length: value.length }, (_, index) => {\n if (!Object.prototype.hasOwnProperty.call(value, index)) {\n throw new TypeError('Cannot encode sparse array as canonical JSON');\n }\n return encodeCanonical(value[index], seen);\n });\n return `[${values.join(',')}]`;\n}\n\nfunction encodeObject(value: Record<string, unknown>, seen: Set<object>): string {\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new TypeError('Cannot encode a non-plain object as canonical JSON');\n }\n if (Object.getOwnPropertySymbols(value).some((symbol) =>\n Object.prototype.propertyIsEnumerable.call(value, symbol))) {\n throw new TypeError('Cannot encode symbol properties as canonical JSON');\n }\n\n const pairs = Object.keys(value)\n .sort(compareCanonicalStrings)\n .map((key) => `${JSON.stringify(key)}:${encodeCanonical(value[key], seen)}`);\n return `{${pairs.join(',')}}`;\n}\n\nfunction compareCanonicalStrings(left: string, right: string): number {\n if (left === right) return 0;\n return left < right ? -1 : 1;\n}\n", "import type { FindingConfidence, PolicyEffect, ScanSeverity } from './policy';\n\nexport type RuleCatalogEntry = {\n policyId: string;\n defaultSeverity: ScanSeverity;\n defaultConfidence: FindingConfidence;\n precision: 'HIGH' | 'MEDIUM' | 'LOW';\n policyEffect: PolicyEffect;\n curationAction: 'NONE' | 'REVIEW';\n serveAction: 'DISPLAY' | 'HIDE';\n /** CWE identifiers (`CWE-###`) this rule's finding maps to. See docs/scanner/policy-inventory.md\n * for the reviewed rationale behind each mapping, including the ones this catalog deliberately\n * narrows or rejects. Empty only for a policy ID listed in `RULES_WITHOUT_CWE`. */\n cweIds: readonly string[];\n /** OWASP Agentic Top 10 category names. Only the two agentic rules carry this; every other\n * rule leaves it undefined rather than an empty array, so \"not agentic\" and \"agentic with an\n * unresolved mapping\" stay distinguishable. */\n owaspAgenticIds?: readonly string[];\n};\n\n/**\n * Policy IDs with no CWE mapping, on purpose, not by omission. `UNAPPROVED_DOMAIN` was reviewed\n * against CWE-918 (SSRF) and that mapping was rejected: SSRF requires an attacker-influenced\n * destination, but this rule fires on any URL outside an allowlist, including one hardcoded by\n * the workflow's own author with no external input involved. CWE-918 is reserved for\n * `TAINTED_REQUEST_URL`, the rule with an actual tainted-destination claim. See the `[^domain]`\n * footnote in docs/scanner/policy-inventory.md for the full rationale.\n */\nexport const RULES_WITHOUT_CWE = ['UNAPPROVED_DOMAIN'] as const;\n\nconst betaRule = (\n policyId: string,\n defaultSeverity: ScanSeverity,\n defaultConfidence: FindingConfidence,\n precision: RuleCatalogEntry['precision'],\n cweIds: readonly string[],\n): RuleCatalogEntry => ({\n policyId,\n defaultSeverity,\n defaultConfidence,\n precision,\n policyEffect: 'LEGACY_SCORE',\n curationAction: 'NONE',\n serveAction: 'DISPLAY',\n cweIds,\n});\n\nexport const betaDefaultRuleCatalog: readonly RuleCatalogEntry[] = [\n betaRule('N8N_EXECUTE_COMMAND', 'CRITICAL', 'HIGH', 'HIGH', ['CWE-78']),\n betaRule('N8N_CODE_NODE', 'LOW', 'HIGH', 'HIGH', ['CWE-94']),\n // Literal Authorization values are a hardcoded credential (CWE-798); expression/credential-\n // driven values that still leaked as a raw header are an insufficiently protected transmission\n // (CWE-522). Both apply to this rule depending on evidence shape, so both are catalogued.\n betaRule('RAW_AUTH_HEADER', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-798', 'CWE-522']),\n betaRule('RAW_SECRET_INDICATOR', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-798']),\n betaRule('UNAPPROVED_DOMAIN', 'MEDIUM', 'HIGH', 'HIGH', []),\n betaRule('UNKNOWN_NODE_PACKAGE', 'LOW', 'MEDIUM', 'MEDIUM', ['CWE-1357']),\n betaRule('WEBHOOK_EXPOSURE', 'MEDIUM', 'MEDIUM', 'MEDIUM', ['CWE-306']),\n];\n\nconst reportOnlyRule = (\n policyId: string,\n defaultSeverity: ScanSeverity,\n defaultConfidence: FindingConfidence,\n precision: RuleCatalogEntry['precision'],\n cweIds: readonly string[],\n owaspAgenticIds?: readonly string[],\n): RuleCatalogEntry => ({\n policyId,\n defaultSeverity,\n defaultConfidence,\n precision,\n policyEffect: 'REPORT_ONLY',\n curationAction: 'REVIEW',\n serveAction: 'DISPLAY',\n cweIds,\n ...(owaspAgenticIds ? { owaspAgenticIds } : {}),\n});\n\nexport const TAINT_POLICY_IDS = [\n 'TAINTED_COMMAND',\n 'TAINTED_SQL_QUERY',\n 'TAINTED_REQUEST_URL',\n 'TAINTED_FILE_PATH',\n 'TAINTED_CODE_INPUT',\n 'TAINTED_REQUEST_HEADER',\n 'TAINTED_AI_PROMPT',\n 'AI_AGENT_UNGATED_TOOL',\n] as const;\n\nexport type TaintPolicyId = (typeof TAINT_POLICY_IDS)[number];\n\nexport const betaHardenedRuleCatalog: readonly RuleCatalogEntry[] = [\n ...betaDefaultRuleCatalog,\n // CWE-95 (\"Eval Injection\") precisely fits only this rule's EVAL/FUNCTION_CONSTRUCTOR\n // indicators; CHILD_PROCESS_* is closer to CWE-78 and FILESYSTEM_ACCESS to CWE-73. One CWE per\n // policy ID is a simplification of the eight indicators this rule reports under; see the\n // `[^js]`/`[^py]` footnotes in docs/scanner/policy-inventory.md.\n reportOnlyRule('JAVASCRIPT_DYNAMIC_EXECUTION', 'HIGH', 'HIGH', 'HIGH', ['CWE-95']),\n reportOnlyRule('PYTHON_DYNAMIC_EXECUTION', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-95']),\n reportOnlyRule('TAINTED_COMMAND', 'CRITICAL', 'MEDIUM', 'MEDIUM', ['CWE-78']),\n reportOnlyRule('TAINTED_SQL_QUERY', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-89']),\n reportOnlyRule('TAINTED_REQUEST_URL', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-918']),\n reportOnlyRule('TAINTED_FILE_PATH', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-22']),\n reportOnlyRule('TAINTED_CODE_INPUT', 'HIGH', 'MEDIUM', 'MEDIUM', ['CWE-94']),\n reportOnlyRule('TAINTED_REQUEST_HEADER', 'MEDIUM', 'MEDIUM', 'MEDIUM', ['CWE-113']),\n // No CWE is dedicated to LLM prompt injection; CWE-77 (\"Command Injection\") is the nearest\n // structural analogy (untrusted data reaching an interpreter that blends instructions and\n // data). OWASP Agentic's \"Prompt Injection\" is the precise, purpose-built taxonomy tag and\n // should be treated as primary; CWE-77 is a bridge for CWE-only tooling.\n reportOnlyRule('TAINTED_AI_PROMPT', 'MEDIUM', 'LOW', 'LOW', ['CWE-77'], ['Prompt Injection']),\n // CWE-269 (Improper Privilege Management) frames the agent as holding privilege it should not\n // autonomously exercise; the alternative CWE-862 (Missing Authorization) was reviewed and is\n // also defensible, but the OWASP Agentic \"Excessive Agency\" pairing does the precise work\n // either way, so CWE-269 is kept per docs/scanner/policy-inventory.md.\n reportOnlyRule('AI_AGENT_UNGATED_TOOL', 'MEDIUM', 'LOW', 'LOW', ['CWE-269'], ['Excessive Agency']),\n];\n", "export const SCAN_CONFIG_SCHEMA_V2 = 'n8n-scan-config-v2' as const;\nexport type ScanFormatV2 = 'json' | 'ndjson' | 'sarif' | 'table';\nexport type ScanSeverityV2 = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO';\n\nexport type ScanConfigV2 = Readonly<{\n schemaVersion: typeof SCAN_CONFIG_SCHEMA_V2;\n format?: ScanFormatV2;\n profile?: string;\n output?: string;\n inputs?: readonly string[];\n configPath?: string;\n failOn?: ScanSeverityV2;\n requireComplete?: boolean;\n concurrency?: number;\n rules?: string;\n catalogue?: string;\n limits?: string;\n target?: string;\n include?: readonly string[];\n exclude?: readonly string[];\n allowUnsignedDevelopmentRules?: boolean;\n noColor?: boolean;\n}>;\n\nexport const ADMITTED_PROFILE_V2 = Object.freeze({ id: 'beta-default', version: '2.0.0', digest: '3ca5d69db2554383e22c44afe507cc98e381ea58a7e42aaac0ee8f7497fb4f44' });\n\n/**\n * The profile spellings a caller may write, and the one place they are listed. Both the\n * config loader and the MCP tool read this, so a profile cannot be admitted on one\n * surface and refused on the other; the bare id and its `id@version` pin are the same\n * admission, and both canonicalize to `ADMITTED_PROFILE_V2.id`.\n */\nexport const ADMITTED_PROFILE_SPECIFIERS_V2: readonly string[] = Object.freeze([\n ADMITTED_PROFILE_V2.id,\n `${ADMITTED_PROFILE_V2.id}@${ADMITTED_PROFILE_V2.version}`,\n]);\n\nexport function isAdmittedProfileSpecifierV2(value: unknown): value is string {\n return typeof value === 'string' && ADMITTED_PROFILE_SPECIFIERS_V2.includes(value);\n}\nexport const BUILTIN_AUTHORITIES_V2 = Object.freeze({\n profile: ADMITTED_PROFILE_V2,\n rules: Object.freeze({ id: 'scanner-core-builtins', version: '2.0.0', digest: 'a36d00564bbf8e8c38f05820480782cdc53fdbd3712558850066c4e3f5c3413d', signatureStatus: 'VERIFIED' as const }),\n semantics: Object.freeze({ id: 'scanner-core-builtins', version: '2.0.0', digest: '1bb11f63269d427cb28e141dfe0a6a1512e53c298abdb4d6450545ceb56d11c4' }),\n limits: Object.freeze({ schemaVersion: 'scanner-limits-v2' as const, digest: 'fca787753ca88f71cf0d174427f4ac730a7aef1c823aaf73aa1ea72af92b4077' }),\n});\nexport const PROFILE_MANIFEST_DIGEST_V2 = ADMITTED_PROFILE_V2.digest;\nexport const BUILTIN_RULESET_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.rules;\nexport const BUILTIN_SEMANTICS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.semantics;\nexport const BUILTIN_LIMITS_AUTHORITY_V2 = BUILTIN_AUTHORITIES_V2.limits;\nexport const RULE_PACK_DIGEST_V2 = BUILTIN_RULESET_AUTHORITY_V2.digest;\nexport const SEMANTIC_CATALOGUE_DIGEST_V2 = BUILTIN_SEMANTICS_AUTHORITY_V2.digest;\n\nexport const DEFAULT_SCAN_CONFIG_V2: ScanConfigV2 = Object.freeze({\n schemaVersion: SCAN_CONFIG_SCHEMA_V2,\n format: 'json', profile: ADMITTED_PROFILE_V2.id, failOn: 'INFO', requireComplete: false, concurrency: 1,\n rules: 'builtin', catalogue: 'builtin', limits: 'builtin',\n include: Object.freeze(['**/*.json']), exclude: Object.freeze(['.git/**', 'node_modules/**']),\n allowUnsignedDevelopmentRules: false, noColor: false,\n});\n\nexport const SCAN_CONFIG_V2_FIELDS = Object.freeze([\n 'schemaVersion', 'format', 'profile', 'output', 'inputs', 'configPath', 'failOn', 'requireComplete', 'concurrency',\n 'rules', 'catalogue', 'limits', 'target', 'include', 'exclude', 'allowUnsignedDevelopmentRules', 'noColor',\n] as const);\nexport const SCAN_CONFIG_V2_MAX_STRING = 4096;\nexport const SCAN_CONFIG_V2_MAX_PATTERNS = 1024;\nexport const SCAN_CONFIG_V2_MAX_CONCURRENCY = 16;\n", "import {\n ADMITTED_PROFILE_V2, BUILTIN_AUTHORITIES_V2, DEFAULT_SCAN_CONFIG_V2, SCAN_CONFIG_V2_FIELDS,\n SCAN_CONFIG_V2_MAX_CONCURRENCY, SCAN_CONFIG_V2_MAX_PATTERNS, SCAN_CONFIG_V2_MAX_STRING,\n isAdmittedProfileSpecifierV2,\n type ScanConfigV2,\n} from './contracts';\n\nexport type ConfigLoadOptions = Readonly<{ configDirectory?: string; cli?: unknown }>;\nexport type ConfigLoadResult = Readonly<{ ok: true; config: ScanConfigV2 } | { ok: false; code: 'INVALID_CONFIG'; errors: readonly string[] }>;\ntype Plain = Record<string, unknown>;\nconst BUILTIN: Record<string, true> = { builtin: true };\nconst CLI_NAMES: Readonly<Record<string, string>> = Object.freeze({\n 'fail-on': 'failOn', 'require-complete': 'requireComplete', 'max-concurrency': 'concurrency',\n 'allow-unsigned-development-rules': 'allowUnsignedDevelopmentRules',\n 'no-color': 'noColor', config: 'configPath',\n});\nconst REPEATABLE_CLI: Record<string, true> = { inputs: true, include: true, exclude: true };\n\nexport function loadExplicitConfig(input: unknown, options: ConfigLoadOptions = {}): ConfigLoadResult {\n const errors: string[] = [];\n const config = parseConfig(input, errors);\n const cli = readCli(options.cli, errors);\n if (typeof options.configDirectory !== 'undefined' && typeof options.configDirectory !== 'string') errors.push('config directory is invalid');\n if (!config || !cli) return failure(errors);\n const configPathCount = Number(Object.prototype.hasOwnProperty.call(config, 'configPath'))\n + Number(Object.prototype.hasOwnProperty.call(cli, 'configPath'))\n + Number(Object.prototype.hasOwnProperty.call(cli, '_configPath'));\n if (configPathCount > 1) errors.push('config path supplied more than once');\n const merged: Plain = Object.assign(Object.create(null), DEFAULT_SCAN_CONFIG_V2, config);\n for (const key of Object.keys(cli)) if (key !== 'configPath' && key !== '_configPath') merged[key] = cli[key];\n if (Object.prototype.hasOwnProperty.call(cli, 'configPath')) merged.configPath = cli.configPath;\n else if (Object.prototype.hasOwnProperty.call(cli, '_configPath')) merged.configPath = cli._configPath;\n const result = normalize(merged, config, cli, errors);\n return result ? Object.freeze({ ok: true as const, config: deepFreeze(result) }) : failure(errors);\n}\n\nexport function validateScanConfigV2(input: unknown): ConfigLoadResult { return loadExplicitConfig(input); }\n\nfunction parseConfig(input: unknown, errors: string[]): Plain | undefined {\n if (typeof input === 'string') {\n if (input.length > SCAN_CONFIG_V2_MAX_STRING * 16 || duplicateKeys(input)) { errors.push('configuration JSON is invalid'); return undefined; }\n try { input = JSON.parse(input) as unknown; } catch { errors.push('configuration JSON is invalid'); return undefined; }\n }\n const value = record(input);\n if (!value) { errors.push('configuration must be a closed object'); return undefined; }\n for (const key of Object.keys(value)) if (!(SCAN_CONFIG_V2_FIELDS as readonly string[]).includes(key)) errors.push(`unknown configuration key: ${safeErrorKey(key)}`);\n if (value.schemaVersion !== 'n8n-scan-config-v2') errors.push('unsupported schemaVersion');\n return Object.keys(value).every((key) => (SCAN_CONFIG_V2_FIELDS as readonly string[]).includes(key)) ? value : undefined;\n}\n\nfunction readCli(input: unknown, errors: string[]): Plain | undefined {\n if (input === undefined) return {};\n const value = record(input); if (!value) { errors.push('CLI configuration is invalid'); return undefined; }\n const out: Plain = Object.create(null);\n for (const [rawKey, rawValue] of Object.entries(value)) {\n if (rawKey === 'config') {\n if (Object.prototype.hasOwnProperty.call(out, '_configPath')) errors.push('config path supplied more than once');\n out._configPath = rawValue;\n continue;\n }\n const key = CLI_NAMES[rawKey] ?? rawKey;\n if (!(SCAN_CONFIG_V2_FIELDS as readonly string[]).includes(key)) { errors.push(`unknown CLI configuration key: ${safeErrorKey(rawKey)}`); continue; }\n out[key] = REPEATABLE_CLI[key] === true && typeof rawValue === 'string' ? [rawValue] : rawValue;\n }\n return out;\n}\nfunction normalize(value: Plain, config: Plain, cli: Plain, errors: string[]): ScanConfigV2 | undefined {\n const out: Plain = Object.assign(Object.create(null), { schemaVersion: 'n8n-scan-config-v2' });\n const format = value.format; if (format !== 'json' && format !== 'ndjson' && format !== 'sarif' && format !== 'table') errors.push('format is invalid'); else out.format = format;\n const profile = value.profile;\n if (!isAdmittedProfileSpecifierV2(profile)) errors.push('profile is not admitted'); else out.profile = ADMITTED_PROFILE_V2.id;\n if (value.failOn !== 'CRITICAL' && value.failOn !== 'HIGH' && value.failOn !== 'MEDIUM' && value.failOn !== 'LOW' && value.failOn !== 'INFO') errors.push('failOn is invalid'); else out.failOn = value.failOn;\n for (const key of ['requireComplete', 'allowUnsignedDevelopmentRules', 'noColor']) {\n if (typeof value[key] !== 'boolean') errors.push(`${key} is invalid`); else out[key] = value[key];\n }\n if (!Number.isSafeInteger(value.concurrency) || (value.concurrency as number) < 1 || (value.concurrency as number) > SCAN_CONFIG_V2_MAX_CONCURRENCY) errors.push('concurrency is outside the admitted range'); else out.concurrency = value.concurrency;\n for (const key of ['rules', 'catalogue'] as const) {\n const raw = value[key];\n if (typeof raw !== 'string' || BUILTIN[raw] !== true) errors.push(`${key} is not admitted in built-in-only v2`); else out[key] = 'builtin';\n }\n for (const key of ['limits', 'target', 'output', 'configPath'] as const) if (value[key] !== undefined || Object.prototype.hasOwnProperty.call(value, key)) {\n const raw = value[key]; if (typeof raw !== 'string') errors.push(`${key} is invalid`); else { const path = localPath(raw, false, errors, key === 'limits'); if (path) out[key] = path; }\n }\n for (const key of ['inputs', 'include', 'exclude'] as const) {\n const raw = value[key]; if (raw === undefined) { if (Object.prototype.hasOwnProperty.call(value, key)) errors.push(`${key} is invalid`); continue; }\n const items = arrayValues(raw);\n if (!items || items.length > SCAN_CONFIG_V2_MAX_PATTERNS) { errors.push(`${key} is outside the admitted limit`); continue; }\n const paths: string[] = [];\n for (const item of items) if (typeof item !== 'string') errors.push(`${key} contains an invalid path`); else { const path = localPath(item, true, errors); if (path) paths.push(path); }\n out[key] = Object.freeze(paths);\n }\n if (!Object.prototype.hasOwnProperty.call(config, 'include') && !Object.prototype.hasOwnProperty.call(cli, 'include')) out.include = DEFAULT_SCAN_CONFIG_V2.include;\n if (!Object.prototype.hasOwnProperty.call(config, 'exclude') && !Object.prototype.hasOwnProperty.call(cli, 'exclude')) out.exclude = DEFAULT_SCAN_CONFIG_V2.exclude;\n return errors.length === 0 ? out as ScanConfigV2 : undefined;\n}\n\nfunction localPath(raw: string, pattern: boolean, errors: string[], allowBuiltin = false): string | undefined {\n if (raw.length === 0 || raw.length > SCAN_CONFIG_V2_MAX_STRING || /[\\u0000-\\u001f\\u007f]/.test(raw)) { errors.push('path is invalid'); return undefined; }\n if (BUILTIN[raw] === true) { if (allowBuiltin) return 'builtin'; errors.push('built-in marker is not valid for this path'); return undefined; }\n const normalized = raw.replaceAll('\\\\', '/');\n if (/^(?:[a-z][a-z\\d+.-]*:|\\/|[a-z]:)/i.test(normalized)) { errors.push('absolute or remote path is not admitted'); return undefined; }\n const parts: string[] = [];\n for (const part of normalized.split('/')) {\n if (!part || part === '.') continue;\n if (part === '..') { if (pattern || parts.length === 0) { errors.push('path escapes its config directory'); return undefined; } parts.pop(); continue; }\n parts.push(part);\n }\n if (parts.length === 0) { errors.push('path is invalid'); return undefined; }\n return parts.join('/');\n}\nfunction arrayValues(value: unknown): readonly unknown[] | undefined {\n try {\n if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || Object.getOwnPropertySymbols(value).length > 0) return undefined;\n const names = Object.getOwnPropertyNames(value);\n if (names.length !== value.length + 1) return undefined;\n const output: unknown[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index));\n if (!descriptor || !('value' in descriptor)) return undefined;\n output.push(descriptor.value);\n }\n return output;\n } catch { return undefined; }\n}\nfunction safeErrorKey(value: string): string {\n return /^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(value) ? value : 'field';\n}\n\nexport {\n ADMITTED_PROFILE_V2,\n BUILTIN_AUTHORITIES_V2,\n BUILTIN_LIMITS_AUTHORITY_V2,\n BUILTIN_RULESET_AUTHORITY_V2,\n BUILTIN_SEMANTICS_AUTHORITY_V2,\n DEFAULT_SCAN_CONFIG_V2,\n PROFILE_MANIFEST_DIGEST_V2,\n RULE_PACK_DIGEST_V2,\n SCAN_CONFIG_SCHEMA_V2,\n SEMANTIC_CATALOGUE_DIGEST_V2,\n type ScanConfigV2,\n} from './contracts';\n\nfunction record(value: unknown): Plain | undefined {\n try {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const proto = Object.getPrototypeOf(value); if (proto !== Object.prototype && proto !== null) return undefined;\n if (Object.getOwnPropertySymbols(value).length > 0) return undefined;\n const out: Plain = Object.create(null);\n for (const key of Object.getOwnPropertyNames(value)) { const descriptor = Object.getOwnPropertyDescriptor(value, key); if (!descriptor || !('value' in descriptor) || !descriptor.enumerable) return undefined; out[key] = descriptor.value; }\n return out;\n } catch { return undefined; }\n}\n\nfunction duplicateKeys(text: string): boolean {\n let index = 0;\n const skip = () => { while (/\\s/.test(text[index] ?? '')) index += 1; };\n const string = () => { index += 1; while (index < text.length) { const char = text[index++]; if (char === '\\\\') index += 1; else if (char === '\"') return; } throw new Error(); };\n const value = (): void => { skip(); const char = text[index]; if (char === '{') return object(); if (char === '[') return array(); if (char === '\"') { string(); return; } const start = index; while (index < text.length && !/[\\s,\\]}]/.test(text[index]!)) index += 1; if (start === index) throw new Error(); };\n const object = (): void => { index += 1; const keys = new Set<string>(); skip(); if (text[index] === '}') { index += 1; return; } while (index < text.length) { skip(); if (text[index] !== '\"') throw new Error(); const start = index; string(); const key = text.slice(start, index); if (keys.has(key)) throw new Error(); keys.add(key); skip(); if (text[index++] !== ':') throw new Error(); value(); skip(); if (text[index] === '}') { index += 1; return; } if (text[index++] !== ',') throw new Error(); } throw new Error(); };\n const array = (): void => { index += 1; skip(); if (text[index] === ']') { index += 1; return; } while (index < text.length) { value(); skip(); if (text[index] === ']') { index += 1; return; } if (text[index++] !== ',') throw new Error(); } throw new Error(); };\n try { value(); skip(); if (index !== text.length) throw new Error(); return false; } catch { return true; }\n}\nfunction failure(errors: readonly string[]): ConfigLoadResult {\n return Object.freeze({ ok: false, code: 'INVALID_CONFIG' as const, errors: Object.freeze([...new Set(errors)].sort()) });\n}\nfunction deepFreeze<T>(value: T, seen = new WeakSet<object>()): T { if (value && typeof value === 'object') { if (seen.has(value)) return value; seen.add(value); for (const key of Object.getOwnPropertyNames(value)) deepFreeze((value as Plain)[key], seen); Object.freeze(value); } return value; }\n\n", "/**\n * Locale-independent ordering for serialized artifacts.\n *\n * Relational string comparison is deliberate: it follows JavaScript's stable\n * UTF-16 code-unit ordering and does not depend on the host locale or ICU data.\n */\nexport function compareCanonicalStrings(left: string, right: string): number {\n if (left === right) return 0;\n return left < right ? -1 : 1;\n}\n", "import { compareCanonicalStrings } from '@hub/contracts/stable-order';\nimport type { CliMetadataDocumentV2 } from './commands';\nimport {\n explainDocumentV2,\n profilesDocumentV2,\n rulesDocumentV2,\n validateConfigDocumentV2,\n versionDocumentV2,\n} from './commands';\n\nconst KEYS: Record<string, readonly string[]> = {\n 'n8n-scan-rules-v2': ['schemaVersion', 'tool', 'artifacts', 'rules'],\n 'n8n-scan-explain-v2': ['schemaVersion', 'tool', 'artifacts', 'rule', 'prose', 'evidenceProperties', 'provenance'],\n 'n8n-scan-profiles-v2': ['schemaVersion', 'tool', 'profiles'],\n 'n8n-scan-version-v2': ['schemaVersion', 'name', 'cliVersion', 'engine', 'resultSchemas', 'configSchema', 'rulesetDigest', 'semanticsDigest', 'trustStoreDigest', 'mode'],\n 'n8n-scan-config-validation-v2': ['schemaVersion', 'valid', 'artifacts'],\n tool: ['name', 'version', 'buildDigest'], artifacts: ['profile', 'ruleset', 'semantics', 'target', 'limits'],\n profileId: ['id', 'version'], ruleset: ['id', 'version', 'digest', 'signatureStatus'], semantics: ['id', 'version', 'digest'],\n target: ['edition', 'deployment', 'role', 'taskRunner', 'communityPackages', 'configuration', 'contextDigest'],\n limits: ['schemaVersion', 'digest'], rule: ['ruleId', 'revision', 'effect', 'severity', 'confidence', 'capabilityId', 'evidenceSchemaId', 'remediationId', 'cweIds', 'owaspAgenticIds'],\n prose: ['title', 'message', 'explanation', 'whyItMatters', 'possibleImpact', 'remediation', 'remediationSteps'],\n provenance: ['packDigest', 'semanticsDigest'], profile: ['id', 'version', 'admitted', 'advertised', 'digest', 'scoringPolicyVersion', 'capabilities'],\n capability: ['id', 'version', 'required', 'dependsOn', 'ruleIds'], engine: ['id', 'version', 'buildDigest'],\n};\nconst DIGEST = /^[0-9a-f]{64}$/;\nconst fail = (): never => { throw new TypeError('Invalid metadata document'); };\n\nexport function checkPlain(o: unknown): Record<string, unknown> {\n if (!o || typeof o !== 'object' || Array.isArray(o)) return fail();\n if (Object.getPrototypeOf(o) !== Object.prototype && Object.getPrototypeOf(o) !== null) return fail();\n if (Object.getOwnPropertySymbols(o).length > 0) return fail();\n for (const key of Object.getOwnPropertyNames(o)) {\n const descriptor = Object.getOwnPropertyDescriptor(o, key);\n if (!descriptor || !('value' in descriptor) || !descriptor.enumerable) return fail();\n }\n return o as Record<string, unknown>;\n}\n\nexport function checkDenseArray<T>(arr: unknown): T[] {\n if (!Array.isArray(arr) || Object.getPrototypeOf(arr) !== Array.prototype || Object.getOwnPropertySymbols(arr).length > 0) return fail();\n const names = Object.getOwnPropertyNames(arr);\n if (names.length !== arr.length + 1) return fail();\n for (const name of names) {\n if (name === 'length') continue;\n if (!/^(?:0|[1-9]\\d*)$/.test(name) || Number(name) >= arr.length) return fail();\n const descriptor = Object.getOwnPropertyDescriptor(arr, name);\n if (!descriptor || !('value' in descriptor) || !descriptor.enumerable) return fail();\n }\n const length = Object.getOwnPropertyDescriptor(arr, 'length');\n if (!length || !('value' in length) || !Number.isSafeInteger(length.value)) return fail();\n return arr as T[];\n}\n\nfunction safeString(value: unknown): void {\n if (typeof value !== 'string' || value.length === 0 || value.length > 4096 || /[\\u0000-\\u001f\\u007f\\ud800-\\udfff]/.test(value)\n || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(value) || /^[A-Za-z]:[\\\\/]|^\\/|^\\\\\\\\/.test(value)\n || /(?:^|[\\\\/])\\.\\.(?:[\\\\/]|$)/.test(value)) return fail();\n}\n\nfunction walk(value: unknown, seen = new WeakSet<object>()): void {\n if (value === null) return;\n if (typeof value === 'string') return safeString(value);\n if (typeof value === 'boolean') return;\n if (typeof value === 'number') { if (!Number.isFinite(value)) fail(); return; }\n if (typeof value !== 'object') return fail();\n if (seen.has(value)) return fail();\n seen.add(value);\n if (Array.isArray(value)) for (const item of checkDenseArray<unknown>(value)) walk(item, seen);\n else for (const item of Object.values(checkPlain(value))) walk(item, seen);\n seen.delete(value);\n}\n\nfunction checkKeys(value: unknown, expected: readonly string[]): Record<string, unknown> {\n const object = checkPlain(value); const actual = Object.keys(object);\n if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) return fail();\n return object;\n}\nfunction digest(value: unknown): void { if (typeof value !== 'string' || !DIGEST.test(value)) fail(); }\nfunction sortedStrings(value: unknown): void {\n const values = checkDenseArray<unknown>(value);\n if (values.some((item) => typeof item !== 'string')) return fail();\n for (let i = 1; i < values.length; i += 1) if (compareCanonicalStrings(values[i - 1] as string, values[i] as string) >= 0) return fail();\n}\nfunction artifacts(value: unknown): void {\n const object = checkKeys(value, KEYS.artifacts!);\n checkKeys(object.profile, KEYS.profileId!);\n const ruleset = checkKeys(object.ruleset, KEYS.ruleset!);\n digest(ruleset.digest); if (ruleset.signatureStatus !== 'VERIFIED' && ruleset.signatureStatus !== 'UNVERIFIED') return fail();\n checkKeys(object.semantics, KEYS.semantics!);\n const target = checkKeys(object.target, KEYS.target!);\n checkDenseArray(target.communityPackages); checkDenseArray(target.configuration); digest(target.contextDigest);\n const limits = checkKeys(object.limits, KEYS.limits!); if (limits.schemaVersion !== 'scanner-limits-v2') return fail(); digest(limits.digest);\n}\nfunction exact(left: unknown, right: unknown): boolean {\n if (left === right) return true;\n if (typeof left !== typeof right || left === null || right === null) return false;\n if (Array.isArray(left) || Array.isArray(right)) {\n if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;\n return left.every((item, index) => exact(item, right[index]));\n }\n if (typeof left !== 'object' || typeof right !== 'object') return Object.is(left, right);\n const a = Object.keys(left as object); const b = Object.keys(right as object);\n return a.length === b.length && a.every((key, index) => key === b[index] && exact((left as Record<string, unknown>)[key], (right as Record<string, unknown>)[key]));\n}\n\nfunction authority(schema: string, root: Record<string, unknown>): CliMetadataDocumentV2 {\n if (schema === 'n8n-scan-rules-v2') return rulesDocumentV2();\n if (schema === 'n8n-scan-explain-v2') {\n const result = explainDocumentV2(String((root.rule as Record<string, unknown>).ruleId));\n if (!result.ok) return fail();\n return result.document;\n }\n if (schema === 'n8n-scan-profiles-v2') return profilesDocumentV2();\n if (schema === 'n8n-scan-version-v2') return versionDocumentV2();\n const result = validateConfigDocumentV2({ schemaVersion: 'n8n-scan-config-v2' });\n if (!result.ok) return fail();\n return result.document;\n}\n\nexport function validateDocumentShape(doc: unknown): asserts doc is CliMetadataDocumentV2 {\n walk(doc);\n const root = checkPlain(doc); const schema = root.schemaVersion;\n if (typeof schema !== 'string' || !Object.prototype.hasOwnProperty.call(KEYS, schema)) return fail();\n checkKeys(root, KEYS[schema]!);\n if (schema === 'n8n-scan-rules-v2') {\n checkKeys(root.tool, KEYS.tool!); artifacts(root.artifacts);\n const rules = checkDenseArray(root.rules); for (const rule of rules) { const item = checkKeys(rule, KEYS.rule!); sortedStrings(item.cweIds); sortedStrings(item.owaspAgenticIds); }\n } else if (schema === 'n8n-scan-explain-v2') {\n checkKeys(root.tool, KEYS.tool!); artifacts(root.artifacts); checkKeys(root.rule, KEYS.rule!); const prose = checkKeys(root.prose, KEYS.prose!); checkDenseArray(prose.remediationSteps); checkDenseArray(root.evidenceProperties); checkKeys(root.provenance, KEYS.provenance!);\n } else if (schema === 'n8n-scan-profiles-v2') {\n checkKeys(root.tool, KEYS.tool!); const profiles = checkDenseArray(root.profiles);\n for (const profile of profiles) { const item = checkKeys(profile, KEYS.profile!); for (const capability of checkDenseArray(item.capabilities)) { const value = checkKeys(capability, KEYS.capability!); checkDenseArray(value.dependsOn); checkDenseArray(value.ruleIds); } }\n } else if (schema === 'n8n-scan-version-v2') {\n checkKeys(root.engine, KEYS.engine!); checkDenseArray(root.resultSchemas); digest(root.rulesetDigest); digest(root.semanticsDigest); digest(root.trustStoreDigest);\n } else {\n if (root.valid !== true) return fail(); artifacts(root.artifacts);\n }\n if (!exact(root, authority(schema, root))) return fail();\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["readFileSync", "compareCanonicalStrings", "compareCanonicalStrings", "artifacts", "result", "readFileSync", "res"]
7
+ }
@@ -0,0 +1,4 @@
1
+ import type { CliMetadataDocumentV2 } from './commands';
2
+ export declare function checkPlain(o: unknown): Record<string, unknown>;
3
+ export declare function checkDenseArray<T>(arr: unknown): T[];
4
+ export declare function validateDocumentShape(doc: unknown): asserts doc is CliMetadataDocumentV2;
@@ -0,0 +1,3 @@
1
+ import type { BatchResultV2 } from './batch-runner';
2
+ import { type ProjectionOptionsV2 } from './json-output';
3
+ export declare function serializeNdjsonV2(batch: BatchResultV2, options?: ProjectionOptionsV2): string;
@@ -0,0 +1,69 @@
1
+ import { type ScannerResultV2 } from '@hub/contracts/scanner-v2-result';
2
+ import type { SourceSpanV2, SubjectV2 } from '@hub/contracts/scanner-v2-source';
3
+ import type { BatchSarifInputV2, SarifV2Limits } from './sarif-output';
4
+ export type Bounds = {
5
+ rules: number;
6
+ results: number;
7
+ notifications: number;
8
+ taxonomies: number;
9
+ taxa: number;
10
+ tags: number;
11
+ flows: number;
12
+ steps: number;
13
+ };
14
+ export type NotifItem = {
15
+ code: string;
16
+ level: 'warning' | 'error';
17
+ location?: Record<string, unknown>;
18
+ locKey: string;
19
+ id?: string;
20
+ label?: string;
21
+ };
22
+ export type BatchId = {
23
+ engineId: string;
24
+ engineVersion: string;
25
+ engineBuildDigest: string;
26
+ profileId: string;
27
+ profileVersion: string;
28
+ rulesetId: string;
29
+ rulesetVersion: string;
30
+ rulesetDigest: string;
31
+ rulesetSig: string;
32
+ semanticsId: string;
33
+ semanticsVersion: string;
34
+ semanticsDigest: string;
35
+ targetContextDigest: string;
36
+ targetEdition: string;
37
+ targetDeployment: string;
38
+ targetRole: string;
39
+ targetTaskRunner: string;
40
+ limitsSchemaVersion: string;
41
+ limitsDigest: string;
42
+ };
43
+ export type InputIdentity = {
44
+ rawUri: unknown;
45
+ label: string;
46
+ };
47
+ export declare const FALLBACK: Bounds;
48
+ export declare const SEV_ORDER: Record<string, number>;
49
+ export declare const LEVELS: Record<string, 'error' | 'warning' | 'note'>;
50
+ export declare const ALLOWED_ERRORS: Set<string>;
51
+ export declare const prop: (v: unknown, k: string) => unknown;
52
+ export declare const inv: () => never;
53
+ export declare function checkResult(r: unknown): ScannerResultV2;
54
+ export declare function inputIdentity(value: unknown): InputIdentity;
55
+ export declare function extractItems(input: BatchSarifInputV2): {
56
+ items: readonly unknown[];
57
+ repoRoot?: string;
58
+ selRoot?: string;
59
+ limits?: SarifV2Limits;
60
+ };
61
+ export declare function safePath(v: unknown): v is string;
62
+ export declare function safeUri(raw: unknown, repoRoot?: string, selRoot?: string): string | undefined;
63
+ export declare function readPos(v: unknown): SourceSpanV2['start'] | undefined;
64
+ export declare function readSpan(source: unknown): SourceSpanV2 | undefined;
65
+ export declare function subjectKey(s: SubjectV2): string;
66
+ export declare function subjectSpan(subj: SubjectV2): SourceSpanV2 | undefined;
67
+ export declare function physical(uri: string, s: SourceSpanV2): Record<string, unknown>;
68
+ export declare function freeze<T>(v: T, seen?: WeakSet<object>): T;
69
+ export declare function sameId(a: BatchId, b: BatchId): boolean;
@@ -0,0 +1,40 @@
1
+ import type { ScannerResultV2 } from '@hub/contracts/scanner-v2-result';
2
+ export type SarifLog = Readonly<{
3
+ version: '2.1.0';
4
+ $schema: string;
5
+ runs: readonly SarifRun[];
6
+ }>;
7
+ export type SarifRun = Readonly<{
8
+ tool: {
9
+ driver: Record<string, unknown>;
10
+ };
11
+ results: readonly Record<string, unknown>[];
12
+ invocations: readonly Record<string, unknown>[];
13
+ taxonomies?: readonly Record<string, unknown>[];
14
+ }>;
15
+ export type SarifV2Limits = Readonly<{
16
+ maxRules?: number;
17
+ maxResults?: number;
18
+ maxNotifications?: number;
19
+ maxTaxonomies?: number;
20
+ maxTaxa?: number;
21
+ maxTags?: number;
22
+ maxFlows?: number;
23
+ maxTraceSteps?: number;
24
+ }>;
25
+ export type BatchSarifEnvelopeV2 = Readonly<{
26
+ items?: readonly unknown[];
27
+ results?: readonly unknown[];
28
+ input?: Readonly<{
29
+ label: string;
30
+ uri?: string;
31
+ }>;
32
+ result?: ScannerResultV2;
33
+ repositoryRoot?: string;
34
+ selectionRoot?: string;
35
+ limits?: SarifV2Limits;
36
+ }>;
37
+ export type BatchSarifInputV2 = BatchSarifEnvelopeV2 | readonly unknown[];
38
+ export declare function buildBatchSarifV2(input: BatchSarifInputV2): SarifLog;
39
+ export declare function buildSarifV2(input: BatchSarifInputV2): SarifLog;
40
+ export declare function serializeSarifV2(input: BatchSarifInputV2): string;
@@ -0,0 +1,2 @@
1
+ import type { BatchResultV2 } from './batch-runner';
2
+ export declare function renderTableV2(batch: BatchResultV2): string;
@@ -0,0 +1,24 @@
1
+ export type WorkerHostStatus = 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'TIMEOUT';
2
+ export type WorkerHostRun<T> = Readonly<{
3
+ status: 'COMPLETED';
4
+ value: T;
5
+ } | {
6
+ status: Exclude<WorkerHostStatus, 'COMPLETED'>;
7
+ }>;
8
+ export type SigintSource = Readonly<{
9
+ on: (event: 'SIGINT', listener: () => void) => unknown;
10
+ off?: (event: 'SIGINT', listener: () => void) => unknown;
11
+ removeListener?: (event: 'SIGINT', listener: () => void) => unknown;
12
+ }>;
13
+ export type SigintController = Readonly<{
14
+ signal: AbortSignal;
15
+ dispose: () => void;
16
+ }>;
17
+ export type WorkerHostOptions = Readonly<{
18
+ signal?: AbortSignal;
19
+ sigint?: SigintSource;
20
+ timeoutMs?: number;
21
+ now?: () => number;
22
+ }>;
23
+ export declare function createSigintController(source?: SigintSource): SigintController;
24
+ export declare function runHostedScan<T>(task: () => T | PromiseLike<T>, options?: WorkerHostOptions): Promise<WorkerHostRun<T>>;
package/package.json CHANGED
@@ -1,6 +1,67 @@
1
1
  {
2
2
  "name": "sfscanner",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "SecureFlow Scanner — Deterministic, offline security & dataflow analyzer for n8n workflows",
5
+ "keywords": [
6
+ "n8n",
7
+ "security",
8
+ "sast",
9
+ "sarif",
10
+ "scanner",
11
+ "workflow"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/jitwark/n8n-Secureflow.git"
16
+ },
17
+ "homepage": "https://github.com/jitwark/n8n-Secureflow#readme",
18
+ "license": "MIT",
19
+ "private": false,
20
+ "type": "module",
21
+ "engines": {
22
+ "node": ">=22 <23"
23
+ },
24
+ "main": "./dist/main.js",
25
+ "bin": {
26
+ "sfscanner": "dist/main.js",
27
+ "sfscanner-mcp": "dist/mcp.js"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE",
33
+ "THIRD_PARTY_NOTICES.md"
34
+ ],
35
+ "exports": {
36
+ "./v2/arguments": {
37
+ "types": "./dist/v2/arguments.d.ts",
38
+ "import": "./dist/v2/arguments.js"
39
+ },
40
+ "./v2/cli-runner": {
41
+ "types": "./dist/v2/cli-runner.d.ts",
42
+ "import": "./dist/v2/cli-runner.js"
43
+ },
44
+ "./v2/help": {
45
+ "types": "./dist/v2/help.d.ts",
46
+ "import": "./dist/v2/help.js"
47
+ },
48
+ "./v2/metadata-output": {
49
+ "types": "./dist/v2/metadata-output.d.ts",
50
+ "import": "./dist/v2/metadata-output.js"
51
+ }
52
+ },
53
+ "scripts": {
54
+ "build": "node build.mjs",
55
+ "lint": "eslint .",
56
+ "test": "vitest run --config vitest.config.ts",
57
+ "typecheck": "tsc -p tsconfig.json --noEmit"
58
+ },
59
+ "devDependencies": {
60
+ "@hub/contracts": "*",
61
+ "@hub/scanner-core": "*",
62
+ "@types/node": "^22.0.0",
63
+ "esbuild": "^0.28.2",
64
+ "typescript": "^5.7.2",
65
+ "vitest": "^4.1.11"
66
+ }
67
+ }