stashify 0.1.0__tar.gz

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 (44) hide show
  1. stashify-0.1.0/LICENSE +21 -0
  2. stashify-0.1.0/PKG-INFO +653 -0
  3. stashify-0.1.0/README.md +622 -0
  4. stashify-0.1.0/pyproject.toml +92 -0
  5. stashify-0.1.0/setup.cfg +4 -0
  6. stashify-0.1.0/src/stash/__init__.py +5 -0
  7. stashify-0.1.0/src/stash/cli/__init__.py +5 -0
  8. stashify-0.1.0/src/stash/cli/commands/__init__.py +23 -0
  9. stashify-0.1.0/src/stash/cli/commands/get.py +160 -0
  10. stashify-0.1.0/src/stash/cli/commands/info.py +45 -0
  11. stashify-0.1.0/src/stash/cli/commands/init.py +34 -0
  12. stashify-0.1.0/src/stash/cli/commands/ls.py +41 -0
  13. stashify-0.1.0/src/stash/cli/commands/provider.py +124 -0
  14. stashify-0.1.0/src/stash/cli/commands/put.py +185 -0
  15. stashify-0.1.0/src/stash/cli/commands/rm.py +82 -0
  16. stashify-0.1.0/src/stash/cli/commands/status.py +47 -0
  17. stashify-0.1.0/src/stash/cli/commands/verify.py +100 -0
  18. stashify-0.1.0/src/stash/cli/main.py +43 -0
  19. stashify-0.1.0/src/stash/cli/output.py +121 -0
  20. stashify-0.1.0/src/stash/core/__init__.py +53 -0
  21. stashify-0.1.0/src/stash/core/chunking.py +102 -0
  22. stashify-0.1.0/src/stash/core/crypto.py +121 -0
  23. stashify-0.1.0/src/stash/core/exceptions.py +66 -0
  24. stashify-0.1.0/src/stash/core/http_status.py +19 -0
  25. stashify-0.1.0/src/stash/core/jobs.py +235 -0
  26. stashify-0.1.0/src/stash/core/manifest.py +171 -0
  27. stashify-0.1.0/src/stash/core/metadata.py +130 -0
  28. stashify-0.1.0/src/stash/core/storage.py +120 -0
  29. stashify-0.1.0/src/stash/providers/__init__.py +15 -0
  30. stashify-0.1.0/src/stash/providers/base.py +48 -0
  31. stashify-0.1.0/src/stash/providers/discord/__init__.py +12 -0
  32. stashify-0.1.0/src/stash/providers/discord/auth.py +29 -0
  33. stashify-0.1.0/src/stash/providers/discord/limits.py +34 -0
  34. stashify-0.1.0/src/stash/providers/discord/provider.py +250 -0
  35. stashify-0.1.0/src/stash/providers/telegram/__init__.py +11 -0
  36. stashify-0.1.0/src/stash/providers/telegram/auth.py +15 -0
  37. stashify-0.1.0/src/stash/providers/telegram/limits.py +21 -0
  38. stashify-0.1.0/src/stash/providers/telegram/provider.py +286 -0
  39. stashify-0.1.0/src/stashify.egg-info/PKG-INFO +653 -0
  40. stashify-0.1.0/src/stashify.egg-info/SOURCES.txt +42 -0
  41. stashify-0.1.0/src/stashify.egg-info/dependency_links.txt +1 -0
  42. stashify-0.1.0/src/stashify.egg-info/entry_points.txt +2 -0
  43. stashify-0.1.0/src/stashify.egg-info/requires.txt +23 -0
  44. stashify-0.1.0/src/stashify.egg-info/top_level.txt +1 -0
stashify-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sparklee
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,653 @@
1
+ Metadata-Version: 2.4
2
+ Name: stashify
3
+ Version: 0.1.0
4
+ Summary: Privacy-focused CLI storage system using third-party platforms as encrypted backends
5
+ License: MIT
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: cryptography>=49.0
10
+ Requires-Dist: click>=8.1
11
+ Requires-Dist: pydantic>=2.7
12
+ Requires-Dist: pydantic-settings>=2.3
13
+ Requires-Dist: sqlite-utils>=3.37
14
+ Requires-Dist: tqdm>=4.70.0
15
+ Requires-Dist: structlog>=24.1
16
+ Requires-Dist: httpx>=0.27
17
+ Requires-Dist: pyyaml>=6.0
18
+ Requires-Dist: rich>=13.0
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=9.1.1; extra == "dev"
21
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
22
+ Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
23
+ Requires-Dist: ruff>=0.6; extra == "dev"
24
+ Requires-Dist: mypy>=2.3.1; extra == "dev"
25
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest>=9.1.1; extra == "test"
28
+ Requires-Dist: pytest-asyncio>=0.23; extra == "test"
29
+ Requires-Dist: hypothesis>=6.100; extra == "test"
30
+ Dynamic: license-file
31
+
32
+ # Stashify
33
+
34
+ <p align="center">
35
+ <strong>Encrypted storage. Your providers. Your keys.</strong>
36
+ </p>
37
+
38
+ <p align="center">
39
+ An open-source, privacy-focused storage system that turns third-party platforms into encrypted storage backends.
40
+ </p>
41
+
42
+ <p align="center">
43
+ <a href="https://github.com/Sparkleeop/Stashify">
44
+ <img src="https://img.shields.io/github/stars/Sparkleeop/Stashify?style=flat-square" alt="GitHub Stars">
45
+ </a>
46
+ <a href="https://github.com/Sparkleeop/Stashify">
47
+ <img src="https://img.shields.io/github/license/Sparkleeop/Stashify?style=flat-square" alt="License">
48
+ </a>
49
+ <img src="https://img.shields.io/badge/Python-3.12+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python">
50
+ <img src="https://img.shields.io/badge/Status-Early%20Development-ee8695?style=flat-square" alt="Status">
51
+ </p>
52
+
53
+ ---
54
+
55
+ ## What is Stashify?
56
+
57
+ **Stashify** is an open-source, provider-agnostic storage system designed around one simple idea:
58
+
59
+ > **Your storage provider shouldn't have to be your storage system.**
60
+
61
+ Stashify lets you use services such as **Telegram and Discord as storage backends**, while encryption and file management remain under your control.
62
+
63
+ Files are encrypted locally, split into chunks, and uploaded as ciphertext. Chunks can be stored on one provider or distributed across multiple providers depending on your configuration.
64
+
65
+ ```text
66
+ STASHIFY
67
+
68
+ Storage Engine
69
+
70
+ ┌─────────────┴─────────────┐
71
+ │ │
72
+ Encryption Chunking
73
+ │ │
74
+ └─────────────┬─────────────┘
75
+
76
+ Storage Router
77
+
78
+ ┌─────────────┴─────────────┐
79
+ │ │
80
+ Telegram Discord
81
+ │ │
82
+ encrypted chunks encrypted chunks
83
+ ```
84
+
85
+ Stashify does **not** provide the underlying storage.
86
+
87
+ It provides the abstraction that lets you use storage you already have access to.
88
+
89
+ ---
90
+
91
+ ## Why Stashify?
92
+
93
+ Traditional cloud storage usually means trusting one provider with both your data and your storage.
94
+
95
+ Stashify separates those concepts.
96
+
97
+ | Problem | Stashify |
98
+ | -------------------------- | ------------------------------------- |
99
+ | Vendor lock-in | Provider-agnostic storage abstraction |
100
+ | Provider sees plaintext | Files are encrypted before upload |
101
+ | Large files | Automatic chunking |
102
+ | Provider-specific limits | Provider-aware chunking and routing |
103
+ | Single provider dependency | Multi-provider storage |
104
+ | Interrupted uploads | Resumable operations |
105
+ | Manual file management | Unified CLI/TUI |
106
+ | Provider-specific APIs | One consistent interface |
107
+
108
+ ---
109
+
110
+ ## Features
111
+
112
+ ### Client-side encryption
113
+
114
+ Your files are encrypted **before they leave your device**.
115
+
116
+ ```text
117
+ YOUR DEVICE
118
+
119
+ Plaintext
120
+
121
+
122
+ Encryption
123
+
124
+
125
+ Chunking
126
+
127
+
128
+ Encrypted ciphertext
129
+
130
+ ┌──────────┴──────────┐
131
+ ▼ ▼
132
+ Telegram Discord
133
+ ```
134
+
135
+ Storage providers should only receive ciphertext.
136
+
137
+ Stashify is designed around:
138
+
139
+ * Client-side encryption
140
+ * Authenticated encryption (AEAD)
141
+ * Per-file cryptographic keys
142
+ * Proper key derivation
143
+ * Cryptographically secure randomness
144
+ * No custom cryptographic primitives
145
+ * Authenticated chunk integrity
146
+ * Local key management
147
+
148
+ Stashify uses established cryptographic libraries rather than implementing cryptography from scratch.
149
+
150
+ > **Security note:** Stashify does not claim that multi-provider storage makes encryption stronger. Confidentiality comes from the cryptographic design and key management. Multi-provider storage primarily provides distribution, redundancy, and provider independence.
151
+
152
+ ---
153
+
154
+ ### Chunked storage
155
+
156
+ Large files are automatically split into manageable chunks.
157
+
158
+ ```text
159
+ movie.mkv
160
+
161
+
162
+ encrypted data
163
+
164
+
165
+ ┌────────┬────────┬────────┬────────┐
166
+ │ chunk0 │ chunk1 │ chunk2 │ chunk3 │
167
+ └────────┴────────┴────────┴────────┘
168
+ │ │ │ │
169
+ ▼ ▼ ▼ ▼
170
+ encrypted encrypted encrypted encrypted
171
+ ```
172
+
173
+ Each chunk is independently tracked and authenticated.
174
+
175
+ The storage engine can account for provider-specific upload limitations without exposing those implementation details to the rest of the application.
176
+
177
+ ---
178
+
179
+ ### Multi-provider storage
180
+
181
+ Stashify can distribute a file across multiple storage providers.
182
+
183
+ For example:
184
+
185
+ ```text
186
+ 100 encrypted chunks
187
+
188
+ Telegram:
189
+ 0 2 4 6 8 10 12 ...
190
+
191
+ Discord:
192
+ 1 3 5 7 9 11 13 ...
193
+ ```
194
+
195
+ Multiple storage strategies are planned:
196
+
197
+ | Strategy | Description |
198
+ | -------------- | ----------------------------------------------------- |
199
+ | **Single** | Store all chunks on one provider |
200
+ | **Split** | Distribute chunks across multiple providers |
201
+ | **Balanced** | Dynamically distribute chunks based on provider state |
202
+ | **Replicated** | Store copies across multiple providers |
203
+
204
+ This allows Stashify to build storage around the providers available to you instead of forcing you into a single backend.
205
+
206
+ ---
207
+
208
+ ### Provider abstraction
209
+
210
+ Providers are implementations of the same storage interface.
211
+
212
+ ```text
213
+ Storage Provider
214
+
215
+ ┌────────────────┼────────────────┐
216
+ │ │ │
217
+ Telegram Discord S3 / B2
218
+ │ │ │
219
+ └────────────────┼────────────────┘
220
+
221
+ Storage Engine
222
+ ```
223
+
224
+ The core engine does not need to know how Telegram or Discord works.
225
+
226
+ This makes it possible to add new providers without rewriting the storage system.
227
+
228
+ Planned providers include:
229
+
230
+ * S3-compatible storage
231
+ * Backblaze B2
232
+ * Google Drive
233
+ * Local filesystem
234
+ * WebDAV
235
+ * Other community-built providers
236
+
237
+ ---
238
+
239
+ ### Asynchronous transfers
240
+
241
+ Stashify is designed around asynchronous I/O.
242
+
243
+ Large uploads can consist of hundreds or thousands of chunks, so operations should run concurrently with bounded workers.
244
+
245
+ ```text
246
+ Upload Queue
247
+
248
+ ┌───────────┼───────────┐
249
+ ▼ ▼ ▼
250
+ Worker 1 Worker 2 Worker 3
251
+ │ │ │
252
+ Telegram Discord Telegram
253
+ ```
254
+
255
+ The transfer system is designed to support:
256
+
257
+ * Concurrent uploads
258
+ * Concurrent downloads
259
+ * Bounded concurrency
260
+ * Retries
261
+ * Exponential backoff
262
+ * Provider-aware rate limiting
263
+ * Cancellation
264
+ * Progress reporting
265
+ * Failed-job tracking
266
+ * Resumable operations
267
+
268
+ ---
269
+
270
+ ### Resumable uploads
271
+
272
+ Interrupted transfers shouldn't mean starting from zero.
273
+
274
+ ```text
275
+ 200 chunks
276
+
277
+ chunk 000 ✓
278
+ chunk 001 ✓
279
+ chunk 002 ✓
280
+ ...
281
+ chunk 147 ✓
282
+ chunk 148 ✗
283
+ chunk 149 ✗
284
+ ...
285
+ ```
286
+
287
+ Stashify keeps track of individual chunks so completed work can be preserved across interruptions.
288
+
289
+ ---
290
+
291
+ ### Integrity verification
292
+
293
+ Encrypted chunks are authenticated and tracked using local metadata.
294
+
295
+ Stashify is designed to detect:
296
+
297
+ * Missing chunks
298
+ * Corrupted chunks
299
+ * Modified ciphertext
300
+ * Incomplete downloads
301
+ * Invalid manifests
302
+ * Incorrect chunk ordering
303
+ * Failed reconstruction
304
+
305
+ The final reconstructed file can also be verified against file-level integrity information.
306
+
307
+ ---
308
+
309
+ ### Manifest-based storage
310
+
311
+ Every stored file has a manifest describing how it can be reconstructed.
312
+
313
+ Conceptually:
314
+
315
+ ```text
316
+ File
317
+ ├── ID
318
+ ├── Original name
319
+ ├── Original size
320
+ ├── Chunk size
321
+ ├── Chunk count
322
+ ├── Encryption metadata
323
+ ├── Integrity information
324
+
325
+ └── Chunks
326
+ ├── 0 → Telegram → remote ID
327
+ ├── 1 → Discord → remote ID
328
+ ├── 2 → Telegram → remote ID
329
+ └── ...
330
+ ```
331
+
332
+ Local metadata is stored in SQLite.
333
+
334
+ ---
335
+
336
+ # Terminal UI (planned)
337
+
338
+ Stashify is designed to have a full interactive terminal interface rather than being limited to traditional commands.
339
+
340
+ Run:
341
+
342
+ ```bash
343
+ stashify
344
+ ```
345
+
346
+ to launch the TUI.
347
+
348
+ The interface is designed around a keyboard-first workflow with:
349
+
350
+ * Local file explorer
351
+ * Remote storage explorer
352
+ * Multi-file selection
353
+ * Upload/download controls
354
+ * Live transfer progress
355
+ * Provider status
356
+ * Transfer queue
357
+ * Provider management
358
+ * Configuration
359
+ * Search
360
+ * Command palette
361
+ * Keyboard shortcuts
362
+
363
+ ---
364
+
365
+ # CLI
366
+
367
+ Stashify can also be used without the interactive interface.
368
+
369
+ ```bash
370
+ # Initialize
371
+ stashify init
372
+
373
+ # Configure providers
374
+ stashify provider add telegram
375
+ stashify provider add discord
376
+
377
+ # List providers
378
+ stashify provider list
379
+
380
+ # Upload
381
+ stashify put ./movie.mkv
382
+
383
+ # List stored files
384
+ stashify ls
385
+
386
+ # Inspect a file
387
+ stashify info movie.mkv
388
+
389
+ # Download
390
+ stashify get movie.mkv
391
+
392
+ # Delete
393
+ stashify rm movie.mkv
394
+
395
+ # Verify
396
+ stashify verify movie.mkv
397
+
398
+ # Check status
399
+ stashify status
400
+ ```
401
+
402
+ The exact command set may evolve during development.
403
+
404
+ ---
405
+
406
+ # Provider Support
407
+
408
+ | Provider | Status |
409
+ | ---------------- | -------------- |
410
+ | Telegram | Implemented |
411
+ | Discord | Implemented |
412
+ | S3-compatible | Planned |
413
+ | Backblaze B2 | Planned |
414
+ | Google Drive | Planned |
415
+ | Local filesystem | Planned |
416
+ | WebDAV | Planned |
417
+
418
+ Provider availability and capabilities are subject to the APIs, limits, and policies of the respective services.
419
+
420
+ ### About "unlimited storage"
421
+
422
+ Stashify does **not** provide unlimited storage.
423
+
424
+ It does not bypass provider limits or guarantee unlimited capacity.
425
+
426
+ Actual storage capacity, file-size limits, rate limits, retention policies, and availability depend on the underlying provider.
427
+
428
+ Stashify's job is to abstract those providers and make the best use of the storage available to the user.
429
+
430
+ ---
431
+
432
+ # Security & Privacy
433
+
434
+ Stashify is designed around a simple trust model:
435
+
436
+ ```text
437
+ Trusted
438
+
439
+
440
+ ┌───────────┐
441
+ │ User Device│
442
+ └─────┬─────┘
443
+
444
+ encrypted data
445
+
446
+ ┌───────┴───────┐
447
+ ▼ ▼
448
+ Telegram Discord
449
+ untrusted untrusted
450
+ storage storage
451
+ ```
452
+
453
+ ### Principles
454
+
455
+ **Local-first encryption**
456
+
457
+ Plaintext files are processed locally before being uploaded.
458
+
459
+ **Untrusted providers**
460
+
461
+ Storage providers are treated as storage infrastructure, not trusted holders of plaintext data.
462
+
463
+ **No custom cryptography**
464
+
465
+ Stashify uses established cryptographic implementations.
466
+
467
+ **Authenticated data**
468
+
469
+ Encrypted chunks should provide confidentiality and integrity.
470
+
471
+ **Minimal exposure**
472
+
473
+ Provider APIs should receive only the information required to store and retrieve encrypted data.
474
+
475
+ **Open source**
476
+
477
+ The codebase is intended to remain publicly auditable.
478
+
479
+ > Stashify is early-stage software. Do not rely on it for critical backups until the security model, implementation, and recovery mechanisms have been thoroughly reviewed.
480
+
481
+ ---
482
+
483
+ # Architecture
484
+
485
+ At a high level:
486
+
487
+ ```text
488
+ ┌───────▼───────┐
489
+ │ CLI │
490
+ └───────┬───────┘
491
+
492
+ ┌───────▼───────┐
493
+ │ Core Engine │
494
+ └───────┬───────┘
495
+
496
+ ┌──────────────────┼──────────────────┐
497
+ │ │ │
498
+ ▼ ▼ ▼
499
+ Encryption Chunking Metadata
500
+ │ │ │
501
+ └──────────────────┼──────────────────┘
502
+
503
+ ┌───────▼───────┐
504
+ │ Storage Router│
505
+ └───────┬───────┘
506
+
507
+ ┌────────────┼────────────┐
508
+ ▼ ▼ ▼
509
+ Telegram Discord Future
510
+ Providers
511
+ ```
512
+
513
+ The architecture intentionally separates:
514
+
515
+ * User interface
516
+ * Core storage logic
517
+ * Cryptography
518
+ * Chunking
519
+ * Metadata
520
+ * Job execution
521
+ * Provider implementations
522
+
523
+ This allows the system to evolve without coupling the entire codebase to a specific provider.
524
+
525
+ ---
526
+
527
+ # Project Status
528
+
529
+ > **Stashify is currently in early development.**
530
+
531
+ The architecture is being actively developed and APIs may change significantly.
532
+
533
+ | Component | Status |
534
+ | ---------------------- | ----------- |
535
+ | Project architecture | In progress |
536
+ | Python CLI | In progress |
537
+ | Encryption | Implemented |
538
+ | Chunking | Implemented |
539
+ | Manifest / metadata | Implemented |
540
+ | Provider abstraction | In progress |
541
+ | Telegram provider | Implemented |
542
+ | Discord provider | Implemented |
543
+ | Async job engine | Implemented |
544
+ | Resumable transfers | Planned |
545
+ | Multi-provider routing | Planned |
546
+ | Verification | Planned |
547
+ | Repair / recovery | Future |
548
+ | Additional providers | Future |
549
+
550
+ Features marked **Planned** or **Future** should not be considered implemented.
551
+
552
+ ---
553
+
554
+ # Development
555
+
556
+ Stashify is built with Python and is designed around asynchronous I/O.
557
+
558
+ The project aims to keep the core storage engine independent from its user interfaces and provider implementations.
559
+
560
+ A typical architecture is:
561
+
562
+ ```text
563
+ UI
564
+
565
+ └── CLI
566
+
567
+
568
+ Core Storage Engine
569
+
570
+ ├── Crypto
571
+ ├── Chunking
572
+ ├── Metadata
573
+ ├── Jobs
574
+ └── Storage Router
575
+
576
+ ├── Telegram
577
+ ├── Discord
578
+ └── Future Providers
579
+ ```
580
+
581
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
582
+
583
+ ---
584
+
585
+ # Contributing
586
+
587
+ Contributions are welcome.
588
+
589
+ Some areas where contributions will be especially useful:
590
+
591
+ * Storage providers
592
+ * Encryption and security review
593
+ * Chunking and transfer reliability
594
+ * TUI/UX improvements
595
+ * Testing
596
+ * Documentation
597
+ * Performance
598
+ * Cross-platform support
599
+
600
+ Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
601
+
602
+ If you discover a potential security vulnerability, please follow the project's security reporting process rather than publicly disclosing the issue immediately.
603
+
604
+ ---
605
+
606
+ # Roadmap
607
+
608
+ The long-term goal is to turn Stashify into a flexible encrypted storage layer that can sit on top of almost any suitable storage provider.
609
+
610
+ ### Near term
611
+
612
+ * [x] Core encryption pipeline
613
+ * [x] Chunking
614
+ * [ ] SQLite metadata
615
+ * [x] Telegram provider
616
+ * [x] Discord provider
617
+ * [x] Async transfer system
618
+ * [ ] Resumable uploads
619
+
620
+ ### Medium term
621
+
622
+ * [ ] Multi-provider routing
623
+ * [ ] Replication
624
+ * [ ] Integrity verification
625
+ * [ ] Recovery/repair
626
+ * [ ] Provider health monitoring
627
+
628
+ ### Long term
629
+
630
+ * [ ] S3-compatible providers
631
+ * [ ] Backblaze B2
632
+ * [ ] Google Drive
633
+ * [ ] WebDAV
634
+ * [ ] Local filesystem backend
635
+ * [ ] Additional community providers
636
+ * [ ] Advanced redundancy strategies
637
+
638
+ The roadmap is intentionally flexible and will evolve as the project matures.
639
+
640
+ ---
641
+
642
+ # License
643
+
644
+ Stashify is released under the **MIT License**.
645
+
646
+ See [LICENSE](LICENSE) for the full license text.
647
+
648
+ ---
649
+
650
+ <p align="center">
651
+ <strong>Stashify</strong><br>
652
+ <sub>Your files. Your keys. Your storage.</sub>
653
+ </p>