@pcircle/footprint 1.1.1 → 1.2.1

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.
Files changed (207) hide show
  1. package/README.md +165 -12
  2. package/SKILL.md +72 -15
  3. package/dist/src/analyzers/content-analyzer.d.ts +20 -0
  4. package/dist/src/analyzers/content-analyzer.d.ts.map +1 -0
  5. package/dist/src/analyzers/content-analyzer.js +169 -0
  6. package/dist/src/analyzers/content-analyzer.js.map +1 -0
  7. package/dist/src/index.d.ts +38 -0
  8. package/dist/src/index.d.ts.map +1 -0
  9. package/dist/src/index.js +243 -0
  10. package/dist/src/index.js.map +1 -0
  11. package/dist/src/lib/crypto/decrypt.d.ts.map +1 -0
  12. package/dist/{lib → src/lib}/crypto/decrypt.js +4 -0
  13. package/dist/src/lib/crypto/decrypt.js.map +1 -0
  14. package/dist/src/lib/crypto/encrypt.d.ts.map +1 -0
  15. package/dist/src/lib/crypto/encrypt.js.map +1 -0
  16. package/dist/{lib → src/lib}/crypto/index.d.ts +1 -1
  17. package/dist/src/lib/crypto/index.d.ts.map +1 -0
  18. package/dist/{lib → src/lib}/crypto/index.js +1 -1
  19. package/dist/src/lib/crypto/index.js.map +1 -0
  20. package/dist/{lib → src/lib}/crypto/key-derivation.d.ts +17 -3
  21. package/dist/src/lib/crypto/key-derivation.d.ts.map +1 -0
  22. package/dist/{lib → src/lib}/crypto/key-derivation.js +44 -3
  23. package/dist/src/lib/crypto/key-derivation.js.map +1 -0
  24. package/dist/src/lib/crypto/types.d.ts.map +1 -0
  25. package/dist/src/lib/crypto/types.js.map +1 -0
  26. package/dist/src/lib/errors/base-error.d.ts +15 -0
  27. package/dist/src/lib/errors/base-error.d.ts.map +1 -0
  28. package/dist/src/lib/errors/base-error.js +34 -0
  29. package/dist/src/lib/errors/base-error.js.map +1 -0
  30. package/dist/src/lib/errors/crypto-error.d.ts +29 -0
  31. package/dist/src/lib/errors/crypto-error.d.ts.map +1 -0
  32. package/dist/src/lib/errors/crypto-error.js +43 -0
  33. package/dist/src/lib/errors/crypto-error.js.map +1 -0
  34. package/dist/src/lib/errors/index.d.ts +26 -0
  35. package/dist/src/lib/errors/index.d.ts.map +1 -0
  36. package/dist/src/lib/errors/index.js +26 -0
  37. package/dist/src/lib/errors/index.js.map +1 -0
  38. package/dist/src/lib/errors/storage-error.d.ts +25 -0
  39. package/dist/src/lib/errors/storage-error.d.ts.map +1 -0
  40. package/dist/src/lib/errors/storage-error.js +38 -0
  41. package/dist/src/lib/errors/storage-error.js.map +1 -0
  42. package/dist/src/lib/errors/validation-error.d.ts +21 -0
  43. package/dist/src/lib/errors/validation-error.d.ts.map +1 -0
  44. package/dist/src/lib/errors/validation-error.js +29 -0
  45. package/dist/src/lib/errors/validation-error.js.map +1 -0
  46. package/dist/{lib → src/lib}/storage/database.d.ts +14 -2
  47. package/dist/src/lib/storage/database.d.ts.map +1 -0
  48. package/dist/{lib → src/lib}/storage/database.js +65 -29
  49. package/dist/src/lib/storage/database.js.map +1 -0
  50. package/dist/src/lib/storage/export.d.ts.map +1 -0
  51. package/dist/{lib → src/lib}/storage/export.js +16 -1
  52. package/dist/src/lib/storage/export.js.map +1 -0
  53. package/dist/{lib → src/lib}/storage/git.d.ts +1 -1
  54. package/dist/src/lib/storage/git.d.ts.map +1 -0
  55. package/dist/{lib → src/lib}/storage/git.js +5 -2
  56. package/dist/src/lib/storage/git.js.map +1 -0
  57. package/dist/{lib → src/lib}/storage/index.d.ts +1 -0
  58. package/dist/src/lib/storage/index.d.ts.map +1 -0
  59. package/dist/{lib → src/lib}/storage/index.js +1 -0
  60. package/dist/src/lib/storage/index.js.map +1 -0
  61. package/dist/src/lib/storage/salt-storage.d.ts +25 -0
  62. package/dist/src/lib/storage/salt-storage.d.ts.map +1 -0
  63. package/dist/src/lib/storage/salt-storage.js +66 -0
  64. package/dist/src/lib/storage/salt-storage.js.map +1 -0
  65. package/dist/src/lib/storage/schema.d.ts.map +1 -0
  66. package/dist/{lib → src/lib}/storage/schema.js +22 -1
  67. package/dist/src/lib/storage/schema.js.map +1 -0
  68. package/dist/src/lib/storage/types.d.ts.map +1 -0
  69. package/dist/src/lib/storage/types.js.map +1 -0
  70. package/dist/src/lib/tool-response.d.ts +84 -0
  71. package/dist/src/lib/tool-response.d.ts.map +1 -0
  72. package/dist/src/lib/tool-response.js +91 -0
  73. package/dist/src/lib/tool-response.js.map +1 -0
  74. package/dist/src/lib/tool-wrapper.d.ts +45 -0
  75. package/dist/src/lib/tool-wrapper.d.ts.map +1 -0
  76. package/dist/src/lib/tool-wrapper.js +73 -0
  77. package/dist/src/lib/tool-wrapper.js.map +1 -0
  78. package/dist/{test-helpers.d.ts → src/test-helpers.d.ts} +4 -4
  79. package/dist/src/test-helpers.d.ts.map +1 -0
  80. package/dist/{test-helpers.js → src/test-helpers.js} +2 -2
  81. package/dist/src/test-helpers.js.map +1 -0
  82. package/dist/src/tools/capture-footprint.d.ts +29 -0
  83. package/dist/src/tools/capture-footprint.d.ts.map +1 -0
  84. package/dist/src/tools/capture-footprint.js +94 -0
  85. package/dist/src/tools/capture-footprint.js.map +1 -0
  86. package/dist/src/tools/delete-footprints.d.ts +22 -0
  87. package/dist/src/tools/delete-footprints.d.ts.map +1 -0
  88. package/dist/src/tools/delete-footprints.js +33 -0
  89. package/dist/src/tools/delete-footprints.js.map +1 -0
  90. package/dist/src/tools/export-footprints.d.ts +33 -0
  91. package/dist/src/tools/export-footprints.d.ts.map +1 -0
  92. package/dist/src/tools/export-footprints.js +50 -0
  93. package/dist/src/tools/export-footprints.js.map +1 -0
  94. package/dist/src/tools/get-footprint.d.ts +51 -0
  95. package/dist/src/tools/get-footprint.d.ts.map +1 -0
  96. package/dist/src/tools/get-footprint.js +66 -0
  97. package/dist/src/tools/get-footprint.js.map +1 -0
  98. package/dist/src/tools/get-tag-stats.d.ts +30 -0
  99. package/dist/src/tools/get-tag-stats.d.ts.map +1 -0
  100. package/dist/src/tools/get-tag-stats.js +33 -0
  101. package/dist/src/tools/get-tag-stats.js.map +1 -0
  102. package/dist/src/tools/index.d.ts +16 -0
  103. package/dist/src/tools/index.d.ts.map +1 -0
  104. package/dist/src/tools/index.js +16 -0
  105. package/dist/src/tools/index.js.map +1 -0
  106. package/dist/src/tools/list-footprints.d.ts +57 -0
  107. package/dist/src/tools/list-footprints.d.ts.map +1 -0
  108. package/dist/src/tools/list-footprints.js +57 -0
  109. package/dist/src/tools/list-footprints.js.map +1 -0
  110. package/dist/src/tools/remove-tag.d.ts +22 -0
  111. package/dist/src/tools/remove-tag.d.ts.map +1 -0
  112. package/dist/src/tools/remove-tag.js +30 -0
  113. package/dist/src/tools/remove-tag.js.map +1 -0
  114. package/dist/src/tools/rename-tag.d.ts +24 -0
  115. package/dist/src/tools/rename-tag.d.ts.map +1 -0
  116. package/dist/src/tools/rename-tag.js +34 -0
  117. package/dist/src/tools/rename-tag.js.map +1 -0
  118. package/dist/src/tools/search-footprints.d.ts +60 -0
  119. package/dist/src/tools/search-footprints.d.ts.map +1 -0
  120. package/dist/src/tools/search-footprints.js +78 -0
  121. package/dist/src/tools/search-footprints.js.map +1 -0
  122. package/dist/src/tools/suggest-capture.d.ts +21 -0
  123. package/dist/src/tools/suggest-capture.d.ts.map +1 -0
  124. package/dist/src/tools/suggest-capture.js +37 -0
  125. package/dist/src/tools/suggest-capture.js.map +1 -0
  126. package/dist/src/tools/verify-footprint.d.ts +104 -0
  127. package/dist/src/tools/verify-footprint.d.ts.map +1 -0
  128. package/dist/src/tools/verify-footprint.js +102 -0
  129. package/dist/src/tools/verify-footprint.js.map +1 -0
  130. package/dist/{types.d.ts → src/types.d.ts} +1 -1
  131. package/dist/src/types.d.ts.map +1 -0
  132. package/dist/{lib/storage → src}/types.js.map +1 -1
  133. package/dist/src/ui/register.d.ts.map +1 -0
  134. package/dist/src/ui/register.js +94 -0
  135. package/dist/src/ui/register.js.map +1 -0
  136. package/dist/tests/error-handling.test.d.ts +2 -0
  137. package/dist/tests/error-handling.test.d.ts.map +1 -0
  138. package/dist/tests/error-handling.test.js +114 -0
  139. package/dist/tests/error-handling.test.js.map +1 -0
  140. package/dist/tests/fixtures.d.ts +87 -0
  141. package/dist/tests/fixtures.d.ts.map +1 -0
  142. package/dist/tests/fixtures.js +130 -0
  143. package/dist/tests/fixtures.js.map +1 -0
  144. package/dist/tests/integration.test.d.ts +2 -0
  145. package/dist/tests/integration.test.d.ts.map +1 -0
  146. package/dist/tests/integration.test.js +115 -0
  147. package/dist/tests/integration.test.js.map +1 -0
  148. package/dist/tests/resources.test.d.ts +2 -0
  149. package/dist/tests/resources.test.d.ts.map +1 -0
  150. package/dist/tests/resources.test.js +73 -0
  151. package/dist/tests/resources.test.js.map +1 -0
  152. package/dist/tests/setup.d.ts +8 -0
  153. package/dist/tests/setup.d.ts.map +1 -0
  154. package/dist/tests/setup.js +8 -0
  155. package/dist/tests/setup.js.map +1 -0
  156. package/dist/tests/tools.test.d.ts +2 -0
  157. package/dist/tests/tools.test.d.ts.map +1 -0
  158. package/dist/tests/tools.test.js +224 -0
  159. package/dist/tests/tools.test.js.map +1 -0
  160. package/dist/ui/dashboard.html +1 -1
  161. package/dist/ui/detail.html +1 -1
  162. package/dist/ui/export.html +1 -1
  163. package/dist/ui-tmp/ui/export.html +1 -1
  164. package/package.json +8 -8
  165. package/dist/index.d.ts +0 -19
  166. package/dist/index.d.ts.map +0 -1
  167. package/dist/index.js +0 -694
  168. package/dist/index.js.map +0 -1
  169. package/dist/lib/crypto/decrypt.d.ts.map +0 -1
  170. package/dist/lib/crypto/decrypt.js.map +0 -1
  171. package/dist/lib/crypto/encrypt.d.ts.map +0 -1
  172. package/dist/lib/crypto/encrypt.js.map +0 -1
  173. package/dist/lib/crypto/index.d.ts.map +0 -1
  174. package/dist/lib/crypto/index.js.map +0 -1
  175. package/dist/lib/crypto/key-derivation.d.ts.map +0 -1
  176. package/dist/lib/crypto/key-derivation.js.map +0 -1
  177. package/dist/lib/crypto/types.d.ts.map +0 -1
  178. package/dist/lib/crypto/types.js.map +0 -1
  179. package/dist/lib/storage/database.d.ts.map +0 -1
  180. package/dist/lib/storage/database.js.map +0 -1
  181. package/dist/lib/storage/export.d.ts.map +0 -1
  182. package/dist/lib/storage/export.js.map +0 -1
  183. package/dist/lib/storage/git.d.ts.map +0 -1
  184. package/dist/lib/storage/git.js.map +0 -1
  185. package/dist/lib/storage/index.d.ts.map +0 -1
  186. package/dist/lib/storage/index.js.map +0 -1
  187. package/dist/lib/storage/schema.d.ts.map +0 -1
  188. package/dist/lib/storage/schema.js.map +0 -1
  189. package/dist/lib/storage/types.d.ts.map +0 -1
  190. package/dist/test-helpers.d.ts.map +0 -1
  191. package/dist/test-helpers.js.map +0 -1
  192. package/dist/types.d.ts.map +0 -1
  193. package/dist/types.js.map +0 -1
  194. package/dist/ui/register.d.ts.map +0 -1
  195. package/dist/ui/register.js +0 -154
  196. package/dist/ui/register.js.map +0 -1
  197. /package/dist/{lib → src/lib}/crypto/decrypt.d.ts +0 -0
  198. /package/dist/{lib → src/lib}/crypto/encrypt.d.ts +0 -0
  199. /package/dist/{lib → src/lib}/crypto/encrypt.js +0 -0
  200. /package/dist/{lib → src/lib}/crypto/types.d.ts +0 -0
  201. /package/dist/{lib → src/lib}/crypto/types.js +0 -0
  202. /package/dist/{lib → src/lib}/storage/export.d.ts +0 -0
  203. /package/dist/{lib → src/lib}/storage/schema.d.ts +0 -0
  204. /package/dist/{lib → src/lib}/storage/types.d.ts +0 -0
  205. /package/dist/{lib → src/lib}/storage/types.js +0 -0
  206. /package/dist/{types.js → src/types.js} +0 -0
  207. /package/dist/{ui → src/ui}/register.d.ts +0 -0
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { EvidenceDatabase, storeSalt, retrieveSalt, } from "./lib/storage/index.js";
5
+ import { deriveKey, rederiveKey } from "./lib/crypto/index.js";
6
+ import { registerUIResources } from "./ui/register.js";
7
+ import { getErrorMessage } from "./lib/tool-wrapper.js";
8
+ import { decrypt } from "./lib/crypto/index.js";
9
+ // Import all tool handlers
10
+ import { captureFootprintSchema, captureFootprintMetadata, createCaptureFootprintHandler, listFootprintsSchema, listFootprintsMetadata, createListFootprintsHandler, exportFootprintsSchema, exportFootprintsMetadata, createExportFootprintsHandler, getFootprintSchema, getFootprintMetadata, createGetFootprintHandler, searchFootprintsSchema, searchFootprintsMetadata, createSearchFootprintsHandler, verifyFootprintSchema, verifyFootprintMetadata, createVerifyFootprintHandler, suggestCaptureSchema, suggestCaptureMetadata, createSuggestCaptureHandler, deleteFootprintsSchema, deleteFootprintsMetadata, createDeleteFootprintsHandler, renameTagSchema, renameTagMetadata, createRenameTagHandler, removeTagSchema, removeTagMetadata, createRemoveTagHandler, getTagStatsSchema, getTagStatsMetadata, createGetTagStatsHandler, } from "./tools/index.js";
11
+ /**
12
+ * Footprint Server - Captures LLM conversations as encrypted evidence
13
+ * with Git timestamps and export capabilities.
14
+ */
15
+ export class FootprintServer {
16
+ server;
17
+ config;
18
+ db;
19
+ derivedKey = null;
20
+ keyDerivationPromise = null;
21
+ constructor(config) {
22
+ this.config = config;
23
+ try {
24
+ this.db = new EvidenceDatabase(config.dbPath);
25
+ }
26
+ catch (error) {
27
+ throw new Error(`Failed to initialize database: ${getErrorMessage(error)}`);
28
+ }
29
+ this.server = new McpServer({
30
+ name: config.name || "traceguard-mcp",
31
+ version: config.version || "0.1.0",
32
+ });
33
+ // Register UI resources for MCP Apps
34
+ registerUIResources(this.server);
35
+ this.registerTools();
36
+ this.registerResources();
37
+ }
38
+ /**
39
+ * Get or derive encryption key using stored salt (thread-safe)
40
+ * Caches key in memory for performance, with cleanup on shutdown
41
+ * Handles concurrent calls by ensuring only one derivation happens at a time
42
+ *
43
+ * @returns 32-byte encryption key
44
+ * @throws Error if salt storage fails
45
+ */
46
+ async getDerivedKey() {
47
+ // Fast path: key already derived
48
+ if (this.derivedKey) {
49
+ return this.derivedKey;
50
+ }
51
+ // If derivation is in progress, wait for it to complete
52
+ if (this.keyDerivationPromise) {
53
+ return this.keyDerivationPromise;
54
+ }
55
+ // Start derivation (only one caller proceeds here)
56
+ this.keyDerivationPromise = (async () => {
57
+ try {
58
+ // Check if salt exists in database
59
+ const existingSalt = retrieveSalt(this.db.getDb());
60
+ let result;
61
+ if (existingSalt) {
62
+ // Re-derive key using stored salt
63
+ result = await rederiveKey(this.config.password, existingSalt);
64
+ }
65
+ else {
66
+ // First-time: generate new key and store salt
67
+ result = await deriveKey(this.config.password);
68
+ storeSalt(this.db.getDb(), result.salt);
69
+ }
70
+ this.derivedKey = result.key;
71
+ return result.key;
72
+ }
73
+ finally {
74
+ // Clear promise after derivation completes (success or failure)
75
+ this.keyDerivationPromise = null;
76
+ }
77
+ })();
78
+ return this.keyDerivationPromise;
79
+ }
80
+ /**
81
+ * Securely clear derived key from memory
82
+ * Should be called on server shutdown
83
+ */
84
+ clearDerivedKey() {
85
+ if (this.derivedKey) {
86
+ // Zero out key in memory
87
+ this.derivedKey.fill(0);
88
+ this.derivedKey = null;
89
+ }
90
+ }
91
+ registerTools() {
92
+ // Capture footprint tool
93
+ this.server.registerTool("capture-footprint", {
94
+ ...captureFootprintMetadata,
95
+ inputSchema: captureFootprintSchema.inputSchema,
96
+ outputSchema: captureFootprintSchema.outputSchema,
97
+ }, createCaptureFootprintHandler(this.db, this.getDerivedKey.bind(this)));
98
+ // List footprints tool
99
+ this.server.registerTool("list-footprints", {
100
+ ...listFootprintsMetadata,
101
+ inputSchema: listFootprintsSchema.inputSchema,
102
+ outputSchema: listFootprintsSchema.outputSchema,
103
+ }, createListFootprintsHandler(this.db));
104
+ // Export footprints tool
105
+ this.server.registerTool("export-footprints", {
106
+ ...exportFootprintsMetadata,
107
+ inputSchema: exportFootprintsSchema.inputSchema,
108
+ outputSchema: exportFootprintsSchema.outputSchema,
109
+ }, createExportFootprintsHandler(this.db));
110
+ // Get footprint tool
111
+ this.server.registerTool("get-footprint", {
112
+ ...getFootprintMetadata,
113
+ inputSchema: getFootprintSchema.inputSchema,
114
+ outputSchema: getFootprintSchema.outputSchema,
115
+ }, createGetFootprintHandler(this.db, this.getDerivedKey.bind(this)));
116
+ // Search footprints tool
117
+ this.server.registerTool("search-footprints", {
118
+ ...searchFootprintsMetadata,
119
+ inputSchema: searchFootprintsSchema.inputSchema,
120
+ outputSchema: searchFootprintsSchema.outputSchema,
121
+ }, createSearchFootprintsHandler(this.db));
122
+ // Verify footprint tool
123
+ this.server.registerTool("verify-footprint", {
124
+ ...verifyFootprintMetadata,
125
+ inputSchema: verifyFootprintSchema.inputSchema,
126
+ outputSchema: verifyFootprintSchema.outputSchema,
127
+ }, createVerifyFootprintHandler(this.db, this.getDerivedKey.bind(this)));
128
+ // Suggest capture tool
129
+ this.server.registerTool("suggest-capture", {
130
+ ...suggestCaptureMetadata,
131
+ inputSchema: suggestCaptureSchema.inputSchema,
132
+ outputSchema: suggestCaptureSchema.outputSchema,
133
+ }, createSuggestCaptureHandler());
134
+ // Delete footprints tool
135
+ this.server.registerTool("delete-footprints", {
136
+ ...deleteFootprintsMetadata,
137
+ inputSchema: deleteFootprintsSchema.inputSchema,
138
+ outputSchema: deleteFootprintsSchema.outputSchema,
139
+ }, createDeleteFootprintsHandler(this.db));
140
+ // Rename tag tool
141
+ this.server.registerTool("rename-tag", {
142
+ ...renameTagMetadata,
143
+ inputSchema: renameTagSchema.inputSchema,
144
+ outputSchema: renameTagSchema.outputSchema,
145
+ }, createRenameTagHandler(this.db));
146
+ // Remove tag tool
147
+ this.server.registerTool("remove-tag", {
148
+ ...removeTagMetadata,
149
+ inputSchema: removeTagSchema.inputSchema,
150
+ outputSchema: removeTagSchema.outputSchema,
151
+ }, createRemoveTagHandler(this.db));
152
+ // Get tag statistics tool
153
+ this.server.registerTool("get-tag-stats", {
154
+ ...getTagStatsMetadata,
155
+ inputSchema: getTagStatsSchema.inputSchema,
156
+ outputSchema: getTagStatsSchema.outputSchema,
157
+ }, createGetTagStatsHandler(this.db));
158
+ }
159
+ registerResources() {
160
+ this.server.registerResource("evidence", new ResourceTemplate("evidence://{id}", { list: undefined }), {
161
+ title: "Evidence Content",
162
+ description: "Access encrypted footprint record by ID",
163
+ mimeType: "text/plain",
164
+ }, async (uri, { id }) => {
165
+ try {
166
+ const evidence = this.db.findById(id);
167
+ if (!evidence) {
168
+ throw new Error(`Evidence with ID ${id} not found`);
169
+ }
170
+ const key = await this.getDerivedKey();
171
+ const decrypted = decrypt(evidence.encryptedContent, evidence.nonce, key);
172
+ return {
173
+ contents: [
174
+ { uri: uri.href, mimeType: "text/plain", text: decrypted },
175
+ ],
176
+ };
177
+ }
178
+ catch (error) {
179
+ throw new Error(`Failed to access evidence resource: ${getErrorMessage(error)}`);
180
+ }
181
+ });
182
+ }
183
+ async start() {
184
+ const transport = new StdioServerTransport();
185
+ await this.server.connect(transport);
186
+ }
187
+ /**
188
+ * Cleanup server resources
189
+ * Clears derived key from memory and closes database
190
+ */
191
+ close() {
192
+ this.clearDerivedKey();
193
+ this.db.close();
194
+ }
195
+ }
196
+ async function main() {
197
+ const config = {
198
+ dbPath: process.env.FOOTPRINT_DB_PATH || "./evidence.db",
199
+ password: process.env.FOOTPRINT_PASSWORD || "",
200
+ };
201
+ if (!config.password) {
202
+ console.error("Error: FOOTPRINT_PASSWORD environment variable required");
203
+ process.exit(1);
204
+ }
205
+ const server = new FootprintServer(config);
206
+ // Setup cleanup handlers for graceful shutdown
207
+ const cleanup = () => {
208
+ server.close();
209
+ };
210
+ // Handle uncaught exceptions and promise rejections
211
+ process.on("uncaughtException", (error) => {
212
+ console.error("Uncaught exception:", error);
213
+ cleanup();
214
+ process.exit(1);
215
+ });
216
+ process.on("unhandledRejection", (reason) => {
217
+ console.error("Unhandled rejection:", reason);
218
+ cleanup();
219
+ process.exit(1);
220
+ });
221
+ process.on("SIGINT", () => {
222
+ cleanup();
223
+ process.exit(0);
224
+ });
225
+ process.on("SIGTERM", () => {
226
+ cleanup();
227
+ process.exit(0);
228
+ });
229
+ process.on("exit", cleanup);
230
+ await server.start();
231
+ }
232
+ // Handle both direct execution and symlink execution
233
+ const isMainModule = import.meta.url === `file://${process.argv[1]}` ||
234
+ process.argv[1]?.endsWith("/footprint") ||
235
+ process.argv[1]?.endsWith("/dist/index.js");
236
+ if (isMainModule) {
237
+ main().catch((error) => {
238
+ console.error("Server error:", error);
239
+ process.exit(1);
240
+ });
241
+ }
242
+ export { FootprintTestHelpers } from "./test-helpers.js";
243
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/decrypt.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,UAAU,GACd,MAAM,CA0BR"}
@@ -24,6 +24,10 @@ export function decrypt(ciphertext, nonce, key) {
24
24
  return new TextDecoder().decode(plaintextBytes);
25
25
  }
26
26
  catch (error) {
27
+ // Log detailed error for debugging (server-side only, never exposed to client)
28
+ const originalError = error instanceof Error ? error.message : String(error);
29
+ console.error('[Decrypt] Decryption failed:', originalError);
30
+ // User-facing error remains generic (security best practice)
27
31
  throw new Error('Decryption failed: invalid key or tampered data');
28
32
  }
29
33
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.js","sourceRoot":"","sources":["../../../../src/lib/crypto/decrypt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,UAAsB,EACtB,KAAiB,EACjB,GAAe;IAEf,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,yBAAyB;IACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,wCAAwC;QACxC,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAElD,+BAA+B;QAC/B,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+EAA+E;QAC/E,MAAM,aAAa,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAC;QAE7D,6DAA6D;QAC7D,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/encrypt.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,aAAa,CAkBzE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../../../src/lib/crypto/encrypt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOlD;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,GAAe;IACxD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,2DAA2D;IAC3D,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAE9B,6BAA6B;IAC7B,MAAM,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE3D,yBAAyB;IACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,8BAA8B;IAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAElD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC"}
@@ -1,4 +1,4 @@
1
- export { deriveKey, verifyKey } from './key-derivation.js';
1
+ export { deriveKey, rederiveKey, verifyKey } from './key-derivation.js';
2
2
  export { encrypt } from './encrypt.js';
3
3
  export { decrypt } from './decrypt.js';
4
4
  export type { DerivedKey, KeyDerivationParams, EncryptedData } from './types.js';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- export { deriveKey, verifyKey } from './key-derivation.js';
1
+ export { deriveKey, rederiveKey, verifyKey } from './key-derivation.js';
2
2
  export { encrypt } from './encrypt.js';
3
3
  export { decrypt } from './decrypt.js';
4
4
  export { DEFAULT_KDF_PARAMS } from './types.js';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -19,12 +19,26 @@ import type { DerivedKey, KeyDerivationParams } from './types.js';
19
19
  */
20
20
  export declare function deriveKey(password: string, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
21
21
  /**
22
- * Re-derive key from password and existing salt (for verification)
22
+ * Re-derive key from password and existing salt
23
+ * Use this for subsequent encryptions/decryptions with stored salt
23
24
  *
24
25
  * @param password - User password
25
- * @param salt - Existing salt (from previous derivation)
26
+ * @param salt - Existing salt (from database)
26
27
  * @param params - Optional KDF parameters
27
28
  * @returns Derived key with same salt
28
29
  */
29
- export declare function verifyKey(password: string, salt: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
30
+ export declare function rederiveKey(password: string, salt: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<DerivedKey>;
31
+ /**
32
+ * Verify password by comparing derived key with expected key
33
+ * Uses constant-time comparison to prevent timing attacks
34
+ *
35
+ * @param password - User password to verify
36
+ * @param salt - Existing salt (from database)
37
+ * @param expectedKey - Expected key (from previous derivation)
38
+ * @param params - Optional KDF parameters
39
+ * @returns true if password is correct, false otherwise
40
+ *
41
+ * @security Uses timingSafeEqual to prevent timing attacks
42
+ */
43
+ export declare function verifyKey(password: string, salt: Uint8Array, expectedKey: Uint8Array, params?: Partial<KeyDerivationParams>): Promise<boolean>;
30
44
  //# sourceMappingURL=key-derivation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/key-derivation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGlE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CAuBrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CAwBrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,UAAU,EACvB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACxC,OAAO,CAAC,OAAO,CAAC,CAkClB"}
@@ -1,5 +1,6 @@
1
1
  import { argon2id } from '@noble/hashes/argon2';
2
2
  import { randomBytes } from '@noble/hashes/utils';
3
+ import { timingSafeEqual } from 'node:crypto';
3
4
  import { DEFAULT_KDF_PARAMS } from './types.js';
4
5
  /**
5
6
  * Derive encryption key from password using Argon2id
@@ -36,14 +37,15 @@ export async function deriveKey(password, params = {}) {
36
37
  return { key, salt };
37
38
  }
38
39
  /**
39
- * Re-derive key from password and existing salt (for verification)
40
+ * Re-derive key from password and existing salt
41
+ * Use this for subsequent encryptions/decryptions with stored salt
40
42
  *
41
43
  * @param password - User password
42
- * @param salt - Existing salt (from previous derivation)
44
+ * @param salt - Existing salt (from database)
43
45
  * @param params - Optional KDF parameters
44
46
  * @returns Derived key with same salt
45
47
  */
46
- export async function verifyKey(password, salt, params = {}) {
48
+ export async function rederiveKey(password, salt, params = {}) {
47
49
  if (!password || password.length === 0) {
48
50
  throw new Error('Password cannot be empty');
49
51
  }
@@ -60,4 +62,43 @@ export async function verifyKey(password, salt, params = {}) {
60
62
  });
61
63
  return { key, salt };
62
64
  }
65
+ /**
66
+ * Verify password by comparing derived key with expected key
67
+ * Uses constant-time comparison to prevent timing attacks
68
+ *
69
+ * @param password - User password to verify
70
+ * @param salt - Existing salt (from database)
71
+ * @param expectedKey - Expected key (from previous derivation)
72
+ * @param params - Optional KDF parameters
73
+ * @returns true if password is correct, false otherwise
74
+ *
75
+ * @security Uses timingSafeEqual to prevent timing attacks
76
+ */
77
+ export async function verifyKey(password, salt, expectedKey, params = {}) {
78
+ if (!password || password.length === 0) {
79
+ throw new Error('Password cannot be empty');
80
+ }
81
+ if (salt.length !== 16) {
82
+ throw new Error('Salt must be 16 bytes');
83
+ }
84
+ if (expectedKey.length !== 32) {
85
+ throw new Error('Expected key must be 32 bytes');
86
+ }
87
+ const kdfParams = { ...DEFAULT_KDF_PARAMS, ...params };
88
+ // Re-derive key using same salt
89
+ const derivedKey = argon2id(password, salt, {
90
+ m: kdfParams.memory,
91
+ t: kdfParams.iterations,
92
+ p: kdfParams.parallelism,
93
+ dkLen: kdfParams.keyLength,
94
+ });
95
+ // Constant-time comparison to prevent timing attacks
96
+ try {
97
+ return timingSafeEqual(Buffer.from(derivedKey), Buffer.from(expectedKey));
98
+ }
99
+ catch {
100
+ // timingSafeEqual throws if lengths don't match
101
+ return false;
102
+ }
103
+ }
63
104
  //# sourceMappingURL=key-derivation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.js","sourceRoot":"","sources":["../../../../src/lib/crypto/key-derivation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/crypto/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,mBAKhC,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/crypto/types.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB;IACrD,MAAM,EAAE,KAAK,EAAO,QAAQ;IAC5B,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,EAAE;CACd,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Base error class for all Footprint errors
3
+ * Provides structured error information with error codes and HTTP-like status codes
4
+ */
5
+ export declare abstract class FootprintError extends Error {
6
+ readonly code: string;
7
+ readonly statusCode: number;
8
+ readonly context?: Record<string, unknown> | undefined;
9
+ constructor(message: string, code: string, statusCode: number, context?: Record<string, unknown> | undefined);
10
+ /**
11
+ * Convert error to JSON format for logging or API responses
12
+ */
13
+ toJSON(): Record<string, unknown>;
14
+ }
15
+ //# sourceMappingURL=base-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-error.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/base-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,8BAAsB,cAAe,SAAQ,KAAK;aAG9B,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;aAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAHjD,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;IAWnD;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAUlC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Base error class for all Footprint errors
3
+ * Provides structured error information with error codes and HTTP-like status codes
4
+ */
5
+ export class FootprintError extends Error {
6
+ code;
7
+ statusCode;
8
+ context;
9
+ constructor(message, code, statusCode, context) {
10
+ super(message);
11
+ this.code = code;
12
+ this.statusCode = statusCode;
13
+ this.context = context;
14
+ this.name = this.constructor.name;
15
+ // Maintains proper stack trace for where error was thrown (V8 only)
16
+ if (Error.captureStackTrace) {
17
+ Error.captureStackTrace(this, this.constructor);
18
+ }
19
+ }
20
+ /**
21
+ * Convert error to JSON format for logging or API responses
22
+ */
23
+ toJSON() {
24
+ return {
25
+ name: this.name,
26
+ message: this.message,
27
+ code: this.code,
28
+ statusCode: this.statusCode,
29
+ context: this.context,
30
+ stack: this.stack
31
+ };
32
+ }
33
+ }
34
+ //# sourceMappingURL=base-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-error.js","sourceRoot":"","sources":["../../../../src/lib/errors/base-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAgB,cAAe,SAAQ,KAAK;IAG9B;IACA;IACA;IAJlB,YACE,OAAe,EACC,IAAY,EACZ,UAAkB,EAClB,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAClB,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAElC,oEAAoE;QACpE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import { FootprintError } from './base-error.js';
2
+ /**
3
+ * Cryptography error for encryption, decryption, and key operations
4
+ * HTTP status code: 500 (Internal Server Error)
5
+ */
6
+ export declare class CryptoError extends FootprintError {
7
+ constructor(message: string, context?: Record<string, unknown>);
8
+ /**
9
+ * Create a crypto error for encryption failures
10
+ */
11
+ static encryptionFailed(originalError: Error): CryptoError;
12
+ /**
13
+ * Create a crypto error for decryption failures
14
+ */
15
+ static decryptionFailed(reason?: string): CryptoError;
16
+ /**
17
+ * Create a crypto error for key derivation failures
18
+ */
19
+ static keyDerivationFailed(originalError: Error): CryptoError;
20
+ /**
21
+ * Create a crypto error for invalid key
22
+ */
23
+ static invalidKey(reason: string): CryptoError;
24
+ /**
25
+ * Create a crypto error for invalid nonce
26
+ */
27
+ static invalidNonce(reason: string): CryptoError;
28
+ }
29
+ //# sourceMappingURL=crypto-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-error.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/crypto-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,qBAAa,WAAY,SAAQ,cAAc;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI9D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW;IAO1D;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW;IASrD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,KAAK,GAAG,WAAW;IAO7D;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;IAI9C;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;CAGjD"}
@@ -0,0 +1,43 @@
1
+ import { FootprintError } from './base-error.js';
2
+ /**
3
+ * Cryptography error for encryption, decryption, and key operations
4
+ * HTTP status code: 500 (Internal Server Error)
5
+ */
6
+ export class CryptoError extends FootprintError {
7
+ constructor(message, context) {
8
+ super(message, 'CRYPTO_ERROR', 500, context);
9
+ }
10
+ /**
11
+ * Create a crypto error for encryption failures
12
+ */
13
+ static encryptionFailed(originalError) {
14
+ return new CryptoError(`Encryption failed: ${originalError.message}`, { originalError: originalError.message });
15
+ }
16
+ /**
17
+ * Create a crypto error for decryption failures
18
+ */
19
+ static decryptionFailed(reason) {
20
+ return new CryptoError(reason
21
+ ? `Decryption failed: ${reason}`
22
+ : 'Decryption failed: invalid key or tampered data', { reason });
23
+ }
24
+ /**
25
+ * Create a crypto error for key derivation failures
26
+ */
27
+ static keyDerivationFailed(originalError) {
28
+ return new CryptoError(`Key derivation failed: ${originalError.message}`, { originalError: originalError.message });
29
+ }
30
+ /**
31
+ * Create a crypto error for invalid key
32
+ */
33
+ static invalidKey(reason) {
34
+ return new CryptoError(`Invalid key: ${reason}`, { reason });
35
+ }
36
+ /**
37
+ * Create a crypto error for invalid nonce
38
+ */
39
+ static invalidNonce(reason) {
40
+ return new CryptoError(`Invalid nonce: ${reason}`, { reason });
41
+ }
42
+ }
43
+ //# sourceMappingURL=crypto-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-error.js","sourceRoot":"","sources":["../../../../src/lib/errors/crypto-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,cAAc;IAC7C,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,aAAoB;QAC1C,OAAO,IAAI,WAAW,CACpB,sBAAsB,aAAa,CAAC,OAAO,EAAE,EAC7C,EAAE,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,CACzC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAe;QACrC,OAAO,IAAI,WAAW,CACpB,MAAM;YACJ,CAAC,CAAC,sBAAsB,MAAM,EAAE;YAChC,CAAC,CAAC,iDAAiD,EACrD,EAAE,MAAM,EAAE,CACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,aAAoB;QAC7C,OAAO,IAAI,WAAW,CACpB,0BAA0B,aAAa,CAAC,OAAO,EAAE,EACjD,EAAE,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,CACzC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAc;QAC9B,OAAO,IAAI,WAAW,CAAC,gBAAgB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAc;QAChC,OAAO,IAAI,WAAW,CAAC,kBAAkB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Structured error hierarchy for Footprint MCP server
3
+ *
4
+ * Usage:
5
+ * ```typescript
6
+ * import { ValidationError, StorageError, CryptoError } from './lib/errors/index.js';
7
+ *
8
+ * // Validation errors (HTTP 400)
9
+ * throw ValidationError.required('conversationId');
10
+ * throw ValidationError.invalidFormat('tags', 'comma-separated string');
11
+ * throw new ValidationError('Content cannot be empty', { field: 'content' });
12
+ *
13
+ * // Storage errors (HTTP 500)
14
+ * throw StorageError.notFound('Evidence', id);
15
+ * throw StorageError.databaseOperation('insert', error);
16
+ *
17
+ * // Crypto errors (HTTP 500)
18
+ * throw CryptoError.decryptionFailed();
19
+ * throw CryptoError.invalidKey('Key must be 32 bytes');
20
+ * ```
21
+ */
22
+ export { FootprintError } from './base-error.js';
23
+ export { ValidationError } from './validation-error.js';
24
+ export { StorageError } from './storage-error.js';
25
+ export { CryptoError } from './crypto-error.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Structured error hierarchy for Footprint MCP server
3
+ *
4
+ * Usage:
5
+ * ```typescript
6
+ * import { ValidationError, StorageError, CryptoError } from './lib/errors/index.js';
7
+ *
8
+ * // Validation errors (HTTP 400)
9
+ * throw ValidationError.required('conversationId');
10
+ * throw ValidationError.invalidFormat('tags', 'comma-separated string');
11
+ * throw new ValidationError('Content cannot be empty', { field: 'content' });
12
+ *
13
+ * // Storage errors (HTTP 500)
14
+ * throw StorageError.notFound('Evidence', id);
15
+ * throw StorageError.databaseOperation('insert', error);
16
+ *
17
+ * // Crypto errors (HTTP 500)
18
+ * throw CryptoError.decryptionFailed();
19
+ * throw CryptoError.invalidKey('Key must be 32 bytes');
20
+ * ```
21
+ */
22
+ export { FootprintError } from './base-error.js';
23
+ export { ValidationError } from './validation-error.js';
24
+ export { StorageError } from './storage-error.js';
25
+ export { CryptoError } from './crypto-error.js';
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}