@hasna/mementos 0.1.2 → 0.3.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.
package/dist/mcp/index.js CHANGED
@@ -4217,6 +4217,34 @@ function resolvePartialId(db, table, partialId) {
4217
4217
  return null;
4218
4218
  }
4219
4219
 
4220
+ // src/lib/redact.ts
4221
+ var REDACTED = "[REDACTED]";
4222
+ var SECRET_PATTERNS = [
4223
+ { name: "openai_key", pattern: /sk-[a-zA-Z0-9_-]{20,}/g },
4224
+ { name: "anthropic_key", pattern: /sk-ant-[a-zA-Z0-9_-]{20,}/g },
4225
+ { name: "generic_key", pattern: /(?:pk|tok|key|token|api[_-]?key)[_-][a-zA-Z0-9_-]{16,}/gi },
4226
+ { name: "aws_key", pattern: /AKIA[A-Z0-9]{16}/g },
4227
+ { name: "aws_secret", pattern: /(?<=AWS_SECRET_ACCESS_KEY\s*=\s*)[A-Za-z0-9/+=]{40}/g },
4228
+ { name: "github_token", pattern: /gh[ps]_[a-zA-Z0-9]{36,}/g },
4229
+ { name: "github_oauth", pattern: /gho_[a-zA-Z0-9]{36,}/g },
4230
+ { name: "npm_token", pattern: /npm_[a-zA-Z0-9]{36,}/g },
4231
+ { name: "bearer", pattern: /Bearer\s+[a-zA-Z0-9_\-.]{20,}/g },
4232
+ { name: "conn_string", pattern: /(?:postgres|postgresql|mysql|mongodb|redis|amqp|mqtt):\/\/[^\s"'`]+@[^\s"'`]+/gi },
4233
+ { name: "env_secret", pattern: /(?:SECRET|TOKEN|PASSWORD|PASSPHRASE|API_KEY|PRIVATE_KEY|AUTH|CREDENTIAL)[_A-Z]*\s*=\s*["']?[^\s"'\n]{8,}["']?/gi },
4234
+ { name: "stripe_key", pattern: /(?:sk|pk|rk)_(?:test|live)_[a-zA-Z0-9]{20,}/g },
4235
+ { name: "slack_token", pattern: /xox[bpras]-[a-zA-Z0-9-]{20,}/g },
4236
+ { name: "jwt", pattern: /eyJ[a-zA-Z0-9_-]{10,}\.eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g },
4237
+ { name: "hex_secret", pattern: /(?<=(?:key|token|secret|password|hash)\s*[:=]\s*["']?)[0-9a-f]{32,}(?=["']?)/gi }
4238
+ ];
4239
+ function redactSecrets(text) {
4240
+ let result = text;
4241
+ for (const { pattern } of SECRET_PATTERNS) {
4242
+ pattern.lastIndex = 0;
4243
+ result = result.replace(pattern, REDACTED);
4244
+ }
4245
+ return result;
4246
+ }
4247
+
4220
4248
  // src/db/memories.ts
4221
4249
  function parseMemoryRow(row) {
4222
4250
  return {
@@ -4254,6 +4282,8 @@ function createMemory(input, dedupeMode = "merge", db) {
4254
4282
  const tags = input.tags || [];
4255
4283
  const tagsJson = JSON.stringify(tags);
4256
4284
  const metadataJson = JSON.stringify(input.metadata || {});
4285
+ const safeValue = redactSecrets(input.value);
4286
+ const safeSummary = input.summary ? redactSecrets(input.summary) : null;
4257
4287
  if (dedupeMode === "merge") {
4258
4288
  const existing = d.query(`SELECT id, version FROM memories
4259
4289
  WHERE key = ? AND scope = ?
@@ -4267,9 +4297,9 @@ function createMemory(input, dedupeMode = "merge", db) {
4267
4297
  pinned = COALESCE(pinned, 0),
4268
4298
  version = version + 1, updated_at = ?
4269
4299
  WHERE id = ?`, [
4270
- input.value,
4300
+ safeValue,
4271
4301
  input.category || "knowledge",
4272
- input.summary || null,
4302
+ safeSummary,
4273
4303
  tagsJson,
4274
4304
  input.importance ?? 5,
4275
4305
  metadataJson,
@@ -4448,7 +4478,7 @@ function updateMemory(id, input, db) {
4448
4478
  const params = [now()];
4449
4479
  if (input.value !== undefined) {
4450
4480
  sets.push("value = ?");
4451
- params.push(input.value);
4481
+ params.push(redactSecrets(input.value));
4452
4482
  }
4453
4483
  if (input.category !== undefined) {
4454
4484
  sets.push("category = ?");
@@ -4647,11 +4677,211 @@ function listProjects(db) {
4647
4677
  return rows.map(parseProjectRow);
4648
4678
  }
4649
4679
 
4680
+ // src/lib/search.ts
4681
+ function parseMemoryRow2(row) {
4682
+ return {
4683
+ id: row["id"],
4684
+ key: row["key"],
4685
+ value: row["value"],
4686
+ category: row["category"],
4687
+ scope: row["scope"],
4688
+ summary: row["summary"] || null,
4689
+ tags: JSON.parse(row["tags"] || "[]"),
4690
+ importance: row["importance"],
4691
+ source: row["source"],
4692
+ status: row["status"],
4693
+ pinned: !!row["pinned"],
4694
+ agent_id: row["agent_id"] || null,
4695
+ project_id: row["project_id"] || null,
4696
+ session_id: row["session_id"] || null,
4697
+ metadata: JSON.parse(row["metadata"] || "{}"),
4698
+ access_count: row["access_count"],
4699
+ version: row["version"],
4700
+ expires_at: row["expires_at"] || null,
4701
+ created_at: row["created_at"],
4702
+ updated_at: row["updated_at"],
4703
+ accessed_at: row["accessed_at"] || null
4704
+ };
4705
+ }
4706
+ function determineMatchType(memory, queryLower) {
4707
+ if (memory.key.toLowerCase() === queryLower)
4708
+ return "exact";
4709
+ if (memory.tags.some((t) => t.toLowerCase() === queryLower))
4710
+ return "tag";
4711
+ return "fuzzy";
4712
+ }
4713
+ function computeScore(memory, queryLower) {
4714
+ let score = 0;
4715
+ const keyLower = memory.key.toLowerCase();
4716
+ if (keyLower === queryLower) {
4717
+ score += 10;
4718
+ } else if (keyLower.includes(queryLower)) {
4719
+ score += 7;
4720
+ }
4721
+ if (memory.tags.some((t) => t.toLowerCase() === queryLower)) {
4722
+ score += 6;
4723
+ }
4724
+ if (memory.summary && memory.summary.toLowerCase().includes(queryLower)) {
4725
+ score += 4;
4726
+ }
4727
+ if (memory.value.toLowerCase().includes(queryLower)) {
4728
+ score += 3;
4729
+ }
4730
+ return score;
4731
+ }
4732
+ function searchMemories(query, filter, db) {
4733
+ const d = db || getDatabase();
4734
+ const queryLower = query.toLowerCase();
4735
+ const queryParam = `%${query}%`;
4736
+ const conditions = [];
4737
+ const params = [];
4738
+ conditions.push("m.status = 'active'");
4739
+ conditions.push("(m.expires_at IS NULL OR m.expires_at >= datetime('now'))");
4740
+ conditions.push(`(m.key LIKE ? OR m.value LIKE ? OR m.summary LIKE ? OR m.id IN (SELECT memory_id FROM memory_tags WHERE tag LIKE ?))`);
4741
+ params.push(queryParam, queryParam, queryParam, queryParam);
4742
+ if (filter) {
4743
+ if (filter.scope) {
4744
+ if (Array.isArray(filter.scope)) {
4745
+ conditions.push(`m.scope IN (${filter.scope.map(() => "?").join(",")})`);
4746
+ params.push(...filter.scope);
4747
+ } else {
4748
+ conditions.push("m.scope = ?");
4749
+ params.push(filter.scope);
4750
+ }
4751
+ }
4752
+ if (filter.category) {
4753
+ if (Array.isArray(filter.category)) {
4754
+ conditions.push(`m.category IN (${filter.category.map(() => "?").join(",")})`);
4755
+ params.push(...filter.category);
4756
+ } else {
4757
+ conditions.push("m.category = ?");
4758
+ params.push(filter.category);
4759
+ }
4760
+ }
4761
+ if (filter.source) {
4762
+ if (Array.isArray(filter.source)) {
4763
+ conditions.push(`m.source IN (${filter.source.map(() => "?").join(",")})`);
4764
+ params.push(...filter.source);
4765
+ } else {
4766
+ conditions.push("m.source = ?");
4767
+ params.push(filter.source);
4768
+ }
4769
+ }
4770
+ if (filter.status) {
4771
+ conditions.shift();
4772
+ if (Array.isArray(filter.status)) {
4773
+ conditions.push(`m.status IN (${filter.status.map(() => "?").join(",")})`);
4774
+ params.push(...filter.status);
4775
+ } else {
4776
+ conditions.push("m.status = ?");
4777
+ params.push(filter.status);
4778
+ }
4779
+ }
4780
+ if (filter.project_id) {
4781
+ conditions.push("m.project_id = ?");
4782
+ params.push(filter.project_id);
4783
+ }
4784
+ if (filter.agent_id) {
4785
+ conditions.push("m.agent_id = ?");
4786
+ params.push(filter.agent_id);
4787
+ }
4788
+ if (filter.session_id) {
4789
+ conditions.push("m.session_id = ?");
4790
+ params.push(filter.session_id);
4791
+ }
4792
+ if (filter.min_importance) {
4793
+ conditions.push("m.importance >= ?");
4794
+ params.push(filter.min_importance);
4795
+ }
4796
+ if (filter.pinned !== undefined) {
4797
+ conditions.push("m.pinned = ?");
4798
+ params.push(filter.pinned ? 1 : 0);
4799
+ }
4800
+ if (filter.tags && filter.tags.length > 0) {
4801
+ for (const tag of filter.tags) {
4802
+ conditions.push("m.id IN (SELECT memory_id FROM memory_tags WHERE tag = ?)");
4803
+ params.push(tag);
4804
+ }
4805
+ }
4806
+ }
4807
+ const sql = `SELECT m.* FROM memories m WHERE ${conditions.join(" AND ")}`;
4808
+ const rows = d.query(sql).all(...params);
4809
+ const scored = [];
4810
+ for (const row of rows) {
4811
+ const memory = parseMemoryRow2(row);
4812
+ const rawScore = computeScore(memory, queryLower);
4813
+ if (rawScore === 0)
4814
+ continue;
4815
+ const weightedScore = rawScore * memory.importance / 10;
4816
+ const matchType = determineMatchType(memory, queryLower);
4817
+ scored.push({
4818
+ memory,
4819
+ score: weightedScore,
4820
+ match_type: matchType
4821
+ });
4822
+ }
4823
+ scored.sort((a, b) => {
4824
+ if (b.score !== a.score)
4825
+ return b.score - a.score;
4826
+ return b.memory.importance - a.memory.importance;
4827
+ });
4828
+ const offset = filter?.offset ?? 0;
4829
+ const limit = filter?.limit ?? scored.length;
4830
+ return scored.slice(offset, offset + limit);
4831
+ }
4832
+
4833
+ // src/lib/project-detect.ts
4834
+ import { existsSync as existsSync2 } from "fs";
4835
+ import { basename, dirname as dirname2, join as join2, resolve as resolve2 } from "path";
4836
+ function findGitRoot2(startDir) {
4837
+ let dir = resolve2(startDir);
4838
+ while (true) {
4839
+ if (existsSync2(join2(dir, ".git")))
4840
+ return dir;
4841
+ const parent = dirname2(dir);
4842
+ if (parent === dir)
4843
+ break;
4844
+ dir = parent;
4845
+ }
4846
+ return null;
4847
+ }
4848
+ var _cachedProject = undefined;
4849
+ function detectProject(db) {
4850
+ if (_cachedProject !== undefined)
4851
+ return _cachedProject;
4852
+ const d = db || getDatabase();
4853
+ const cwd = process.cwd();
4854
+ const gitRoot = findGitRoot2(cwd);
4855
+ if (!gitRoot) {
4856
+ _cachedProject = null;
4857
+ return null;
4858
+ }
4859
+ const repoName = basename(gitRoot);
4860
+ const absPath = resolve2(gitRoot);
4861
+ const existing = getProject(absPath, d);
4862
+ if (existing) {
4863
+ _cachedProject = existing;
4864
+ return existing;
4865
+ }
4866
+ const project = registerProject(repoName, absPath, undefined, undefined, d);
4867
+ _cachedProject = project;
4868
+ return project;
4869
+ }
4870
+
4650
4871
  // src/mcp/index.ts
4651
4872
  var server = new McpServer({
4652
4873
  name: "mementos",
4653
4874
  version: "0.1.0"
4654
4875
  });
4876
+ var _autoProjectInitialized = false;
4877
+ function ensureAutoProject() {
4878
+ if (_autoProjectInitialized)
4879
+ return;
4880
+ _autoProjectInitialized = true;
4881
+ try {
4882
+ detectProject();
4883
+ } catch {}
4884
+ }
4655
4885
  function formatError(error) {
4656
4886
  if (error instanceof VersionConflictError)
4657
4887
  return `Version conflict: ${error.message}`;
@@ -4711,17 +4941,18 @@ server.tool("memory_save", "Save a memory (create or upsert). Use scope 'global'
4711
4941
  value: exports_external.string().describe("Memory content/value"),
4712
4942
  scope: exports_external.enum(["global", "shared", "private"]).optional().describe("Memory scope (default: private)"),
4713
4943
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional().describe("Memory category (default: knowledge)"),
4714
- importance: exports_external.number().min(1).max(10).optional().describe("Importance 1-10 (default: 5)"),
4944
+ importance: exports_external.coerce.number().min(1).max(10).optional().describe("Importance 1-10 (default: 5)"),
4715
4945
  tags: exports_external.array(exports_external.string()).optional().describe("Tags for categorization"),
4716
4946
  summary: exports_external.string().optional().describe("Brief summary of the memory"),
4717
4947
  agent_id: exports_external.string().optional().describe("Agent ID (for scoping)"),
4718
4948
  project_id: exports_external.string().optional().describe("Project ID (for scoping)"),
4719
4949
  session_id: exports_external.string().optional().describe("Session ID (for scoping)"),
4720
- ttl_ms: exports_external.number().optional().describe("Time-to-live in milliseconds"),
4950
+ ttl_ms: exports_external.coerce.number().optional().describe("Time-to-live in milliseconds"),
4721
4951
  source: exports_external.enum(["user", "agent", "system", "auto", "imported"]).optional().describe("Source of the memory"),
4722
4952
  metadata: exports_external.record(exports_external.unknown()).optional().describe("Arbitrary metadata")
4723
4953
  }, async (args) => {
4724
4954
  try {
4955
+ ensureAutoProject();
4725
4956
  const memory = createMemory(args);
4726
4957
  return { content: [{ type: "text", text: `Memory saved:
4727
4958
  ${formatMemory(memory)}` }] };
@@ -4737,12 +4968,31 @@ server.tool("memory_recall", "Recall a memory by key. Returns the best matching
4737
4968
  session_id: exports_external.string().optional()
4738
4969
  }, async (args) => {
4739
4970
  try {
4971
+ ensureAutoProject();
4740
4972
  const memory = getMemoryByKey(args.key, args.scope, args.agent_id, args.project_id, args.session_id);
4741
- if (!memory) {
4742
- return { content: [{ type: "text", text: `No memory found for key: ${args.key}` }] };
4973
+ if (memory) {
4974
+ touchMemory(memory.id);
4975
+ return { content: [{ type: "text", text: formatMemory(memory) }] };
4976
+ }
4977
+ const results = searchMemories(args.key, {
4978
+ scope: args.scope,
4979
+ agent_id: args.agent_id,
4980
+ project_id: args.project_id,
4981
+ session_id: args.session_id,
4982
+ limit: 1
4983
+ });
4984
+ if (results.length > 0) {
4985
+ const best = results[0];
4986
+ touchMemory(best.memory.id);
4987
+ return {
4988
+ content: [{
4989
+ type: "text",
4990
+ text: `No exact match for key "${args.key}", showing best result (score: ${best.score.toFixed(2)}, match: ${best.match_type}):
4991
+ ${formatMemory(best.memory)}`
4992
+ }]
4993
+ };
4743
4994
  }
4744
- touchMemory(memory.id);
4745
- return { content: [{ type: "text", text: formatMemory(memory) }] };
4995
+ return { content: [{ type: "text", text: `No memory found for key: ${args.key}` }] };
4746
4996
  } catch (e) {
4747
4997
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
4748
4998
  }
@@ -4751,14 +5001,14 @@ server.tool("memory_list", "List memories with optional filters", {
4751
5001
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
4752
5002
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
4753
5003
  tags: exports_external.array(exports_external.string()).optional(),
4754
- min_importance: exports_external.number().optional(),
5004
+ min_importance: exports_external.coerce.number().optional(),
4755
5005
  pinned: exports_external.boolean().optional(),
4756
5006
  agent_id: exports_external.string().optional(),
4757
5007
  project_id: exports_external.string().optional(),
4758
5008
  session_id: exports_external.string().optional(),
4759
5009
  status: exports_external.enum(["active", "archived", "expired"]).optional(),
4760
- limit: exports_external.number().optional().describe("Max results (default: 50)"),
4761
- offset: exports_external.number().optional()
5010
+ limit: exports_external.coerce.number().optional().describe("Max results (default: 50)"),
5011
+ offset: exports_external.coerce.number().optional()
4762
5012
  }, async (args) => {
4763
5013
  try {
4764
5014
  const filter = {
@@ -4782,14 +5032,14 @@ server.tool("memory_update", "Update a memory's metadata (value, importance, tag
4782
5032
  value: exports_external.string().optional(),
4783
5033
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
4784
5034
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
4785
- importance: exports_external.number().min(1).max(10).optional(),
5035
+ importance: exports_external.coerce.number().min(1).max(10).optional(),
4786
5036
  tags: exports_external.array(exports_external.string()).optional(),
4787
5037
  summary: exports_external.string().nullable().optional(),
4788
5038
  pinned: exports_external.boolean().optional(),
4789
5039
  status: exports_external.enum(["active", "archived", "expired"]).optional(),
4790
5040
  metadata: exports_external.record(exports_external.unknown()).optional(),
4791
5041
  expires_at: exports_external.string().nullable().optional(),
4792
- version: exports_external.number().describe("Current version (for optimistic locking)")
5042
+ version: exports_external.coerce.number().describe("Current version (for optimistic locking)")
4793
5043
  }, async (args) => {
4794
5044
  try {
4795
5045
  const id = resolveId(args.id);
@@ -4834,7 +5084,7 @@ server.tool("memory_search", "Search memories by keyword across key, value, summ
4834
5084
  tags: exports_external.array(exports_external.string()).optional(),
4835
5085
  agent_id: exports_external.string().optional(),
4836
5086
  project_id: exports_external.string().optional(),
4837
- limit: exports_external.number().optional().describe("Max results (default: 20)")
5087
+ limit: exports_external.coerce.number().optional().describe("Max results (default: 20)")
4838
5088
  }, async (args) => {
4839
5089
  try {
4840
5090
  const filter = {
@@ -4923,7 +5173,7 @@ server.tool("memory_import", "Import memories from JSON array", {
4923
5173
  value: exports_external.string(),
4924
5174
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
4925
5175
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
4926
- importance: exports_external.number().optional(),
5176
+ importance: exports_external.coerce.number().optional(),
4927
5177
  tags: exports_external.array(exports_external.string()).optional(),
4928
5178
  summary: exports_external.string().optional(),
4929
5179
  source: exports_external.enum(["user", "agent", "system", "auto", "imported"]).optional(),
@@ -4949,9 +5199,9 @@ server.tool("memory_inject", "Get formatted memory context for injection into ag
4949
5199
  agent_id: exports_external.string().optional().describe("Agent ID for scope filtering"),
4950
5200
  project_id: exports_external.string().optional().describe("Project ID for scope filtering"),
4951
5201
  session_id: exports_external.string().optional().describe("Session ID for scope filtering"),
4952
- max_tokens: exports_external.number().optional().describe("Max approximate token budget (default: 500)"),
5202
+ max_tokens: exports_external.coerce.number().optional().describe("Max approximate token budget (default: 500)"),
4953
5203
  categories: exports_external.array(exports_external.enum(["preference", "fact", "knowledge", "history"])).optional(),
4954
- min_importance: exports_external.number().optional().describe("Minimum importance threshold (default: 3)")
5204
+ min_importance: exports_external.coerce.number().optional().describe("Minimum importance threshold (default: 3)")
4955
5205
  }, async (args) => {
4956
5206
  try {
4957
5207
  const maxTokens = args.max_tokens || 500;
@@ -5162,7 +5412,7 @@ server.tool("bulk_forget", "Delete multiple memories by IDs", {
5162
5412
  });
5163
5413
  server.tool("bulk_update", "Update multiple memories with the same changes", {
5164
5414
  ids: exports_external.array(exports_external.string()).describe("Memory IDs to update"),
5165
- importance: exports_external.number().min(1).max(10).optional(),
5415
+ importance: exports_external.coerce.number().min(1).max(10).optional(),
5166
5416
  tags: exports_external.array(exports_external.string()).optional(),
5167
5417
  pinned: exports_external.boolean().optional(),
5168
5418
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
@@ -5196,7 +5446,7 @@ server.tool("memory_context", "Get all memories relevant to the current context.
5196
5446
  agent_id: exports_external.string().optional(),
5197
5447
  project_id: exports_external.string().optional(),
5198
5448
  scope: exports_external.enum(["global", "shared", "private"]).optional().describe("Limit to specific scope"),
5199
- limit: exports_external.number().optional().describe("Max memories (default: 30)")
5449
+ limit: exports_external.coerce.number().optional().describe("Max memories (default: 30)")
5200
5450
  }, async (args) => {
5201
5451
  try {
5202
5452
  const filter = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAslBH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkD9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAslBH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoG9C"}
@@ -217,6 +217,34 @@ function shortUuid() {
217
217
  return crypto.randomUUID().slice(0, 8);
218
218
  }
219
219
 
220
+ // src/lib/redact.ts
221
+ var REDACTED = "[REDACTED]";
222
+ var SECRET_PATTERNS = [
223
+ { name: "openai_key", pattern: /sk-[a-zA-Z0-9_-]{20,}/g },
224
+ { name: "anthropic_key", pattern: /sk-ant-[a-zA-Z0-9_-]{20,}/g },
225
+ { name: "generic_key", pattern: /(?:pk|tok|key|token|api[_-]?key)[_-][a-zA-Z0-9_-]{16,}/gi },
226
+ { name: "aws_key", pattern: /AKIA[A-Z0-9]{16}/g },
227
+ { name: "aws_secret", pattern: /(?<=AWS_SECRET_ACCESS_KEY\s*=\s*)[A-Za-z0-9/+=]{40}/g },
228
+ { name: "github_token", pattern: /gh[ps]_[a-zA-Z0-9]{36,}/g },
229
+ { name: "github_oauth", pattern: /gho_[a-zA-Z0-9]{36,}/g },
230
+ { name: "npm_token", pattern: /npm_[a-zA-Z0-9]{36,}/g },
231
+ { name: "bearer", pattern: /Bearer\s+[a-zA-Z0-9_\-.]{20,}/g },
232
+ { name: "conn_string", pattern: /(?:postgres|postgresql|mysql|mongodb|redis|amqp|mqtt):\/\/[^\s"'`]+@[^\s"'`]+/gi },
233
+ { name: "env_secret", pattern: /(?:SECRET|TOKEN|PASSWORD|PASSPHRASE|API_KEY|PRIVATE_KEY|AUTH|CREDENTIAL)[_A-Z]*\s*=\s*["']?[^\s"'\n]{8,}["']?/gi },
234
+ { name: "stripe_key", pattern: /(?:sk|pk|rk)_(?:test|live)_[a-zA-Z0-9]{20,}/g },
235
+ { name: "slack_token", pattern: /xox[bpras]-[a-zA-Z0-9-]{20,}/g },
236
+ { name: "jwt", pattern: /eyJ[a-zA-Z0-9_-]{10,}\.eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g },
237
+ { name: "hex_secret", pattern: /(?<=(?:key|token|secret|password|hash)\s*[:=]\s*["']?)[0-9a-f]{32,}(?=["']?)/gi }
238
+ ];
239
+ function redactSecrets(text) {
240
+ let result = text;
241
+ for (const { pattern } of SECRET_PATTERNS) {
242
+ pattern.lastIndex = 0;
243
+ result = result.replace(pattern, REDACTED);
244
+ }
245
+ return result;
246
+ }
247
+
220
248
  // src/db/memories.ts
221
249
  function parseMemoryRow(row) {
222
250
  return {
@@ -254,6 +282,8 @@ function createMemory(input, dedupeMode = "merge", db) {
254
282
  const tags = input.tags || [];
255
283
  const tagsJson = JSON.stringify(tags);
256
284
  const metadataJson = JSON.stringify(input.metadata || {});
285
+ const safeValue = redactSecrets(input.value);
286
+ const safeSummary = input.summary ? redactSecrets(input.summary) : null;
257
287
  if (dedupeMode === "merge") {
258
288
  const existing = d.query(`SELECT id, version FROM memories
259
289
  WHERE key = ? AND scope = ?
@@ -267,9 +297,9 @@ function createMemory(input, dedupeMode = "merge", db) {
267
297
  pinned = COALESCE(pinned, 0),
268
298
  version = version + 1, updated_at = ?
269
299
  WHERE id = ?`, [
270
- input.value,
300
+ safeValue,
271
301
  input.category || "knowledge",
272
- input.summary || null,
302
+ safeSummary,
273
303
  tagsJson,
274
304
  input.importance ?? 5,
275
305
  metadataJson,
@@ -422,7 +452,7 @@ function updateMemory(id, input, db) {
422
452
  const params = [now()];
423
453
  if (input.value !== undefined) {
424
454
  sets.push("value = ?");
425
- params.push(input.value);
455
+ params.push(redactSecrets(input.value));
426
456
  }
427
457
  if (input.category !== undefined) {
428
458
  sets.push("category = ?");
@@ -1158,6 +1188,42 @@ function startServer(port) {
1158
1188
  if (pathname === "/api/health" || pathname === "/health") {
1159
1189
  return json({ status: "ok", version: "0.1.0" });
1160
1190
  }
1191
+ if (pathname === "/api/memories/stream" && req.method === "GET") {
1192
+ const stream = new ReadableStream({
1193
+ start(controller) {
1194
+ const encoder = new TextEncoder;
1195
+ let lastSeen = new Date().toISOString();
1196
+ const send = (data) => {
1197
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}
1198
+
1199
+ `));
1200
+ };
1201
+ send({ type: "connected", timestamp: lastSeen });
1202
+ const interval = setInterval(() => {
1203
+ try {
1204
+ const db = getDatabase();
1205
+ const rows = db.query("SELECT * FROM memories WHERE updated_at > ? OR created_at > ? ORDER BY updated_at DESC LIMIT 50").all(lastSeen, lastSeen);
1206
+ if (rows.length > 0) {
1207
+ lastSeen = new Date().toISOString();
1208
+ send({ type: "memories", data: rows, count: rows.length });
1209
+ }
1210
+ } catch {}
1211
+ }, 1000);
1212
+ req.signal.addEventListener("abort", () => {
1213
+ clearInterval(interval);
1214
+ controller.close();
1215
+ });
1216
+ }
1217
+ });
1218
+ return new Response(stream, {
1219
+ headers: {
1220
+ "Content-Type": "text/event-stream",
1221
+ "Cache-Control": "no-cache",
1222
+ Connection: "keep-alive",
1223
+ ...CORS_HEADERS
1224
+ }
1225
+ });
1226
+ }
1161
1227
  const matched = matchRoute(req.method, pathname);
1162
1228
  if (!matched) {
1163
1229
  if (pathname.startsWith("/api/")) {
@@ -121,6 +121,8 @@ export interface MementosConfig {
121
121
  auto_cleanup: {
122
122
  enabled: boolean;
123
123
  expired_check_interval: number;
124
+ unused_archive_days: number;
125
+ stale_deprioritize_days: number;
124
126
  };
125
127
  }
126
128
  export type DedupeMode = "merge" | "create";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border)}body{background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.relative{position:relative}.end{inset-inline-end:var(--spacing)}.top-2\.5{top:calc(var(--spacing) * 2.5)}.right-2{right:calc(var(--spacing) * 2)}.right-2\.5{right:calc(var(--spacing) * 2.5)}.left-2{left:calc(var(--spacing) * 2)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.z-10{z-index:10}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.-ml-3{margin-left:calc(var(--spacing) * -3)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-24{height:calc(var(--spacing) * 24)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-96{max-height:calc(var(--spacing) * 96)}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-7{width:calc(var(--spacing) * 7)}.w-9{width:calc(var(--spacing) * 9)}.w-\[130px\]{width:130px}.w-\[140px\]{width:140px}.w-\[150px\]{width:150px}.w-full{width:100%}.w-max{width:max-content}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[120px\]{max-width:120px}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-\[300px\]{max-width:300px}.max-w-max{max-width:max-content}.max-w-sm{max-width:var(--container-sm)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[200px\]{min-width:200px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-y-1{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-0{rotate:none}.rotate-90{rotate:90deg}.animate-in{animation:.2s ease-out enter}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500) 30%,transparent)}}.border-border{border-color:var(--border)}.border-gray-500\/30{border-color:#6a72824d}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/30{border-color:color-mix(in oklab,var(--color-gray-500) 30%,transparent)}}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500) 30%,transparent)}}.border-input{border-color:var(--input)}.border-purple-500\/30{border-color:#ac4bff4d}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/30{border-color:color-mix(in oklab,var(--color-purple-500) 30%,transparent)}}.border-teal-500\/30{border-color:#00baa74d}@supports (color:color-mix(in lab,red,red)){.border-teal-500\/30{border-color:color-mix(in oklab,var(--color-teal-500) 30%,transparent)}}.border-transparent{border-color:#0000}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500) 30%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500) 10%,transparent)}}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/15{background-color:color-mix(in oklab,var(--color-amber-500) 15%,transparent)}}.bg-background{background-color:var(--background)}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500) 10%,transparent)}}.bg-blue-500\/15{background-color:#3080ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/15{background-color:color-mix(in oklab,var(--color-blue-500) 15%,transparent)}}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-gray-500\/10{background-color:#6a72821a}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/10{background-color:color-mix(in oklab,var(--color-gray-500) 10%,transparent)}}.bg-gray-500\/15{background-color:#6a728226}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/15{background-color:color-mix(in oklab,var(--color-gray-500) 15%,transparent)}}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500) 10%,transparent)}}.bg-green-500\/15{background-color:#00c75826}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/15{background-color:color-mix(in oklab,var(--color-green-500) 15%,transparent)}}.bg-muted,.bg-muted\/30{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/30{background-color:color-mix(in oklab,var(--muted) 30%,transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500) 10%,transparent)}}.bg-purple-500\/15{background-color:#ac4bff26}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/15{background-color:color-mix(in oklab,var(--color-purple-500) 15%,transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-teal-500\/10{background-color:#00baa71a}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/10{background-color:color-mix(in oklab,var(--color-teal-500) 10%,transparent)}}.bg-teal-500\/15{background-color:#00baa726}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/15{background-color:color-mix(in oklab,var(--color-teal-500) 15%,transparent)}}.bg-transparent{background-color:#0000}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500) 10%,transparent)}}.bg-yellow-500\/15{background-color:#edb20026}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/15{background-color:color-mix(in oklab,var(--color-yellow-500) 15%,transparent)}}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-card-foreground{color:var(--card-foreground)}.text-foreground{color:var(--foreground)}.text-gray-400{color:var(--color-gray-400)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground,.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/50{color:color-mix(in oklab,var(--muted-foreground) 50%,transparent)}}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-purple-400{color:var(--color-purple-400)}.text-purple-500{color:var(--color-purple-500)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-teal-400{color:var(--color-teal-400)}.text-teal-500{color:var(--color-teal-500)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-background\/50:hover{background-color:var(--background)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-background\/50:hover{background-color:color-mix(in oklab,var(--background) 50%,transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive) 90%,transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[active\]\:bg-accent\/50[data-active]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[active\]\:bg-accent\/50[data-active]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media(prefers-color-scheme:dark){.dark\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:-rotate-90{rotate:-90deg}.dark\:rotate-0{rotate:none}.dark\:bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30{background-color:color-mix(in oklab,var(--input) 30%,transparent)}}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@keyframes enter{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}:root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.5% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(96.5% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(96.5% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.1% 0 0);--input:oklch(92.1% 0 0);--ring:oklch(70.8% 0 0)}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(17.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(17.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(98.5% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(39.6% .141 25.723);--border:oklch(26.9% 0 0);--input:oklch(26.9% 0 0);--ring:oklch(43.9% 0 0)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}