memor-cli 0.1.0__py3-none-any.whl

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 (48) hide show
  1. memor/__init__.py +0 -0
  2. memor/cli.py +463 -0
  3. memor/daemon.py +294 -0
  4. memor/dashboard/__init__.py +0 -0
  5. memor/dashboard/server.py +153 -0
  6. memor/dashboard/static/index.html +688 -0
  7. memor/distill/__init__.py +0 -0
  8. memor/distill/distiller.py +112 -0
  9. memor/distill/extractive.py +161 -0
  10. memor/embed/__init__.py +0 -0
  11. memor/embed/api.py +15 -0
  12. memor/embed/fake.py +16 -0
  13. memor/embed/local.py +16 -0
  14. memor/eval/__init__.py +0 -0
  15. memor/eval/baselines/__init__.py +5 -0
  16. memor/eval/baselines/base.py +15 -0
  17. memor/eval/baselines/claude_mem.py +19 -0
  18. memor/eval/baselines/graphiti.py +25 -0
  19. memor/eval/dataset.py +48 -0
  20. memor/eval/embed_benchmark.py +67 -0
  21. memor/eval/judge.py +137 -0
  22. memor/eval/metrics.py +13 -0
  23. memor/eval/runner.py +78 -0
  24. memor/feedback.py +96 -0
  25. memor/hook_server.py +144 -0
  26. memor/ingest/__init__.py +0 -0
  27. memor/ingest/claude_code.py +135 -0
  28. memor/ingest/documents.py +28 -0
  29. memor/interfaces.py +20 -0
  30. memor/llm/__init__.py +0 -0
  31. memor/llm/anthropic.py +14 -0
  32. memor/llm/base.py +7 -0
  33. memor/llm/openai_compat.py +20 -0
  34. memor/project.py +69 -0
  35. memor/recall.py +115 -0
  36. memor/redact.py +129 -0
  37. memor/retrieve/__init__.py +0 -0
  38. memor/retrieve/retriever.py +78 -0
  39. memor/store/__init__.py +0 -0
  40. memor/store/sqlite_store.py +336 -0
  41. memor/tokencount.py +9 -0
  42. memor/types.py +45 -0
  43. memor_cli-0.1.0.dist-info/METADATA +273 -0
  44. memor_cli-0.1.0.dist-info/RECORD +48 -0
  45. memor_cli-0.1.0.dist-info/WHEEL +5 -0
  46. memor_cli-0.1.0.dist-info/entry_points.txt +2 -0
  47. memor_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
  48. memor_cli-0.1.0.dist-info/top_level.txt +1 -0
memor/types.py ADDED
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass, field
3
+
4
+ @dataclass
5
+ class Artifact:
6
+ id: str
7
+ kind: str # session_chunk | research | note | page | memory
8
+ project: str
9
+ source: str
10
+ text: str
11
+ token_count: int
12
+ created_at: float # epoch seconds
13
+ meta: dict = field(default_factory=dict)
14
+
15
+ @dataclass
16
+ class Scope:
17
+ project: str | None = None
18
+ since: float | None = None
19
+ until: float | None = None
20
+ kinds: list[str] | None = None
21
+
22
+ def matches(self, a: "Artifact") -> bool:
23
+ if self.project is not None and a.project != self.project:
24
+ return False
25
+ if self.since is not None and a.created_at < self.since:
26
+ return False
27
+ if self.until is not None and a.created_at > self.until:
28
+ return False
29
+ if self.kinds is not None and a.kind not in self.kinds:
30
+ return False
31
+ return True
32
+
33
+ @dataclass
34
+ class Hit:
35
+ artifact: Artifact
36
+ score: float
37
+ components: dict = field(default_factory=dict) # {'sim','recency','edge'}
38
+
39
+ @dataclass
40
+ class RetrievalTrace:
41
+ query: str
42
+ scope: Scope
43
+ candidates: int
44
+ hits: list[Hit]
45
+ latency_ms: float
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: memor-cli
3
+ Version: 0.1.0
4
+ Summary: Measured memory for coding agents. Fire and forget — no API keys needed.
5
+ Author-email: Nimit Bhandari <nimitbhandari17@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/bnimit/memor-ai
8
+ Project-URL: Repository, https://github.com/bnimit/memor-ai
9
+ Project-URL: Issues, https://github.com/bnimit/memor-ai/issues
10
+ Keywords: memory,agent,claude,embeddings,coding-assistant
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: sqlite-vec>=0.1.6
22
+ Requires-Dist: numpy>=1.26
23
+ Requires-Dist: typer>=0.12
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: tiktoken>=0.7
26
+ Requires-Dist: fastapi>=0.111
27
+ Requires-Dist: uvicorn>=0.30
28
+ Requires-Dist: model2vec>=0.8
29
+ Provides-Extra: api-embed
30
+ Requires-Dist: openai>=1.0; extra == "api-embed"
31
+ Provides-Extra: anthropic
32
+ Requires-Dist: anthropic>=0.40; extra == "anthropic"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8.0; extra == "dev"
35
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
36
+ Dynamic: license-file
37
+
38
+ ```
39
+ _
40
+ _ __ ___ ___ _ __ ___ ___ _ __ __ _(_)
41
+ | '_ ` _ \ / _ \ '_ ` _ \ / _ \| '__|____ / _` | |
42
+ | | | | | | __/ | | | | | (_) | | |_____| (_| | |
43
+ |_| |_| |_|\___|_| |_| |_|\___/|_| \__,_|_|
44
+
45
+ Measured memory for coding agents.
46
+ ```
47
+
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
49
+ [![Tests](https://img.shields.io/badge/tests-153%20passing-brightgreen.svg)]()
50
+ [![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)]()
51
+ [![PyPI](https://img.shields.io/pypi/v/memor-cli.svg)](https://pypi.org/project/memor-cli/)
52
+
53
+ **Automatic background memory for Claude Code.** Fire and forget — no API keys needed.
54
+
55
+ Memor watches your coding sessions, extracts decisions and patterns, and recalls relevant context on every prompt. Zero configuration. One install. Your agent remembers everything.
56
+
57
+ ---
58
+
59
+ ## Quick Start
60
+
61
+ ```bash
62
+ # Install globally (recommended)
63
+ pipx install memor-cli
64
+
65
+ # Install the Claude Code hook + download embedding model (~60MB)
66
+ memor install-hook
67
+
68
+ # Start the background daemon
69
+ memor daemon
70
+ ```
71
+
72
+ That's it. Every Claude Code prompt now gets automatic context recall. Open the dashboard to see it working:
73
+
74
+ ```bash
75
+ memor dashboard
76
+ # Opens http://localhost:8420
77
+ ```
78
+
79
+ > **Alternative install:** `pip install memor-cli` works too — just make sure `~/.local/bin` is on your PATH so the `memor` command is available.
80
+
81
+ ---
82
+
83
+ ## How It Works
84
+
85
+ ```
86
+ You type a prompt in Claude Code
87
+ |
88
+ v
89
+ Hook fires (UserPromptSubmit)
90
+ |
91
+ v
92
+ Embed query locally (model2vec, ~2ms)
93
+ |
94
+ v
95
+ Hybrid scoring: similarity + recency + kind weight + quality
96
+ |
97
+ v
98
+ Inject relevant context into prompt
99
+ |
100
+ v
101
+ Claude sees your past decisions, bugfixes,
102
+ architecture choices — without you re-explaining
103
+ ```
104
+
105
+ **Two background processes:**
106
+
107
+ 1. **Daemon** — polls `~/.claude/projects/` for transcripts, embeds chunks, runs distillation, analyzes feedback, compacts duplicates. All local.
108
+ 2. **Hook** — fires on every prompt, recalls relevant memories, injects them as context. Sub-15ms.
109
+
110
+ **No API keys required.** Embeddings run locally via [model2vec](https://github.com/MinishLab/model2vec) (potion-base-8M, 256-dim). Vectors stored in [sqlite-vec](https://github.com/asg017/sqlite-vec). Everything runs on your machine.
111
+
112
+ ---
113
+
114
+ ## Hybrid Scoring
115
+
116
+ Memor doesn't just match keywords. Each memory is scored by four signals:
117
+
118
+ | Signal | Weight | How it works |
119
+ |---|---|---|
120
+ | **Semantic similarity** | 50% | Vector cosine distance between query and memory |
121
+ | **Recency** | 25% | Exponential decay with 14-day half-life — recent decisions rank higher |
122
+ | **Kind weight** | 15% | Distilled memories (1.3x) rank above raw session chunks (1.0x) |
123
+ | **Quality** | 10% | Bayesian score from implicit feedback — memories the agent actually uses rank higher |
124
+
125
+ This means a relevant decision from yesterday beats a vaguely-related chunk from a month ago — even if the raw embedding similarity is similar.
126
+
127
+ ### Feedback Loop
128
+
129
+ Memor tracks whether recalled memories actually get used by the agent. After each session, the daemon analyzes the transcript to detect if recalled content appeared in the agent's responses. Memories that consistently prove useful get quality boosts; memories never recalled in 30+ days get automatically deactivated. Near-duplicate memories are compacted into one.
130
+
131
+ ---
132
+
133
+ ## What Gets Stored
134
+
135
+ | Kind | Source | Description |
136
+ |---|---|---|
137
+ | `session_chunk` | Daemon auto-ingest | Filtered turns from Claude Code transcripts |
138
+ | `memory` | Extractive distillation | Key decisions, patterns, bugfixes per session |
139
+
140
+ Memories are automatically classified as `decision`, `bugfix`, `lesson`, `snippet`, or generic `extract` based on content patterns. The daemon runs a signal filter that keeps decisions, bugfixes, lessons, and code rationale while skipping noise (tool calls, file listings, boilerplate).
141
+
142
+ ---
143
+
144
+ ## Dashboard
145
+
146
+ ```bash
147
+ memor dashboard
148
+ ```
149
+
150
+ Shows:
151
+ - **Memory bank** — session chunks, distilled memories, projects tracked
152
+ - **Context efficiency** — overhead %, recall precision, quality scores per session
153
+ - **Per-project breakdown** — which projects have the most context
154
+ - **Recent recalls** — every hook event with scores, latency, and status
155
+
156
+ ---
157
+
158
+ ## Commands
159
+
160
+ ```
161
+ memor help Print the full manual
162
+ memor install-hook Install Claude Code hook + download model
163
+ memor daemon Auto-ingest + distill (background watcher)
164
+ memor dashboard Web dashboard on localhost:8420
165
+ memor query <text> Search memories from the CLI
166
+ memor reingest Wipe DB and re-ingest everything
167
+ memor reingest --project <name> Re-ingest only one project
168
+ memor forget-stale Deactivate memories unused for 30+ days
169
+ memor scan Audit DB for leaked secrets
170
+ memor scan --purge Redact secrets in place
171
+ memor setup-model Download/retry the embedding model
172
+ memor ingest-cc <file> Ingest a single transcript
173
+ memor ingest-project <dir> Bulk ingest a project directory
174
+ memor ingest-doc <file> Ingest a markdown document
175
+ memor distill --project <name> Run distillation manually
176
+ memor eval <cases.json> Run eval suite
177
+ memor bench-embed --project <name> Compare embedding models
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Architecture
183
+
184
+ ```
185
+ memor/
186
+ +-- types.py Core dataclasses: Artifact, Scope, Hit, RetrievalTrace
187
+ +-- interfaces.py Protocols: Embedder, LLM, MemoryStore
188
+ +-- cli.py Typer CLI entry point
189
+ +-- daemon.py Auto-ingest + auto-distill + compaction watcher
190
+ +-- project.py Git-root project resolver (filesystem-aware)
191
+ +-- recall.py Shared recall core (used by hook + skill)
192
+ +-- redact.py Secret detection and redaction at ingest
193
+ +-- feedback.py Implicit feedback analyzer (usage detection)
194
+ |
195
+ +-- retrieve/
196
+ | +-- retriever.py Hybrid scoring: similarity + recency + kind + quality
197
+ |
198
+ +-- store/
199
+ | +-- sqlite_store.py SQLite + sqlite-vec (WAL mode, dimension safety)
200
+ |
201
+ +-- embed/
202
+ | +-- local.py model2vec (potion-base-8M, 256-dim, ~60MB)
203
+ | +-- api.py OpenAI-compatible embedding API (optional)
204
+ | +-- fake.py Deterministic SHA-256 embedder (tests)
205
+ |
206
+ +-- dashboard/
207
+ | +-- server.py FastAPI dashboard backend
208
+ | +-- static/index.html Self-contained dashboard (no CDN deps)
209
+ |
210
+ +-- distill/
211
+ | +-- extractive.py TF-IDF + clustering + auto-classification
212
+ | +-- distiller.py Extractive + optional LLM abstractive
213
+ |
214
+ +-- eval/
215
+ +-- runner.py 4-baseline eval runner
216
+ +-- judge.py LLM-as-judge evaluation
217
+ +-- embed_benchmark.py Embedding model comparison
218
+
219
+ bin/memor-hook.py Claude Code hook (thin client)
220
+ skill/recall.py Standalone recall script
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Security
226
+
227
+ **Nothing leaves your machine.** In the default configuration:
228
+
229
+ - **No telemetry, no analytics, no phone-home.** Zero outbound network calls.
230
+ - **Embeddings run locally** via model2vec ONNX (one-time model download from HuggingFace — no user data sent).
231
+ - **Hook transport is a Unix socket** (`~/.memor/hook.sock`), not a network port.
232
+ - **Dashboard binds localhost only.**
233
+
234
+ The only optional network paths are the LLM-based abstractive distiller (requires explicitly setting `ANTHROPIC_API_KEY`) and the API embedding backend — both off by default.
235
+
236
+ ### Secret redaction
237
+
238
+ Memor automatically redacts secrets **at ingest**, before anything is embedded or stored:
239
+
240
+ - API keys (AWS `AKIA...`, OpenAI `sk-...`, Anthropic `sk-ant-...`, GitHub `ghp_...`, Stripe, Slack)
241
+ - JWTs, PEM private key blocks
242
+ - Connection strings (`postgres://`, `mongodb://`, `redis://`, etc.)
243
+ - `.env`-style assignments (`DB_PASSWORD=...`, `API_KEY=...`)
244
+ - High-entropy tokens (Shannon entropy > 4.0, length > 20)
245
+
246
+ Redacted content is replaced with `[REDACTED]` in place, preserving surrounding context. To audit and clean an existing database: `memor scan` (audit) or `memor scan --purge` (redact in place).
247
+
248
+ ### Contradiction handling
249
+
250
+ When a new memory contradicts an older one in the same project (detected via replacement cues like "switched from X to Y", "no longer", "ripped out"), the older memory is automatically deactivated. This prevents stale decisions from being recalled and misleading the agent.
251
+
252
+ ### Local storage
253
+
254
+ The memory database (`~/.memor/memor.db`) is stored as plaintext SQLite on disk. For at-rest protection, we recommend enabling OS-level full-disk encryption (FileVault on macOS, LUKS on Linux) which covers all local files with zero performance overhead.
255
+
256
+ ---
257
+
258
+ ## Development
259
+
260
+ ```bash
261
+ git clone https://github.com/bnimit/memor-ai.git
262
+ cd memor-ai
263
+ python3 -m venv .venv && source .venv/bin/activate
264
+ pip install -e ".[dev]"
265
+
266
+ pytest # 153 tests
267
+ ```
268
+
269
+ ---
270
+
271
+ ## License
272
+
273
+ MIT. See [LICENSE](LICENSE) for the full text.
@@ -0,0 +1,48 @@
1
+ memor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ memor/cli.py,sha256=AxH5gqaITemV6GPyYoL1Xu1gjHDeYUsp1Kv28phxQOw,20791
3
+ memor/daemon.py,sha256=6F4P029KsFElCjfAxRZm2G6XTLhZK05TNVdzPWeR_5c,10973
4
+ memor/feedback.py,sha256=G-2_tYCzB2VfT-qp9BQ2V-HAl3UvMTel-Ma8Y_rH0Fg,2967
5
+ memor/hook_server.py,sha256=EPTkM3o1RalLI0W00EbO_4oUW-GgfXT72H7y5pNYbqE,4240
6
+ memor/interfaces.py,sha256=uSOTb9Fvt5yNZAcMUGIVMBJxubugfgsrjC7OzZNCffQ,852
7
+ memor/project.py,sha256=htrvGTXdENhesba9RCtOh0t6oTNJ0nxm9YbqYiQpWH0,2306
8
+ memor/recall.py,sha256=VaxAMV86FJOwHqNTFtSvHnEVoxCC4RsTomUFZAuAHR0,4135
9
+ memor/redact.py,sha256=nvvnlQM0cKN0vgE_TcI5GXvUJ1izQ6AaBCnYbavR_EI,4627
10
+ memor/tokencount.py,sha256=7FYnKVRgxqIW2tuMT9GGXHatwMno_GSmAID0p9mwO6w,201
11
+ memor/types.py,sha256=7ppuVEcmdhZWN9eHok67rZ0TbzjWvesbCKduVMga_Jc,1196
12
+ memor/dashboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ memor/dashboard/server.py,sha256=eye70M3PVTiY7dz5UICspvce8hk1KJkbQ6bHx9jEGGw,5535
14
+ memor/dashboard/static/index.html,sha256=M-ae6ardwWGWKL0F89GJ5VcNBhXE70oZiWlY4mpgYXc,29746
15
+ memor/distill/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ memor/distill/distiller.py,sha256=e9PXK_cOpdkpOLKw7kz0Q7RHZgmOIUEPz8-Muhyr1SU,4777
17
+ memor/distill/extractive.py,sha256=juVl2MMJbcJzN7UnNr6Qoz2BJbIs4_XSGM1fJZ8-pZI,5820
18
+ memor/embed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ memor/embed/api.py,sha256=d5PAZWiMXfZ4fQQyAxDPBKDjCwQnd3_wh4vdMfK6kEA,697
20
+ memor/embed/fake.py,sha256=EN983eSd3b4ex3uQOEtZGtUzbHq2xJ5XiE3npnfR2Aw,593
21
+ memor/embed/local.py,sha256=Wvg8ZztYtcsJuhWE7gEzMQ83Zn1ENAsECWAhqTBpG9E,576
22
+ memor/eval/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ memor/eval/dataset.py,sha256=UObFvpMzEXIAWSm6bPMWjmnohCNx73DaTahobtBMTHc,1780
24
+ memor/eval/embed_benchmark.py,sha256=f4zyEIGbeN3n0SgRvhz-cCVPUXRoqbdu2j3ikplPPKA,2067
25
+ memor/eval/judge.py,sha256=HINbBi62VMbyLdM6X6JnQj5hbjNyP4_MFZZEo0KGQag,4426
26
+ memor/eval/metrics.py,sha256=Gew3ktiHurOpqhYBIf83itxgHqJJjCQsRrVcg4hOUJ8,504
27
+ memor/eval/runner.py,sha256=TxzcZChVF91wUQsHxrTpLBQuWRNhfVLdxWwExD46bwA,3715
28
+ memor/eval/baselines/__init__.py,sha256=p0fZs6PZPiTBdE4bbQj5M0maByG0Id5BcDrbjRN9Nqo,249
29
+ memor/eval/baselines/base.py,sha256=ZoUwThGGGkjenAarjjb2crN2C2Zbx--fwR4h9ctbcnQ,378
30
+ memor/eval/baselines/claude_mem.py,sha256=JyhtlQ-ZrXYlW8kcJloXTz3ztkkcQwkm5aE__4EEJwM,711
31
+ memor/eval/baselines/graphiti.py,sha256=TjzSDfW-_VN8CnsVG54mOa7eCwsWESONZ5_LEAv1wgY,855
32
+ memor/ingest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ memor/ingest/claude_code.py,sha256=qumtU0iX8yL9oRigTdap_P91NsgcHEsVBszpDzfObM8,4731
34
+ memor/ingest/documents.py,sha256=043qvK7bCdkPlbLE8WBDPzB0W35IpDw_dfc3Am0ykPo,1068
35
+ memor/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ memor/llm/anthropic.py,sha256=CXAXN0rH9_UmLjldFSQP48SPVTTHv2koSah9P9a_gI8,538
37
+ memor/llm/base.py,sha256=ha_eJL7eOB_DMbFWGBg_98HAA7VnxLtOP4XizSUwSIA,332
38
+ memor/llm/openai_compat.py,sha256=NfMXlux4W9Yp9P_csbUbjf1ozR7mYcCMypoxOWy55TI,691
39
+ memor/retrieve/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ memor/retrieve/retriever.py,sha256=ZIQVI5mcaxCQptVpa_3ESIa8cFnsqHUjrciPNxPusBw,3055
41
+ memor/store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ memor/store/sqlite_store.py,sha256=p6AsKe3srIxJyshw5zpN_NHJCDHE8rR_eaYVN_pDnIk,15315
43
+ memor_cli-0.1.0.dist-info/licenses/LICENSE,sha256=eTmbvFyA3bOOeZ9W8wr94kh8X8huYk5XzCAWqM0cOmk,1071
44
+ memor_cli-0.1.0.dist-info/METADATA,sha256=6XEZmHw8vWKY7avWG-HunKTcdg-MC0MWzeoAI5-tH5w,10475
45
+ memor_cli-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
46
+ memor_cli-0.1.0.dist-info/entry_points.txt,sha256=kvOBr1A5IIStOA3jVe-JYWZAzbNn2damfnxfeY6DVDs,40
47
+ memor_cli-0.1.0.dist-info/top_level.txt,sha256=XWNkuLOmIbKZzvUo36F2CF4U3OeM3LbenmhDvi1YpWw,6
48
+ memor_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ memor = memor.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nimit Bhandari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ memor