@sebastienrousseau/crypto-lsp 0.0.7

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.
package/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ This project is dual-licensed under either of:
2
+
3
+ * Apache License, Version 2.0 — see LICENSE-APACHE
4
+ * MIT license — see LICENSE-MIT
5
+
6
+ at your option.
7
+
8
+ SPDX-License-Identifier: Apache-2.0 OR MIT
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
2
+
3
+ # `@sebastienrousseau/crypto-lsp`
4
+
5
+ > Language Server Protocol (LSP) providing real-time cryptographic static analysis, quantum-vulnerability flagging, PEM/OpenPGP validation, and automated quick fixes for IDEs (VS Code, NeoVim, JetBrains, Emacs).
6
+
7
+ [![Version](https://img.shields.io/npm/v/@sebastienrousseau/crypto-lsp.svg)](https://www.npmjs.com/package/@sebastienrousseau/crypto-lsp)
8
+ [![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ `@sebastienrousseau/crypto-lsp` brings institutional-grade cryptographic intelligence directly into developer IDEs via the Language Server Protocol (LSP 3.17). It actively monitors code buffers for broken primitives, inadequate key sizes, quantum vulnerabilities (Harvest-Now-Decrypt-Later risks), hardcoded secret material, and malformed PEM/OpenPGP blocks.
15
+
16
+ ## Key Capabilities
17
+
18
+ - **Real-Time Static Cryptographic Linting**:
19
+ - `CRYPTO-001`: Detects broken hash functions (`MD5`, `SHA-1`, `MD4`, `RIPEMD160`).
20
+ - `CRYPTO-002`: Detects insecure symmetric ciphers and modes (`DES`, `3DES`, `RC4`, `ECB` mode).
21
+ - `CRYPTO-003`: Flags inadequate RSA key sizes (`< 2048` bits).
22
+ - `CRYPTO-004`: Quantum Vulnerability Flagging for classical public-key cryptography (`RSA`, `ECDSA`, `ECDH`, `Ed25519`) in long-term data security contexts.
23
+ - `CRYPTO-005`: Flags hardcoded secret/private keys in source files.
24
+ - `CRYPTO-006`: Validates PEM and OpenPGP armored block syntax.
25
+ - **Intelligent QuickFix Actions**:
26
+ - Automated replacement of broken hashes (e.g. `MD5` -> `SHA-256`).
27
+ - Automated replacement of insecure cipher modes (e.g. `aes-128-ecb` -> `aes-256-gcm`).
28
+ - **Interactive Hover Documentation**:
29
+ - Displays NIST FIPS 203/204/205 standards, quantum security levels, and regulatory compliance mapping (DORA, CRA, CNSA 2.0).
30
+ - **Context-Aware Completion Provider**:
31
+ - Autocompletes modern symmetric, asymmetric, and post-quantum algorithms with recommended parameters.
32
+
33
+ ## Installation & CLI Usage
34
+
35
+ ```bash
36
+ # Global installation
37
+ pnpm add -g @sebastienrousseau/crypto-lsp
38
+
39
+ # Run stdio LSP server
40
+ crypto-lsp --stdio
41
+ ```
42
+
43
+ ## Editor Integration
44
+
45
+ ### VS Code
46
+
47
+ Configure in your `.vscode/settings.json`:
48
+
49
+ ```json
50
+ {
51
+ "crypto.lsp.serverPath": "crypto-lsp"
52
+ }
53
+ ```
54
+
55
+ ### NeoVim (lspconfig)
56
+
57
+ ```lua
58
+ vim.lsp.start({
59
+ name = 'crypto-lsp',
60
+ cmd = {'crypto-lsp', '--stdio'},
61
+ root_dir = vim.fs.dirname(vim.fs.find({'package.json', '.git'}, { upward = true })[1]),
62
+ })
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Development
68
+
69
+ ```bash
70
+ pnpm --filter @sebastienrousseau/crypto-lsp run build
71
+ pnpm --filter @sebastienrousseau/crypto-lsp run test
72
+ pnpm --filter @sebastienrousseau/crypto-lsp run lint
73
+ pnpm --filter @sebastienrousseau/crypto-lsp run format
74
+ ```
75
+
76
+ All 18 packages in the Crypto Service workspace maintain a **100% coverage floor** across statements, branches, functions, and lines.
77
+
78
+ ---
79
+
80
+ ## Documentation
81
+
82
+ - [Full Suite Documentation](https://docs.crypto-service.co/)
83
+ - [API Reference (TypeDoc)](https://docs.crypto-service.co/packages/crypto-lsp/)
84
+ - [Developer Guide](../../DEVELOPMENT.md)
85
+ - [Security Policy](../../SECURITY.md)
86
+ - [Architecture & Design](../../ARCHITECTURE.md)
87
+
88
+ ---
89
+
90
+ ## Stability guarantees
91
+
92
+ Versions advance strictly one step at a time on the `0.0.x` line (`v0.0.1` → `v0.0.2` → `v0.0.3` ... → `v0.0.999` → `v0.1.0`). Work for every release iteration begins on a dedicated `feat/v<version>` branch.
93
+
94
+ All 18 packages in the workspace move in lockstep. Public API signatures, cipher output formats, and serialization schemas are strictly versioned. Breaking changes to serialized formats or algorithm defaults are considered major breaking changes. Minimum toolchain upgrades (e.g. Node.js LTS floor) are governed by [POLICIES.md](../../docs/POLICIES.md).
95
+
96
+ ---
97
+
98
+ ## License
99
+
100
+ Dual-licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) or [MIT](https://opensource.org/licenses/MIT), at your option.
101
+
102
+ Copyright (c) 2022-2026 Sebastien Rousseau and The Crypto Service Suite contributors.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function run(): void;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAKA,wBAAgB,GAAG,IAAI,IAAI,CAG1B"}
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.run = run;
5
+ const server_1 = require("./server");
6
+ function run() {
7
+ const server = new server_1.CryptoLspServer();
8
+ server.listenStdio(process.stdin, process.stdout);
9
+ }
10
+ if (require.main === module) {
11
+ run();
12
+ }
13
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,3 @@
1
+ import { CodeAction, Diagnostic, Range } from "./types";
2
+ export declare function getCodeActions(uri: string, text: string, range: Range, diagnostics: Diagnostic[]): CodeAction[];
3
+ //# sourceMappingURL=code-action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-action.d.ts","sourceRoot":"","sources":["../src/code-action.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKxD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,UAAU,EAAE,GACxB,UAAU,EAAE,CAyId"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCodeActions = getCodeActions;
4
+ function getCodeActions(uri, text, range, diagnostics) {
5
+ const actions = [];
6
+ const lines = text.split(/\r?\n/);
7
+ const targetLine = lines[range.start.line];
8
+ if (targetLine === undefined) {
9
+ return actions;
10
+ }
11
+ for (const diagnostic of diagnostics) {
12
+ if (diagnostic.range.start.line !== range.start.line) {
13
+ continue;
14
+ }
15
+ if (diagnostic.code === "CRYPTO-001") {
16
+ actions.push({
17
+ title: "Replace with secure SHA-256",
18
+ kind: "quickfix",
19
+ diagnostics: [diagnostic],
20
+ isPreferred: true,
21
+ edit: {
22
+ changes: {
23
+ [uri]: [
24
+ {
25
+ range: diagnostic.range,
26
+ newText: "sha256",
27
+ },
28
+ ],
29
+ },
30
+ },
31
+ });
32
+ actions.push({
33
+ title: "Replace with high-security SHA-512",
34
+ kind: "quickfix",
35
+ diagnostics: [diagnostic],
36
+ edit: {
37
+ changes: {
38
+ [uri]: [
39
+ {
40
+ range: diagnostic.range,
41
+ newText: "sha512",
42
+ },
43
+ ],
44
+ },
45
+ },
46
+ });
47
+ }
48
+ if (diagnostic.code === "CRYPTO-002") {
49
+ actions.push({
50
+ title: "Upgrade to authenticated AES-256-GCM",
51
+ kind: "quickfix",
52
+ diagnostics: [diagnostic],
53
+ isPreferred: true,
54
+ edit: {
55
+ changes: {
56
+ [uri]: [
57
+ {
58
+ range: diagnostic.range,
59
+ newText: "aes-256-gcm",
60
+ },
61
+ ],
62
+ },
63
+ },
64
+ });
65
+ actions.push({
66
+ title: "Upgrade to ChaCha20-Poly1305 (zero-latency AEAD)",
67
+ kind: "quickfix",
68
+ diagnostics: [diagnostic],
69
+ edit: {
70
+ changes: {
71
+ [uri]: [
72
+ {
73
+ range: diagnostic.range,
74
+ newText: "chacha20-poly1305",
75
+ },
76
+ ],
77
+ },
78
+ },
79
+ });
80
+ }
81
+ if (diagnostic.code === "CRYPTO-003") {
82
+ actions.push({
83
+ title: "Upgrade key length to 3072 bits (CNSA compliant)",
84
+ kind: "quickfix",
85
+ diagnostics: [diagnostic],
86
+ isPreferred: true,
87
+ edit: {
88
+ changes: {
89
+ [uri]: [
90
+ {
91
+ range: diagnostic.range,
92
+ newText: "modulusLength: 3072",
93
+ },
94
+ ],
95
+ },
96
+ },
97
+ });
98
+ }
99
+ if (diagnostic.code === "CRYPTO-004") {
100
+ actions.push({
101
+ title: "Migrate to Post-Quantum ML-KEM-768 (NIST FIPS 203)",
102
+ kind: "quickfix",
103
+ diagnostics: [diagnostic],
104
+ isPreferred: true,
105
+ edit: {
106
+ changes: {
107
+ [uri]: [
108
+ {
109
+ range: diagnostic.range,
110
+ newText: "ml-kem-768",
111
+ },
112
+ ],
113
+ },
114
+ },
115
+ });
116
+ actions.push({
117
+ title: "Migrate to Post-Quantum ML-DSA-65 (NIST FIPS 204)",
118
+ kind: "quickfix",
119
+ diagnostics: [diagnostic],
120
+ edit: {
121
+ changes: {
122
+ [uri]: [
123
+ {
124
+ range: diagnostic.range,
125
+ newText: "ml-dsa-65",
126
+ },
127
+ ],
128
+ },
129
+ },
130
+ });
131
+ }
132
+ }
133
+ return actions;
134
+ }
135
+ //# sourceMappingURL=code-action.js.map
@@ -0,0 +1,3 @@
1
+ import { CompletionItem } from "./types";
2
+ export declare function getCompletions(): CompletionItem[];
3
+ //# sourceMappingURL=completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2FzC,wBAAgB,cAAc,IAAI,cAAc,EAAE,CAEjD"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCompletions = getCompletions;
4
+ const COMPLETION_ITEMS = [
5
+ {
6
+ label: "ML-KEM-512",
7
+ kind: 12,
8
+ detail: "NIST FIPS 203 Category 1 Key Encapsulation",
9
+ documentation: "Post-quantum lattice KEM for 128-bit quantum security.",
10
+ insertText: "ml-kem-512",
11
+ },
12
+ {
13
+ label: "ML-KEM-768",
14
+ kind: 12,
15
+ detail: "NIST FIPS 203 Category 3 Key Encapsulation (Recommended)",
16
+ documentation: "Standard post-quantum lattice KEM for general security.",
17
+ insertText: "ml-kem-768",
18
+ },
19
+ {
20
+ label: "ML-KEM-1024",
21
+ kind: 12,
22
+ detail: "NIST FIPS 203 Category 5 Key Encapsulation (CNSA 2.0)",
23
+ documentation: "High-security post-quantum lattice KEM.",
24
+ insertText: "ml-kem-1024",
25
+ },
26
+ {
27
+ label: "ML-DSA-44",
28
+ kind: 12,
29
+ detail: "NIST FIPS 204 Category 2 Digital Signature",
30
+ documentation: "Lattice-based deterministic digital signature.",
31
+ insertText: "ml-dsa-44",
32
+ },
33
+ {
34
+ label: "ML-DSA-65",
35
+ kind: 12,
36
+ detail: "NIST FIPS 204 Category 3 Digital Signature (Recommended)",
37
+ documentation: "Standard lattice-based digital signature.",
38
+ insertText: "ml-dsa-65",
39
+ },
40
+ {
41
+ label: "ML-DSA-87",
42
+ kind: 12,
43
+ detail: "NIST FIPS 204 Category 5 Digital Signature (CNSA 2.0)",
44
+ documentation: "High-security lattice-based digital signature.",
45
+ insertText: "ml-dsa-87",
46
+ },
47
+ {
48
+ label: "aes-256-gcm",
49
+ kind: 12,
50
+ detail: "NIST SP 800-38D AEAD",
51
+ documentation: "256-bit AES in Galois/Counter Mode with 128-bit authentication tag.",
52
+ insertText: "aes-256-gcm",
53
+ },
54
+ {
55
+ label: "chacha20-poly1305",
56
+ kind: 12,
57
+ detail: "RFC 8439 AEAD",
58
+ documentation: "High-performance authenticated cipher immune to cache-timing attacks.",
59
+ insertText: "chacha20-poly1305",
60
+ },
61
+ {
62
+ label: "sha256",
63
+ kind: 12,
64
+ detail: "NIST FIPS 180-4 Secure Hash",
65
+ documentation: "256-bit cryptographic hash function.",
66
+ insertText: "sha256",
67
+ },
68
+ {
69
+ label: "sha384",
70
+ kind: 12,
71
+ detail: "NIST FIPS 180-4 Secure Hash (CNSA 2.0)",
72
+ documentation: "384-bit cryptographic hash function.",
73
+ insertText: "sha384",
74
+ },
75
+ {
76
+ label: "sha512",
77
+ kind: 12,
78
+ detail: "NIST FIPS 180-4 Secure Hash",
79
+ documentation: "512-bit cryptographic hash function.",
80
+ insertText: "sha512",
81
+ },
82
+ ];
83
+ function getCompletions() {
84
+ return COMPLETION_ITEMS;
85
+ }
86
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1,3 @@
1
+ import { Diagnostic } from "./types";
2
+ export declare function analyzeDocument(_uri: string, text: string): Diagnostic[];
3
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAS,MAAM,SAAS,CAAC;AAM5C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CA0GxE"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeDocument = analyzeDocument;
4
+ const rules_1 = require("./rules");
5
+ function analyzeDocument(_uri, text) {
6
+ const diagnostics = [];
7
+ const lines = text.split(/\r?\n/);
8
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
9
+ const line = lines[lineIndex];
10
+ const brokenHashRegex = /["'](md5|sha1|sha-1|md4|ripemd160)["']/gi;
11
+ let match;
12
+ while ((match = brokenHashRegex.exec(line)) !== null) {
13
+ const startChar = match.index + 1;
14
+ const endChar = startChar + match[1].length;
15
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-001"];
16
+ diagnostics.push({
17
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
18
+ severity: rule.severity,
19
+ code: rule.id,
20
+ source: "crypto-lsp",
21
+ message: `${rule.description} ${rule.recommendation}`,
22
+ });
23
+ }
24
+ const insecureCipherRegex = /["'](aes-(?:128|192|256)-ecb|des|3des|des-ede3|rc4|blowfish)["']/gi;
25
+ while ((match = insecureCipherRegex.exec(line)) !== null) {
26
+ const startChar = match.index + 1;
27
+ const endChar = startChar + match[1].length;
28
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-002"];
29
+ diagnostics.push({
30
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
31
+ severity: rule.severity,
32
+ code: rule.id,
33
+ source: "crypto-lsp",
34
+ message: `${rule.description} ${rule.recommendation}`,
35
+ });
36
+ }
37
+ const weakRsaRegex = /(?:modulusLength|bits)\s*[:=]\s*(512|1024)\b/gi;
38
+ while ((match = weakRsaRegex.exec(line)) !== null) {
39
+ const startChar = match.index;
40
+ const endChar = match.index + match[0].length;
41
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-003"];
42
+ diagnostics.push({
43
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
44
+ severity: rule.severity,
45
+ code: rule.id,
46
+ source: "crypto-lsp",
47
+ message: `${rule.description} (${match[1]} bits detected). ${rule.recommendation}`,
48
+ });
49
+ }
50
+ const classicalPqRegex = /(?:algorithm\s*[:=]\s*|generateKeyPair(?:Sync)?\s*\(\s*)["'](rsa|ec|ecdsa|ecdh|ed25519)["']/gi;
51
+ while ((match = classicalPqRegex.exec(line)) !== null) {
52
+ const alg = match[1];
53
+ const startChar = line.indexOf(alg, match.index);
54
+ const endChar = startChar + alg.length;
55
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-004"];
56
+ diagnostics.push({
57
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
58
+ severity: rule.severity,
59
+ code: rule.id,
60
+ source: "crypto-lsp",
61
+ message: `${rule.description} (${alg.toUpperCase()} detected). ${rule.recommendation}`,
62
+ });
63
+ }
64
+ const hardcodedKeyRegex = /(?:secret_key|private_key|apiKey|cryptoKey)\s*[:=]\s*["']([0-9a-fA-F]{32,})["']/gi;
65
+ while ((match = hardcodedKeyRegex.exec(line)) !== null) {
66
+ const startChar = line.indexOf(match[1], match.index);
67
+ const endChar = startChar + match[1].length;
68
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-005"];
69
+ diagnostics.push({
70
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
71
+ severity: rule.severity,
72
+ code: rule.id,
73
+ source: "crypto-lsp",
74
+ message: `${rule.description} ${rule.recommendation}`,
75
+ });
76
+ }
77
+ if (line.includes("-----BEGIN") &&
78
+ !line.match(/-----BEGIN [A-Z0-9 ]+-----/)) {
79
+ const startChar = line.indexOf("-----BEGIN");
80
+ const endChar = line.length;
81
+ const rule = rules_1.CRYPTO_RULES["CRYPTO-006"];
82
+ diagnostics.push({
83
+ range: createRange(lineIndex, startChar, lineIndex, endChar),
84
+ severity: rule.severity,
85
+ code: rule.id,
86
+ source: "crypto-lsp",
87
+ message: `${rule.description} ${rule.recommendation}`,
88
+ });
89
+ }
90
+ }
91
+ return diagnostics;
92
+ }
93
+ function createRange(startLine, startChar, endLine, endChar) {
94
+ return {
95
+ start: { line: startLine, character: startChar },
96
+ end: { line: endLine, character: endChar },
97
+ };
98
+ }
99
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1,3 @@
1
+ import { Hover, Position } from "./types";
2
+ export declare function getHover(text: string, position: Position): Hover | null;
3
+ //# sourceMappingURL=hover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../src/hover.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAmG1C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAsCvE"}
package/dist/hover.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getHover = getHover;
4
+ const KNOWLEDGE_BASE = {
5
+ "ml-kem": {
6
+ title: "ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism)",
7
+ category: "Post-Quantum Key Exchange",
8
+ securityLevel: "NIST Security Categories 1, 3, 5 (ML-KEM-512, 768, 1024)",
9
+ quantumSafe: true,
10
+ standard: "NIST FIPS 203 (Final August 2024)",
11
+ description: "Primary post-quantum key encapsulation mechanism standardized by NIST to replace classical Diffie-Hellman and RSA key transport against quantum decryption.",
12
+ },
13
+ "ml-dsa": {
14
+ title: "ML-DSA (Module-Lattice-Based Digital Signature Algorithm)",
15
+ category: "Post-Quantum Digital Signature",
16
+ securityLevel: "NIST Security Categories 2, 3, 5 (ML-DSA-44, 65, 87)",
17
+ quantumSafe: true,
18
+ standard: "NIST FIPS 204 (Final August 2024)",
19
+ description: "Primary post-quantum digital signature algorithm standardized by NIST based on the CRYSTALS-Dilithium lattice problem.",
20
+ },
21
+ "slh-dsa": {
22
+ title: "SLH-DSA (Stateless Hash-Based Digital Signature Algorithm)",
23
+ category: "Post-Quantum Digital Signature",
24
+ securityLevel: "NIST Security Categories 1, 3, 5 (SPHINCS+)",
25
+ quantumSafe: true,
26
+ standard: "NIST FIPS 205 (Final August 2024)",
27
+ description: "Stateless hash-based digital signature serving as a conservative mathematical fallback independent of structured lattice hardness assumptions.",
28
+ },
29
+ "aes-256-gcm": {
30
+ title: "AES-256-GCM (Galois/Counter Mode)",
31
+ category: "Authenticated Symmetric Cipher (AEAD)",
32
+ securityLevel: "256-bit key (128-bit quantum security via Grover's algorithm)",
33
+ quantumSafe: true,
34
+ standard: "NIST SP 800-38D / FIPS 197",
35
+ description: "Industry-standard authenticated encryption providing high-throughput confidentiality and data integrity with hardware acceleration.",
36
+ },
37
+ "chacha20-poly1305": {
38
+ title: "ChaCha20-Poly1305",
39
+ category: "Authenticated Symmetric Cipher (AEAD)",
40
+ securityLevel: "256-bit key",
41
+ quantumSafe: true,
42
+ standard: "RFC 8439 / IETF",
43
+ description: "High-speed stream cipher with Poly1305 authenticator, immune to cache-timing side-channel attacks on architectures without AES-NI instructions.",
44
+ },
45
+ ed25519: {
46
+ title: "Ed25519 (Edwards-curve Digital Signature Algorithm)",
47
+ category: "Classical Elliptic Curve Signature",
48
+ securityLevel: "128-bit classical security margin",
49
+ quantumSafe: false,
50
+ standard: "RFC 8032 / FIPS 186-5",
51
+ description: "Fast, deterministic signature scheme over Curve25519. Vulnerable to Shor's algorithm on a Cryptanalytically Relevant Quantum Computer (CRQC).",
52
+ },
53
+ rsa: {
54
+ title: "RSA (Rivest-Shamir-Adleman)",
55
+ category: "Classical Public-Key Cryptosystem",
56
+ securityLevel: "2048-bit: ~112-bit security | 3072-bit: ~128-bit security",
57
+ quantumSafe: false,
58
+ standard: "PKCS #1 / RFC 8017 / NIST SP 800-56B",
59
+ description: "Classical integer factorization-based cryptosystem. Fully vulnerable to polynomial-time recovery via Shor's algorithm on a CRQC.",
60
+ },
61
+ md5: {
62
+ title: "MD5 (Message Digest Algorithm 5)",
63
+ category: "Cryptographic Hash Function (DEPRECATED)",
64
+ securityLevel: "0-bit collision resistance (Cryptographically Broken)",
65
+ quantumSafe: false,
66
+ standard: "DEPRECATED (RFC 6151 / NIST SP 800-131A)",
67
+ description: "Severely vulnerable to practical collision attacks. Must never be used for security-sensitive operations or signatures.",
68
+ },
69
+ "sha-1": {
70
+ title: "SHA-1 (Secure Hash Algorithm 1)",
71
+ category: "Cryptographic Hash Function (DEPRECATED)",
72
+ securityLevel: "< 60-bit collision resistance (Demonstrated Collisions)",
73
+ quantumSafe: false,
74
+ standard: "DEPRECATED (NIST SP 800-131A / SHAttered)",
75
+ description: "Practical collisions generated since 2017. Disallowed for digital signatures and certificates across all modern compliance regimes.",
76
+ },
77
+ };
78
+ function getHover(text, position) {
79
+ const lines = text.split(/\r?\n/);
80
+ if (position.line < 0 || position.line >= lines.length) {
81
+ return null;
82
+ }
83
+ const line = lines[position.line];
84
+ const char = position.character;
85
+ for (const [key, doc] of Object.entries(KNOWLEDGE_BASE)) {
86
+ const regex = new RegExp(`\\b${key.replace(/-/g, "[ -]?")}\\b`, "gi");
87
+ let match;
88
+ while ((match = regex.exec(line)) !== null) {
89
+ const start = match.index;
90
+ const end = start + match[0].length;
91
+ if (char >= start && char <= end) {
92
+ const md = [
93
+ `### ${doc.title}`,
94
+ `**Category:** ${doc.category}`,
95
+ `**Security:** ${doc.securityLevel}`,
96
+ `**Quantum Resistant:** ${doc.quantumSafe ? "✅ Yes" : "❌ No (Vulnerable to Shor's Algorithm)"}`,
97
+ `**Standard:** ${doc.standard}`,
98
+ "",
99
+ doc.description,
100
+ ].join("\n\n");
101
+ return {
102
+ contents: { kind: "markdown", value: md },
103
+ range: {
104
+ start: { line: position.line, character: start },
105
+ end: { line: position.line, character: end },
106
+ },
107
+ };
108
+ }
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ //# sourceMappingURL=hover.js.map
@@ -0,0 +1,9 @@
1
+ export * from "./types";
2
+ export * from "./rules";
3
+ export * from "./diagnostics";
4
+ export * from "./hover";
5
+ export * from "./code-action";
6
+ export * from "./completion";
7
+ export * from "./server";
8
+ export * from "./cli";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./rules"), exports);
19
+ __exportStar(require("./diagnostics"), exports);
20
+ __exportStar(require("./hover"), exports);
21
+ __exportStar(require("./code-action"), exports);
22
+ __exportStar(require("./completion"), exports);
23
+ __exportStar(require("./server"), exports);
24
+ __exportStar(require("./cli"), exports);
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ import { DiagnosticSeverity } from "./types";
2
+ export interface CryptoRule {
3
+ id: string;
4
+ name: string;
5
+ severity: DiagnosticSeverity;
6
+ description: string;
7
+ recommendation: string;
8
+ }
9
+ export declare const CRYPTO_RULES: Record<string, CryptoRule>;
10
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAqDnD,CAAC"}
package/dist/rules.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CRYPTO_RULES = void 0;
4
+ const types_1 = require("./types");
5
+ exports.CRYPTO_RULES = {
6
+ "CRYPTO-001": {
7
+ id: "CRYPTO-001",
8
+ name: "Broken Hash Function",
9
+ severity: types_1.DiagnosticSeverity.Error,
10
+ description: "Use of broken cryptographic hash function (MD5, SHA-1, MD4, RIPEMD160) vulnerable to collision attacks.",
11
+ recommendation: "Migrate to SHA-256, SHA-384, SHA-512, or SHA3-256.",
12
+ },
13
+ "CRYPTO-002": {
14
+ id: "CRYPTO-002",
15
+ name: "Insecure Symmetric Cipher or Mode",
16
+ severity: types_1.DiagnosticSeverity.Error,
17
+ description: "Use of deprecated cipher (DES, 3DES, RC4) or ECB mode which leaks plaintext patterns.",
18
+ recommendation: "Migrate to AES-256-GCM or ChaCha20-Poly1305 with unique 96-bit nonce.",
19
+ },
20
+ "CRYPTO-003": {
21
+ id: "CRYPTO-003",
22
+ name: "Inadequate Key Size",
23
+ severity: types_1.DiagnosticSeverity.Error,
24
+ description: "RSA key length below 2048 bits provides insufficient security margin.",
25
+ recommendation: "Use RSA with >= 2048 bits (3072+ recommended) or migrate to Ed25519 / ML-DSA.",
26
+ },
27
+ "CRYPTO-004": {
28
+ id: "CRYPTO-004",
29
+ name: "Quantum Vulnerable Public-Key Cryptography",
30
+ severity: types_1.DiagnosticSeverity.Warning,
31
+ description: "Classical public key algorithm is vulnerable to Shor's algorithm on a Cryptanalytically Relevant Quantum Computer (CRQC).",
32
+ recommendation: "Transition to NIST FIPS 203 (ML-KEM) for KEM and FIPS 204 (ML-DSA) for digital signatures.",
33
+ },
34
+ "CRYPTO-005": {
35
+ id: "CRYPTO-005",
36
+ name: "Hardcoded Secret Material",
37
+ severity: types_1.DiagnosticSeverity.Error,
38
+ description: "Hardcoded secret or private cryptographic key detected in source code.",
39
+ recommendation: "Store keys in environment variables, hardware security modules (HSM), or KMS.",
40
+ },
41
+ "CRYPTO-006": {
42
+ id: "CRYPTO-006",
43
+ name: "Malformed PEM Block",
44
+ severity: types_1.DiagnosticSeverity.Warning,
45
+ description: "Malformed or unterminated PEM header structure.",
46
+ recommendation: "Ensure valid RFC 7468 PEM encapsulation with matching BEGIN and END boundaries.",
47
+ },
48
+ };
49
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1,10 @@
1
+ import { JSONRPCRequest, JSONRPCResponse } from "./types";
2
+ export declare class CryptoLspServer {
3
+ private documents;
4
+ private initialized;
5
+ isInitialized(): boolean;
6
+ getDocument(uri: string): string | undefined;
7
+ handleRequest(request: JSONRPCRequest): Promise<JSONRPCResponse | null>;
8
+ listenStdio(input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream): void;
9
+ }
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,cAAc,EACd,eAAe,EAIhB,MAAM,SAAS,CAAC;AAUjB,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,WAAW,CAAS;IAErB,aAAa,IAAI,OAAO;IAIxB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAItC,aAAa,CACxB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAkJ3B,WAAW,CAChB,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,IAAI;CA4BR"}
package/dist/server.js ADDED
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CryptoLspServer = void 0;
7
+ const node_readline_1 = __importDefault(require("node:readline"));
8
+ const node_process_1 = __importDefault(require("node:process"));
9
+ const diagnostics_1 = require("./diagnostics");
10
+ const hover_1 = require("./hover");
11
+ const code_action_1 = require("./code-action");
12
+ const completion_1 = require("./completion");
13
+ const version_1 = require("./version");
14
+ class CryptoLspServer {
15
+ documents = new Map();
16
+ initialized = false;
17
+ isInitialized() {
18
+ return this.initialized;
19
+ }
20
+ getDocument(uri) {
21
+ return this.documents.get(uri);
22
+ }
23
+ async handleRequest(request) {
24
+ if (request.jsonrpc !== "2.0") {
25
+ return {
26
+ jsonrpc: "2.0",
27
+ id: request.id ?? null,
28
+ error: {
29
+ code: -32600,
30
+ message: "Invalid Request: jsonrpc must be '2.0'",
31
+ },
32
+ };
33
+ }
34
+ const id = request.id ?? null;
35
+ const params = request.params;
36
+ switch (request.method) {
37
+ case "initialize": {
38
+ this.initialized = true;
39
+ const result = {
40
+ capabilities: {
41
+ textDocumentSync: 1,
42
+ hoverProvider: true,
43
+ codeActionProvider: true,
44
+ completionProvider: {
45
+ resolveProvider: false,
46
+ triggerCharacters: ['"', "'", "-"],
47
+ },
48
+ },
49
+ serverInfo: {
50
+ name: "crypto-lsp",
51
+ version: version_1.VERSION,
52
+ },
53
+ };
54
+ return { jsonrpc: "2.0", id, result };
55
+ }
56
+ case "initialized": {
57
+ return null;
58
+ }
59
+ case "textDocument/didOpen": {
60
+ const td = params
61
+ ? params.textDocument
62
+ : null;
63
+ if (td) {
64
+ this.documents.set(td.uri, td.text);
65
+ const diagnostics = (0, diagnostics_1.analyzeDocument)(td.uri, td.text);
66
+ const publishParams = {
67
+ uri: td.uri,
68
+ diagnostics,
69
+ };
70
+ return {
71
+ jsonrpc: "2.0",
72
+ id: null,
73
+ result: publishParams,
74
+ };
75
+ }
76
+ return null;
77
+ }
78
+ case "textDocument/didChange": {
79
+ const td = params ? params.textDocument : null;
80
+ const changes = params
81
+ ? params.contentChanges
82
+ : null;
83
+ if (td && changes && changes.length > 0) {
84
+ const newText = changes[0].text;
85
+ this.documents.set(td.uri, newText);
86
+ const diagnostics = (0, diagnostics_1.analyzeDocument)(td.uri, newText);
87
+ const publishParams = {
88
+ uri: td.uri,
89
+ diagnostics,
90
+ };
91
+ return {
92
+ jsonrpc: "2.0",
93
+ id: null,
94
+ result: publishParams,
95
+ };
96
+ }
97
+ return null;
98
+ }
99
+ case "textDocument/didClose": {
100
+ const td = params ? params.textDocument : null;
101
+ if (td) {
102
+ this.documents.delete(td.uri);
103
+ }
104
+ return null;
105
+ }
106
+ case "textDocument/hover": {
107
+ const td = params ? params.textDocument : null;
108
+ const pos = params ? params.position : null;
109
+ if (td && pos) {
110
+ const text = this.documents.get(td.uri) || "";
111
+ const hover = (0, hover_1.getHover)(text, pos);
112
+ return { jsonrpc: "2.0", id, result: hover };
113
+ }
114
+ return { jsonrpc: "2.0", id, result: null };
115
+ }
116
+ case "textDocument/codeAction": {
117
+ const td = params ? params.textDocument : null;
118
+ const range = params ? params.range : null;
119
+ const context = params
120
+ ? params.context
121
+ : null;
122
+ if (td && range) {
123
+ const text = this.documents.get(td.uri) || "";
124
+ const diags = context
125
+ ? context.diagnostics
126
+ : (0, diagnostics_1.analyzeDocument)(td.uri, text);
127
+ const actions = (0, code_action_1.getCodeActions)(td.uri, text, range, diags);
128
+ return { jsonrpc: "2.0", id, result: actions };
129
+ }
130
+ return { jsonrpc: "2.0", id, result: [] };
131
+ }
132
+ case "textDocument/completion": {
133
+ const items = (0, completion_1.getCompletions)();
134
+ return { jsonrpc: "2.0", id, result: items };
135
+ }
136
+ case "shutdown": {
137
+ return { jsonrpc: "2.0", id, result: null };
138
+ }
139
+ case "exit": {
140
+ return null;
141
+ }
142
+ default:
143
+ return {
144
+ jsonrpc: "2.0",
145
+ id,
146
+ error: {
147
+ code: -32601,
148
+ message: `Method not found: ${request.method}`,
149
+ },
150
+ };
151
+ }
152
+ }
153
+ listenStdio(input = node_process_1.default.stdin, output = node_process_1.default.stdout) {
154
+ const rl = node_readline_1.default.createInterface({
155
+ input,
156
+ output: undefined,
157
+ terminal: false,
158
+ });
159
+ rl.on("line", async (line) => {
160
+ const trimmed = line.trim();
161
+ if (!trimmed)
162
+ return;
163
+ if (trimmed.startsWith("Content-Length:"))
164
+ return;
165
+ try {
166
+ const req = JSON.parse(trimmed);
167
+ const res = await this.handleRequest(req);
168
+ if (res !== null) {
169
+ output.write(JSON.stringify(res) + "\n");
170
+ }
171
+ }
172
+ catch {
173
+ const parseError = {
174
+ jsonrpc: "2.0",
175
+ id: null,
176
+ error: { code: -32700, message: "Parse error: invalid JSON" },
177
+ };
178
+ output.write(JSON.stringify(parseError) + "\n");
179
+ }
180
+ });
181
+ }
182
+ }
183
+ exports.CryptoLspServer = CryptoLspServer;
184
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,111 @@
1
+ export interface Position {
2
+ line: number;
3
+ character: number;
4
+ }
5
+ export interface Range {
6
+ start: Position;
7
+ end: Position;
8
+ }
9
+ export declare enum DiagnosticSeverity {
10
+ Error = 1,
11
+ Warning = 2,
12
+ Information = 3,
13
+ Hint = 4
14
+ }
15
+ export interface Diagnostic {
16
+ range: Range;
17
+ severity: DiagnosticSeverity;
18
+ code: string;
19
+ source: string;
20
+ message: string;
21
+ }
22
+ export interface TextDocumentItem {
23
+ uri: string;
24
+ languageId: string;
25
+ version: number;
26
+ text: string;
27
+ }
28
+ export interface TextDocumentContentChangeEvent {
29
+ text: string;
30
+ }
31
+ export interface DidOpenTextDocumentParams {
32
+ textDocument: TextDocumentItem;
33
+ }
34
+ export interface DidChangeTextDocumentParams {
35
+ textDocument: {
36
+ uri: string;
37
+ version: number;
38
+ };
39
+ contentChanges: TextDocumentContentChangeEvent[];
40
+ }
41
+ export interface DidCloseTextDocumentParams {
42
+ textDocument: {
43
+ uri: string;
44
+ };
45
+ }
46
+ export interface PublishDiagnosticsParams {
47
+ uri: string;
48
+ diagnostics: Diagnostic[];
49
+ }
50
+ export interface MarkupContent {
51
+ kind: "markdown" | "plaintext";
52
+ value: string;
53
+ }
54
+ export interface Hover {
55
+ contents: MarkupContent;
56
+ range?: Range;
57
+ }
58
+ export interface TextEdit {
59
+ range: Range;
60
+ newText: string;
61
+ }
62
+ export interface WorkspaceEdit {
63
+ changes?: Record<string, TextEdit[]>;
64
+ }
65
+ export interface CodeAction {
66
+ title: string;
67
+ kind?: string;
68
+ diagnostics?: Diagnostic[];
69
+ isPreferred?: boolean;
70
+ edit?: WorkspaceEdit;
71
+ }
72
+ export interface CompletionItem {
73
+ label: string;
74
+ kind: number;
75
+ detail?: string;
76
+ documentation?: string;
77
+ insertText?: string;
78
+ }
79
+ export interface ServerCapabilities {
80
+ textDocumentSync: number;
81
+ hoverProvider: boolean;
82
+ codeActionProvider: boolean;
83
+ completionProvider: {
84
+ resolveProvider: boolean;
85
+ triggerCharacters: string[];
86
+ };
87
+ }
88
+ export interface InitializeResult {
89
+ capabilities: ServerCapabilities;
90
+ serverInfo: {
91
+ name: string;
92
+ version: string;
93
+ };
94
+ }
95
+ export interface JSONRPCRequest {
96
+ jsonrpc: "2.0";
97
+ id?: number | string | null;
98
+ method: string;
99
+ params?: Record<string, unknown>;
100
+ }
101
+ export interface JSONRPCResponse {
102
+ jsonrpc: "2.0";
103
+ id: number | string | null;
104
+ result?: unknown;
105
+ error?: {
106
+ code: number;
107
+ message: string;
108
+ data?: unknown;
109
+ };
110
+ }
111
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiagnosticSeverity = void 0;
4
+ var DiagnosticSeverity;
5
+ (function (DiagnosticSeverity) {
6
+ DiagnosticSeverity[DiagnosticSeverity["Error"] = 1] = "Error";
7
+ DiagnosticSeverity[DiagnosticSeverity["Warning"] = 2] = "Warning";
8
+ DiagnosticSeverity[DiagnosticSeverity["Information"] = 3] = "Information";
9
+ DiagnosticSeverity[DiagnosticSeverity["Hint"] = 4] = "Hint";
10
+ })(DiagnosticSeverity || (exports.DiagnosticSeverity = DiagnosticSeverity = {}));
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,OAAO,EAAE,MAIb,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ exports.VERSION = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "..", "package.json"), "utf8")).version;
7
+ //# sourceMappingURL=version.js.map
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@sebastienrousseau/crypto-lsp",
3
+ "version": "0.0.7",
4
+ "description": "Language Server Protocol (LSP) providing real-time cryptographic static analysis, quantum-vulnerability flagging, PEM/OpenPGP validation, and automated quick fixes for IDEs.",
5
+ "author": "Sebastien Rousseau <sebastienrousseau@users.noreply.github.com>",
6
+ "license": "MIT OR Apache-2.0",
7
+ "homepage": "https://crypto-service.co",
8
+ "repository": {
9
+ "directory": "packages/crypto-lsp",
10
+ "type": "git",
11
+ "url": "git@github.com:sebastienrousseau/crypto-service.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/sebastienrousseau/crypto-service/issues"
15
+ },
16
+ "engines": {
17
+ "node": ">=22.0.0"
18
+ },
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "sideEffects": false,
22
+ "bin": {
23
+ "crypto-lsp": "./dist/cli.js"
24
+ },
25
+ "files": [
26
+ "dist/**/*.js",
27
+ "dist/**/*.d.ts",
28
+ "dist/**/*.d.ts.map"
29
+ ],
30
+ "dependencies": {
31
+ "@sebastienrousseau/crypto-lib": "0.0.7"
32
+ },
33
+ "devDependencies": {
34
+ "@types/chai": "^4.3.7",
35
+ "@types/chai-as-promised": "^8.0.2",
36
+ "@types/mocha": "^10.0.2",
37
+ "@types/node": "^26.4.1",
38
+ "c8": "^12.0.0",
39
+ "chai": "^4.5.0",
40
+ "chai-as-promised": "^7.1.2",
41
+ "mocha": "^10.8.2",
42
+ "rimraf": "^6.1.3",
43
+ "ts-node": "^10.9.2",
44
+ "typedoc": "^0.28.20",
45
+ "typescript": "~5.9.3"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc --build tsconfig.json",
52
+ "clean": "rimraf ./coverage ./dist ./docs",
53
+ "lint": "eslint --ext .ts src __tests__",
54
+ "lint:fix": "eslint --cache --fix --ext .ts src __tests__",
55
+ "format": "prettier --write src/**/*.ts",
56
+ "format:check": "prettier --check \"src/**/*.ts\"",
57
+ "test": "c8 --check-coverage --lines 100 --branches 100 --functions 100 --reporter=lcov --reporter=text mocha --config=.mocharc.cjs",
58
+ "docs": "typedoc"
59
+ }
60
+ }