@nightowne/tas-cli 2.4.0 → 3.0.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/README.md CHANGED
@@ -1,232 +1,327 @@
1
1
  <p align="center">
2
- <img src="assets/demo.gif" alt="TAS — Telegram as Storage" width="640">
2
+ <img src="assets/demo.gif" alt="TAS — Telegram as Storage CLI demo" width="680">
3
3
  </p>
4
4
 
5
- <h1 align="center">
6
- 📦 TAS — Telegram as Storage
7
- </h1>
5
+ <h1 align="center">📦 TAS</h1>
8
6
 
9
7
  <h3 align="center">
10
- Turn Telegram into your personal encrypted cloud drive.<br>
11
- Free forever. Zero-knowledge. No credit card. No limits.
8
+ Encrypted file transport for data you already keep backed up.<br>
9
+ <strong>Local index. Verifiable restores. Explicit provider risk.</strong>
12
10
  </h3>
13
11
 
14
12
  <p align="center">
15
- <a href="https://github.com/ixchio/tas/actions/workflows/ci.yml"><img src="https://github.com/ixchio/tas/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
16
- <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/v/@nightowne/tas-cli?color=cb3837&label=npm" alt="npm version"></a>
17
- <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/dm/@nightowne/tas-cli?color=blue" alt="Downloads"></a>
18
- <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"></a>
13
+ <a href="https://github.com/ixchio/tas/actions/workflows/ci.yml"><img src="https://github.com/ixchio/tas/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
14
+ <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/v/@nightowne/tas-cli?color=cb3837&label=npm&logo=npm" alt="npm version"></a>
15
+ <a href="https://www.npmjs.com/package/@nightowne/tas-cli"><img src="https://img.shields.io/npm/dm/@nightowne/tas-cli?color=blue&label=downloads&logo=npm" alt="Monthly Downloads"></a>
16
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg" alt="License: MIT"></a>
19
17
  <a href="https://github.com/ixchio/tas/stargazers"><img src="https://img.shields.io/github/stars/ixchio/tas?style=social" alt="GitHub Stars"></a>
18
+ <a href="https://github.com/ixchio/tas/network/members"><img src="https://img.shields.io/github/forks/ixchio/tas?style=social" alt="GitHub Forks"></a>
19
+ <img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen?logo=node.js" alt="Node.js >= 18">
20
+ <img src="https://img.shields.io/badge/encryption-AES--256--GCM-blueviolet?logo=shield" alt="AES-256-GCM">
21
+ <img src="https://img.shields.io/badge/tests-97%20passing-success" alt="97 Tests Passing">
20
22
  </p>
21
23
 
22
24
  <p align="center">
23
- <a href="#-quick-start">Quick Start</a> •
24
- <a href="#-why-tas">Why TAS</a> •
25
- <a href="#-features">Features</a> •
26
- <a href="#%EF%B8%8F-security">Security</a> •
27
- <a href="#-cli-reference">Docs</a> •
28
- <a href="#-contributing">Contributing</a>
25
+ <a href="QUICKSTART.md"><strong>📚 Quick Start</strong></a> &nbsp;•&nbsp;
26
+ <a href="FAQ.md">FAQ</a> &nbsp;•&nbsp;
27
+ <a href="#why-tas">Why TAS?</a> &nbsp;•&nbsp;
28
+ <a href="#-features">Features</a> &nbsp;•&nbsp;
29
+ <a href="#-security-model">Security</a> &nbsp;•&nbsp;
30
+ <a href="#-cli-reference">CLI Docs</a> &nbsp;•&nbsp;
31
+ <a href="#-docker--cicd">Docker / CI</a> &nbsp;•&nbsp;
32
+ <a href="CHANGELOG.md">Changelog</a>
29
33
  </p>
30
34
 
31
35
  ---
32
36
 
33
- <br>
37
+ > **TAS 3.0** — One `npm install`, one `tas init`, then `tas push yourfile.pdf`. TAS encrypts content locally and sends round-trip-safe chunks through the Bot API. It is experimental transport, not a durable backup service: Telegram can limit, remove, or terminate access. Keep an independent backup.
34
38
 
35
- ## The Problem
39
+ ---
40
+
41
+ ## What TAS Is
42
+
43
+ TAS is a local-first CLI for moving encrypted file blobs through your own Telegram bots. Its SQLite index lives on your machine; content is encrypted before upload; completed mutations publish an encrypted recovery manifest you can use to rebuild the index.
36
44
 
37
- Google Drive scans your files. Dropbox costs $12/mo. iCloud locks you into Apple. Every "free" cloud storage either **reads your data**, **charges you money**, or **caps your storage**.
45
+ > **Operating boundary.** TAS is not unlimited storage, a backup guarantee, or a Telegram-supported cloud drive. Telegram provides no TAS quota, retention SLA, recovery service, or account guarantee. Its [Bot Developer Terms](https://telegram.org/tos/bot-developers) also restrict external apps that diverge into cloud-storage use cases. Use TAS only for data that already has an independent backup.
38
46
 
39
- Meanwhile, Telegram gives every user **unlimited storage** with a bot API — and nobody's using it.
47
+ ---
40
48
 
41
- ## The Solution
49
+ ## How It Works
42
50
 
43
- **TAS** compresses, encrypts, and uploads your files to your own private Telegram bot chat. Your password never leaves your machine. Telegram only sees encrypted noise. You get a real CLI-powered cloud drive — with mount, sync, share, and search — for **$0/month, forever.**
51
+ **TAS** compresses, encrypts (AES-256-GCM), chunks, and uploads files to private bot chats. Your password stays local. Content, filenames, original sizes, and the recovery manifest are encrypted or omitted from Telegram-visible chunk metadata. Telegram still sees bot/chat identity, timing, chunk count, and encrypted sizes.
44
52
 
45
53
  ```
46
- Your Machine Telegram Cloud
47
- ┌──────────────────┐ ┌──────────────────────┐
48
- │ │ Compress │ │
49
- │ tas push │──→ Encrypt ──→│ 🔒 Encrypted Blobs │
50
- │ tas mount │──→ Chunk ──→│ 🔒 Private Bot Chat │
51
- │ tas sync │ │ 🔒 Your Data, Safe │
52
- │ │ Decrypt │ │
53
- │ tas pull │←── Decomp ←──│ ← Download on demand│
54
- │ │ │ │
55
- └──────────────────┘ └──────────────────────┘
56
- SQLite Index Unlimited & Free
54
+ Your Machine Telegram Cloud
55
+ ┌─────────────────────────────┐ ┌──────────────────────────┐
56
+ │ │ │ │
57
+ │ tas push secret.tar.gz │──→ gzip ──→ │ 🔒 Encrypted Blob #1 │
58
+ │ tas mount ~/cloud │──→ AES-256 ──→│ 🔒 Encrypted Blob #2 │
59
+ │ tas sync start │──→ chunk ──→ │ 🔒 Encrypted Blob #3 │
60
+ │ │ │ (Private Bot Chat) │
61
+ │ tas pull secret.tar.gz │←── decrypt ←──│ │
62
+ │ (SHA-256 verified) │←── decomp ←──│ ← Stream on demand │
63
+ │ │ │ │
64
+ └─────────────────────────────┘ └──────────────────────────┘
65
+ SQLite Index Remote Bot Messages
57
66
  ```
58
67
 
59
- <br>
68
+ ---
60
69
 
61
70
  ## ⚡ Quick Start
62
71
 
63
- Three commands. Two minutes. Zero cost.
72
+ **Three commands to try it. Keep another copy of every file.**
64
73
 
65
74
  ```bash
75
+ # 1. Install globally
66
76
  npm install -g @nightowne/tas-cli
67
77
 
68
- tas init # Connect your Telegram bot (guided wizard)
69
- tas push secret.pdf # Upload — encrypted, compressed, done
70
- tas pull secret.pdf # Download — decrypted, verified, instant
78
+ # 2. Connect your Telegram bot (guided wizard — takes ~60 seconds)
79
+ tas init
80
+
81
+ # 3. Start using it
82
+ tas push secret.pdf # Encrypt + compress + upload
83
+ tas pull secret.pdf # Download + decrypt + verify
84
+ tas list # See everything you've stored
71
85
  ```
72
86
 
73
- That's it. You now have encrypted cloud storage.
87
+ > **Need a Telegram bot?** Open Telegram → search `@BotFather` → `/newbot` → copy the token. That's it.
74
88
 
75
- <br>
89
+ ---
76
90
 
77
- ## 💡 Why TAS
91
+ ## Why TAS?
78
92
 
79
- <table>
80
- <tr>
81
- <td width="50%">
93
+ TAS is for people who want a small, inspectable command-line transport rather than another account, dashboard, or opaque sync daemon. It makes the important state visible and keeps the recovery path in your hands.
82
94
 
83
- ### vs. Google Drive
84
- - ❌ Google scans & indexes your files
85
- - ❌ 15 GB free tier
86
- - ❌ No encryption at rest (by you)
95
+ - **A local source of truth.** The index is SQLite, paths are exact, and nested directories behave consistently in sync and FUSE.
96
+ - **A recovery story.** TAS writes an authenticated, encrypted remote manifest after completed changes; `tas index rebuild` can restore the file-to-message map when the local index is gone.
97
+ - **A clean automation surface.** Push, pull, search, tags, sync, and JSON output work from a shell, cron job, or CI runner.
98
+ - **Deliberate multi-bot routing.** Each chunk records its owner, so a pool is inspectable and reversible instead of a hidden round-robin trick.
99
+ - **No false promise.** The product is precise about the provider boundary: Telegram is not your storage vendor, and multi-bot mode is not a way around its rules.
87
100
 
88
- ### vs. Dropbox
89
- - ❌ $12/mo for 2 TB
90
- - ❌ Can access your data
91
- - ❌ No CLI-first experience
101
+ ---
92
102
 
93
- ### vs. Mega / pCloud
94
- - ❌ Freemium with tight caps
95
- - ❌ Closed source encryption
96
- - ❌ Can't self-host or script
103
+ ## 🔥 Features
97
104
 
98
- </td>
99
- <td width="50%">
105
+ ### 🗂️ Mount as a Local Folder (FUSE)
100
106
 
101
- ### TAS gives you
102
- - ✅ **$0/month** — forever, no caps
103
- - ✅ **Zero-knowledge** — only you can decrypt
104
- - ✅ **AES-256-GCM** — military-grade encryption
105
- - ✅ **Mount as folder** — FUSE filesystem
106
- - ✅ **Auto-sync** — Dropbox-style folder sync
107
- - ✅ **Share links** — expiring, download-limited
108
- - ✅ **CLI-first** — cron, Docker, CI/CD ready
109
- - ✅ **Open source** — audit every line
107
+ Use Telegram storage exactly like a USB drive — drag and drop, open in any app.
110
108
 
111
- </td>
112
- </tr>
113
- </table>
109
+ ```bash
110
+ tas mount ~/cloud # Mount your Telegram storage as ~/cloud
111
+ ls ~/cloud # Browse your encrypted files normally
112
+ cp report.pdf ~/cloud/ # Drop files in — auto-encrypted and uploaded
113
+ tas unmount ~/cloud # Clean unmount when done
114
+ ```
114
115
 
115
- <br>
116
+ > **Linux only for this release:** install `fuse`/`libfuse-dev`, then run `tas doctor` for a real mount → readdir → unmount smoke test. macOS mount is explicitly unsupported because `fuse-native@2.x` targets obsolete OSXFUSE APIs and is not validated with current macFUSE or Apple Silicon. Push, pull, sync, and share still work on macOS.
116
117
 
117
- ## 🔥 Features
118
+ ---
119
+
120
+ ### 🔄 Auto-Sync Folders (Dropbox-style)
121
+
122
+ Register a local folder and TAS watches it. Any new or changed file is automatically encrypted and uploaded.
123
+
124
+ ```bash
125
+ tas sync add ~/Documents # Register ~/Documents for auto-sync
126
+ tas sync start # Start the watcher (runs in background)
127
+ tas sync pull # Pull all synced files back down
128
+ tas sync status # See what's queued / synced / pending
129
+ ```
130
+
131
+ ---
132
+
133
+ ### 🤖 Experimental Multi-Bot Pool
118
134
 
119
- ### 🗂️ Mount as a Local Folder
120
- Drag and drop files into Telegram storage like it's a regular drive.
135
+ TAS can distribute new chunks deterministically across multiple bots and records the owning bot on every chunk. Disabled bots remain configured for reads; a bot cannot be removed while indexed chunks or the recovery manifest depend on it.
121
136
 
122
137
  ```bash
123
- tas mount ~/cloud # Mount your Telegram storage
124
- # Now use Finder, Explorer, or any app — files sync to Telegram
125
- tas unmount ~/cloud
138
+ tas bot add --name archive-2 # Interactive token/chat setup + risk acknowledgement
139
+ tas bot list # IDs, state, chat, and dependent chunk counts
140
+ tas bot disable archive-2 # Stop new writes; old chunks remain readable
141
+ tas bot enable archive-2
142
+ tas bot remove archive-2 # Refuses unless no data depends on it
126
143
  ```
127
144
 
128
- > Requires `libfuse` — `apt install fuse libfuse-dev` on Linux, `brew install macfuse` on macOS.
145
+ > **Use at your own risk.** Multiple bots do not guarantee more quota, durability, ban avoidance, or Terms compliance. Do not use this feature to evade Telegram limits. All bots remain under Telegram's control, so this is distribution—not redundancy.
129
146
 
130
- ### 🔄 Auto-Sync Folders
131
- Dropbox-style: register a folder, and TAS watches for changes and uploads automatically.
147
+ ### 🧯 Index Recovery
148
+
149
+ Every completed storage mutation publishes a gzip-compressed, AES-256-GCM-authenticated manifest containing the file/chunk mapping and tags. Ephemeral share tokens are deliberately excluded. The latest pointer is stored in `config.json`.
132
150
 
133
151
  ```bash
134
- tas sync add ~/Documents # Register a folder
135
- tas sync start # Watch & auto-upload changes
136
- tas sync pull # Download everything back
137
- tas sync status # See what's synced
152
+ tas index backup # Publish a fresh encrypted recovery point
153
+ tas index rebuild # Authenticate and rebuild index.db
138
154
  ```
139
155
 
140
- ### 🔗 Share with Expiring Links
141
- Generate one-time download links with a sleek dark-themed download page. Files are decrypted on-the-fly — the link holder never sees your password.
156
+ Keep `config.json` and your password separately: recovery cannot discover the latest manifest if both the database and config are lost.
157
+
158
+ ---
159
+
160
+ ### 🔗 Expiring Share Links
161
+
162
+ Generate time-limited, download-limited share links. Recipients get a clean dark-themed download page. **Your password is never shared — files are decrypted on-the-fly by the local server.**
142
163
 
143
164
  ```bash
144
- tas share create report.pdf --expire 1h --max-downloads 3
145
- # → http://localhost:3000/d/a1b2c3d4...
165
+ tas share create report.pdf --expire 24h --max-downloads 5
166
+ # → http://localhost:3000/d/a1b2c3d4e5f6...
146
167
 
147
- tas share list # See active shares
148
- tas share revoke a1b2c3d4 # Revoke anytime
168
+ tas share create backup.tar.gz --expire 1h --max-downloads 1 # Burn-after-read
169
+ tas share list # See active links with expiry info
170
+ tas share revoke a1b2c3d4 # Revoke instantly, anytime
149
171
  ```
150
172
 
151
- ### 🏷️ Tags & Search
152
- Organize and find files instantly.
173
+ ---
174
+
175
+ ### 🏷️ Tags & Full-Text Search
153
176
 
154
177
  ```bash
155
- tas tag add report.pdf work Q4
156
- tas search "report" # Search by filename
157
- tas search -t work # Search by tag
178
+ tas tag add report.pdf work Q4 finance
179
+ tas tag add keys.env secrets production
180
+ tas search "report" # Search by filename pattern
181
+ tas search -t work # All files tagged "work"
182
+ tas search -t secrets # Quickly find your credentials
158
183
  ```
159
184
 
185
+ ---
186
+
160
187
  ### 🩺 Self-Diagnostics
161
- One command to check if everything is healthy.
162
188
 
163
189
  ```bash
164
190
  tas doctor
165
191
  # ✓ Node.js 20.11.0
166
- # ✓ Config v2 (encrypted token)
167
- # ✓ Database: 42 files, 1.3 GB total
192
+ # ✓ Config v3 (encrypted multi-bot token set)
193
+ # ✓ Database: 42 files, 1.3 GB total across 28 chunks
168
194
  # ✓ Disk space: 50 GB free (32% used)
169
- # ✓ Encryption: AES-256-GCM, PBKDF2-SHA512 600,000 iterations
195
+ # ✓ Encryption: AES-256-GCM · PBKDF2-SHA512 · 600,000 iterations (OWASP 2025)
196
+ # ✓ FUSE runtime: mount → readdir → unmount passed (Linux)
197
+ # ✓ Telegram connectivity: 2/2 bots OK
170
198
  # ✨ All systems go!
171
199
  ```
172
200
 
173
- ### 🤖 Built for Automation
174
- First-class JSON output, environment variable support, and zero interactivity mode.
201
+ ---
202
+
203
+ ### 🤖 Built for Automation — CI/CD, Docker, Cron
204
+
205
+ TAS is fully scriptable. No interactive prompts needed when `TAS_PASSWORD` is set.
175
206
 
176
207
  ```bash
177
- export TAS_PASSWORD="your-password" # Skip prompts
178
- export TAS_DATA_DIR="/custom/path" # Custom data location
208
+ # Environment-based automation
209
+ export TAS_PASSWORD="your-password"
210
+ export TAS_DATA_DIR="/custom/path"
211
+
212
+ # Pipe to jq
213
+ tas list --json | jq '.[].filename'
214
+ tas list --json | jq '.[] | select(.size > 1000000)' # Files > 1MB
215
+
216
+ # GitHub Actions backup step
217
+ tas push db-backup-$(date +%Y%m%d).sql.gz
179
218
 
180
- tas push backup.tar.gz # Non-interactive upload
181
- tas list --json | jq '.[].filename' # Pipe to jq
182
- tas status --json # Machine-readable status
219
+ # cron: nightly backup at 2am
220
+ 0 2 * * * TAS_PASSWORD=$SECRET tas push /var/backups/db.tar.gz
183
221
 
184
- # Works with: cron • GitHub Actions • Docker • systemd • any CI/CD
222
+ # JSON machine output everywhere
223
+ tas status --json
224
+ tas list --json
185
225
  ```
186
226
 
187
- <br>
227
+ ---
228
+
229
+ ## 🐳 Docker & CI/CD
188
230
 
189
- ## 🛡️ Security
231
+ ```dockerfile
232
+ FROM node:20-alpine
190
233
 
191
- TAS implements **zero-knowledge encryption** — we can't read your data, Telegram can't read your data, nobody can read your data without your password.
234
+ RUN npm install -g @nightowne/tas-cli
192
235
 
193
- | Layer | Implementation | Why It Matters |
194
- |-------|----------------|----------------|
195
- | **Cipher** | AES-256-GCM | Same cipher used by governments & banks |
196
- | **Key Derivation** | PBKDF2-SHA512, **600k iterations** | OWASP 2025 compliant — brute-force resistant |
197
- | **Salt** | 32 bytes, cryptographically random | Unique per file — no rainbow tables |
198
- | **IV** | 12 bytes, cryptographically random | Unique per file — no pattern analysis |
199
- | **Auth Tag** | 16 bytes GCM authentication | Tamper detection — any bit flip = rejected |
200
- | **Bot Token** | Encrypted at rest (AES-256-GCM) | Even your config file is protected |
201
- | **Password Hash** | Timing-safe PBKDF2 verification | Resistant to timing side-channel attacks |
202
- | **Config Permissions** | `chmod 600` on config.json | Other users on your system can't read your credentials |
203
- | **Integrity** | SHA-256 verified on every download | Bit-perfect downloads, guaranteed |
204
- | **Share Server** | Localhost-only, XSS-safe, RFC 6266 | Binds to 127.0.0.1 by default — your LAN doesn't see it |
236
+ ENV TAS_PASSWORD=""
237
+ ENV TAS_DATA_DIR="/data"
205
238
 
206
- ### What Telegram Sees
239
+ VOLUME ["/data"]
207
240
 
241
+ CMD ["tas", "status"]
208
242
  ```
209
- 📦 a7f3b2c1e9d4.tas — 12.4 MB — application/octet-stream
243
+
244
+ ```yaml
245
+ # .github/workflows/backup.yml
246
+ name: Nightly Backup
247
+
248
+ on:
249
+ schedule:
250
+ - cron: '0 2 * * *'
251
+
252
+ jobs:
253
+ backup:
254
+ runs-on: ubuntu-latest
255
+ steps:
256
+ - name: Install TAS
257
+ run: npm install -g @nightowne/tas-cli
258
+
259
+ - name: Push backup
260
+ env:
261
+ TAS_PASSWORD: ${{ secrets.TAS_PASSWORD }}
262
+ TAS_DATA_DIR: ${{ runner.temp }}/tas-data
263
+ run: |
264
+ tas init --token ${{ secrets.TELEGRAM_BOT_TOKEN }} --chat ${{ secrets.TELEGRAM_CHAT_ID }}
265
+ tar czf backup-$(date +%Y%m%d).tar.gz ./important-data/
266
+ tas push backup-$(date +%Y%m%d).tar.gz
210
267
  ```
211
268
 
212
- That's it. An opaque encrypted blob. No filename, no content, no metadata. Just noise.
269
+ ---
270
+
271
+ ## 🛡️ Security Model
272
+
273
+ TAS applies **client-side authenticated encryption**. TAS has no hosted service that receives your password, but this is not a formal zero-knowledge protocol and it does not hide all traffic metadata from Telegram.
274
+
275
+ | Layer | Implementation | Standard |
276
+ |---|---|---|
277
+ | **Cipher** | AES-256-GCM (authenticated encryption) | NIST FIPS 197 |
278
+ | **Key Derivation** | PBKDF2-SHA512, **600,000 iterations** | OWASP 2025 |
279
+ | **Salt** | 32 bytes, `crypto.randomBytes()` — unique per file | No rainbow tables |
280
+ | **IV/Nonce** | 12 bytes, `crypto.randomBytes()` — unique per file | No nonce reuse |
281
+ | **Auth Tag** | 16 bytes GCM tag — any tampered bit = instant rejection | Tamper detection |
282
+ | **Bot Tokens** | Encrypted independently at rest in `config.json` | Config v3 |
283
+ | **Password Verification** | `crypto.timingSafeEqual()` on both PBKDF2 and legacy paths | Timing-safe |
284
+ | **Config Permissions** | `chmod 600 config.json` on creation | No world-readable secrets |
285
+ | **Recovery Manifest** | gzip + AES-256-GCM; authenticated before SQLite import | Remote index recovery |
286
+ | **Integrity** | SHA-256 hash verified on completed downloads | Detects mismatch/corruption |
287
+ | **Share Server** | Binds `127.0.0.1` by default, XSS-escaped, RFC 6266 filenames | LAN-safe |
213
288
 
214
- <br>
289
+ ### What Telegram Actually Sees
290
+
291
+ ```
292
+ chunk-000000.tas — 12.4 MB — caption: tas:c1:42:1/2
293
+ ```
294
+
295
+ New uploads expose no user filename or original size in the document name, caption, or public WAS1 routing header. Telegram can still observe encrypted size, chunk count, timing, bot/chat identity, IP/network data, and message identifiers. Files uploaded by TAS 2.5 and older may still expose filename/size metadata until re-uploaded.
296
+
297
+ ### Threat Model
298
+
299
+ | Threat | Mitigated? | How |
300
+ |---|---|---|
301
+ | Telegram reads plaintext content | Mitigated | AES-256-GCM, assuming a strong password and uncompromised client |
302
+ | Telegram observes traffic metadata | Not mitigated | Bot/chat, timing, encrypted sizes, and chunk counts remain visible |
303
+ | Someone steals `config.json` | Partly mitigated | Tokens are encrypted; an offline password attack is still possible |
304
+ | Tampered download | Mitigated | GCM authentication plus final SHA-256 verification |
305
+ | Local machine compromise | Not mitigated | A process with password/filesystem access can read plaintext and tokens |
306
+ | Share link exposure | Limited | Localhost default, expiry, and download limits; the local server decrypts content |
307
+
308
+ ---
215
309
 
216
310
  ## 🔄 Reliability
217
311
 
218
- Built like professional backup tools (inspired by restic, rclone, borg):
312
+ Reliability mechanisms implemented by TAS (not an SLA):
219
313
 
220
- | Feature | Details |
221
- |---------|---------|
314
+ | Feature | Implementation |
315
+ |---|---|
222
316
  | **Exponential Backoff** | Auto-retry with jitter on Telegram 429 errors and network timeouts |
223
- | **Rate Limiting** | Built-in 1 msg/sec limiter — never hits Telegram's rate limits |
224
- | **Integrity Verification** | SHA-256 hash check after every single download |
225
- | **Resume Uploads** | Interrupted? Run `tas resume` to pick up where you left off |
226
- | **Graceful Shutdown** | SIGINT/SIGTERM handled cleanly — zero data corruption risk |
227
- | **Self-Diagnostics** | `tas doctor` validates your entire setup in seconds |
317
+ | **Rate Limiting** | One serialized send queue per configured bot within a TAS process; parallel TAS processes and Telegram's dynamic limits still apply |
318
+ | **Integrity Verification** | SHA-256 hash verified after every single download |
319
+ | **Resume Uploads** | Network-stage chunks are staged on disk and persisted in `pending_uploads`; `tas resume` continues them |
320
+ | **Index Recovery** | Authenticated encrypted remote manifest; `tas index rebuild` restores file/chunk ownership |
321
+ | **Graceful Shutdown** | SIGINT/SIGTERM handled; staged chunks and SQLite WAL reduce partial-state risk |
322
+ | **Self-Diagnostics** | Checks config/database/chunk limits, all bots, and a real Linux FUSE smoke mount |
228
323
 
229
- <br>
324
+ ---
230
325
 
231
326
  ## 📋 CLI Reference
232
327
 
@@ -234,16 +329,20 @@ Built like professional backup tools (inspired by restic, rclone, borg):
234
329
  <summary><strong>Core Commands</strong></summary>
235
330
 
236
331
  ```bash
237
- tas init # 🚀 Interactive setup wizard
238
- tas push <file> # ⬆️ Upload (encrypt + compress + upload)
239
- tas pull <file|hash> # ⬇️ Download (download + decrypt + verify)
240
- tas list [-l] [--json] # 📋 List all files
241
- tas delete <file|hash> # 🗑️ Remove from index (--hard to delete from Telegram)
242
- tas status [--json] # 📊 Storage stats
243
- tas search <query> # 🔍 Find files by name or tag
244
- tas resume # 🔄 Resume interrupted uploads
245
- tas verify # ✅ Verify all files exist & are intact
246
- tas doctor # 🩺 System health check
332
+ tas init [--token T --chat ID --password PW] # 🚀 Wizard, or fully non-interactive for CI/Docker
333
+ tas push <files...> # ⬆️ Encrypt + compress + upload (batch supported)
334
+ tas pull <file|hash> # ⬇️ Download + decrypt + verify
335
+ tas list [-l] [--json] # 📋 List all stored files
336
+ tas delete <file|hash> # 🗑️ Remove from index (--hard removes from Telegram)
337
+ tas status [--json] # 📊 Storage stats & database health
338
+ tas search <query> [-t tag] # 🔍 Find by filename or tag
339
+ tas resume # 🔄 Resume interrupted uploads
340
+ tas verify # ✅ Check every Telegram file reference
341
+ tas verify --deep # ✅ Download/decrypt/hash every file (slow and bandwidth-heavy)
342
+ tas doctor # 🩺 Full system health check
343
+ tas index backup # 🧯 Publish encrypted recovery manifest
344
+ tas index rebuild # 🧯 Restore index.db from that manifest
345
+ tas bot add|list|enable|disable|remove # 🤖 Manage experimental bot pool
247
346
  ```
248
347
 
249
348
  </details>
@@ -252,15 +351,15 @@ tas doctor # 🩺 System health check
252
351
  <summary><strong>Mount & Sync</strong></summary>
253
352
 
254
353
  ```bash
255
- # FUSE Mount (use Telegram like a local folder)
256
- tas mount <path> # Mount
257
- tas unmount <path> # Unmount
258
-
259
- # Folder Sync (Dropbox-style auto-upload)
260
- tas sync add <folder> # Register a folder to sync
261
- tas sync start # Start watching for changes
262
- tas sync pull # Download all synced files
263
- tas sync status # Show sync status
354
+ # FUSE Mount (Linux only in this release)
355
+ tas mount <path> # Mount Telegram storage as a local folder
356
+ tas unmount <path> # Clean unmount
357
+
358
+ # Dropbox-style Folder Sync
359
+ tas sync add <folder> # Register folder for auto-sync
360
+ tas sync start # Start watching for changes
361
+ tas sync pull # Download all synced files locally
362
+ tas sync status # Show sync queue and status
264
363
  ```
265
364
 
266
365
  </details>
@@ -269,94 +368,155 @@ tas sync status # Show sync status
269
368
  <summary><strong>Share & Tags</strong></summary>
270
369
 
271
370
  ```bash
272
- # Temporary Share Links
273
- tas share create <file> [--expire 24h] [--max-downloads 3]
274
- tas share list # Active shares
275
- tas share revoke <token> # Revoke a share link
276
-
277
- # File Tags
278
- tas tag add <file> <tags...>
279
- tas tag remove <file> <tags...>
280
- tas tag list [tag] # List tags or files with a specific tag
371
+ # Expiring Share Links
372
+ tas share create <file> [--expire 1h|24h|7d] [--max-downloads N] [--host 0.0.0.0] [--port 3000]
373
+ tas share list # Active links with expiry countdown
374
+ tas share revoke <token> # Instantly revoke a share
375
+
376
+ # File Tagging
377
+ tas tag add <file> <tag> [tag2...]
378
+ tas tag remove <file> <tag>
379
+ tas tag list [tag] # List all tags, or files with a specific tag
281
380
  ```
282
381
 
283
382
  </details>
284
383
 
285
- <br>
384
+ <details>
385
+ <summary><strong>Environment Variables</strong></summary>
386
+
387
+ ```bash
388
+ TAS_PASSWORD="..." # Skip password prompts (CI/CD, cron, Docker)
389
+ TAS_DATA_DIR="/custom/path" # Override default ~/.tas data directory
390
+ ```
391
+
392
+ </details>
393
+
394
+ ---
286
395
 
287
396
  ## 🏗️ Architecture
288
397
 
289
398
  ```
290
399
  src/
291
- ├── cli.js # Commander-based CLI — all commands
292
- ├── index.js # Streaming upload/download pipeline
400
+ ├── cli.js # Commander-based CLI — all commands defined here
401
+ ├── index.js # Core streaming upload/download pipeline
402
+ ├── manifest.js # Encrypted remote index backup/rebuild
293
403
  ├── crypto/
294
- │ └── encryption.js # AES-256-GCM + PBKDF2-SHA512 key derivation
404
+ │ └── encryption.js # AES-256-GCM + PBKDF2-SHA512 (600k iterations)
295
405
  ├── db/
296
- │ └── index.js # SQLite index (files, chunks, tags, shares, sync)
406
+ │ └── index.js # SQLite index: files, chunks, tags, shares, sync
297
407
  ├── telegram/
298
- │ └── client.js # Bot API wrapper — retry, rate-limit, streaming
408
+ │ ├── client.js # Bot API wrapper — retry + serialized send queue
409
+ │ └── pool.js # Stable per-chunk multi-bot routing
299
410
  ├── fuse/
300
- │ └── mount.js # FUSE filesystem — mount Telegram as a folder
411
+ │ └── mount.js # FUSE filesystem — mount Telegram as a local folder
301
412
  ├── share/
302
- │ └── server.js # HTTP server — expiring download links
413
+ │ └── server.js # HTTP server — expiring encrypted share links
303
414
  ├── sync/
304
- │ └── sync.js # Folder watcher — Dropbox-style auto-sync
415
+ │ └── sync.js # fs.watch folder watcher — Dropbox-style auto-sync
305
416
  └── utils/
306
- ├── download-stream.js # Shared Telegram→Decrypt→Decompress pipeline
307
- ├── compression.js # Smart gzip (skips already-compressed formats)
308
- ├── chunker.js # 49MB chunking with custom WAS1 file headers
309
- ├── progress.js # Terminal progress bar with speed + ETA
310
- ├── throttle.js # Bandwidth limiter (stream transform)
311
- ├── branding.js # ASCII art + formatting
312
- └── cli-helpers.js # Password management + config resolution
417
+ ├── download-stream.js # Shared Telegram→Decrypt→Decompress pipeline
418
+ ├── compression.js # Smart gzip (skips already-compressed formats)
419
+ ├── chunker.js # 19 MiB payloads + metadata-free public WAS1 headers
420
+ ├── logical-path.js # Portable exact paths + virtual directory tree
421
+ ├── progress.js # Terminal progress bars with MB/s + ETA
422
+ ├── throttle.js # Bandwidth limiter (stream transform)
423
+ ├── branding.js # ASCII art + version display
424
+ └── cli-helpers.js # Password management + config resolution
313
425
  ```
314
426
 
315
- **Tech stack:** Node.js · better-sqlite3 · node-telegram-bot-api · fuse-native · Commander · Chalk · Ora · Inquirer
427
+ **Tech stack:** Node.js 18+ · better-sqlite3 · node-telegram-bot-api · fuse-native · Commander · Chalk · Ora · Inquirer
316
428
 
317
- <br>
429
+ ---
430
+
431
+ ## 💡 Perfect For
432
+
433
+ | Use Case | Example |
434
+ |---|---|
435
+ | 📄 **Personal document vault** | Taxes, contracts, scans, receipts — encrypted |
436
+ | 🔑 **Secrets & credentials** | `.env` files, SSH private keys, API tokens |
437
+ | 🗝️ **Password manager sync** | KeePass `.kdbx`, 1Password vaults, Bitwarden exports |
438
+ | 📦 **Code project backups** | Git bundles, build artifacts, config files |
439
+ | 🎬 **Private media archive** | Photos, videos, music — encrypted & searchable |
440
+ | 🔗 **Ephemeral file sharing** | Burn-after-read links with download limits |
441
+ | 💾 **Offsite backup** | Nightly database dumps, system configs via cron |
442
+ | 🤖 **CI/CD artifacts** | Store build outputs, test reports, deployment keys |
443
+
444
+ **Not appropriate for:** the only copy of any data, mission-critical/business backups, regulated retention, team storage, or workloads that require an SLA. Telegram can remove messages or terminate access without giving TAS a recovery channel.
445
+
446
+ ---
447
+
448
+ ## ❓ Is This Allowed? (The Legal Question)
449
+
450
+ ### Can Telegram restrict or terminate this use?
451
+
452
+ **Yes.** The Bot API supports sending documents, but that technical capability is not permission or a storage guarantee. Telegram's current [Bot Developer Terms](https://telegram.org/tos/bot-developers) explicitly restrict external applications that diverge into cloud-storage use cases, prohibit circumventing rate limits, and allow bot/account termination. TAS cannot promise that one bot—or a multi-bot pool—will remain available.
453
+
454
+ Use TAS only at your own risk, do not use multiple bots to evade limits, follow all applicable laws and Telegram terms, and keep a tested independent backup. Encryption protects content confidentiality; it does not make the usage invisible or policy-compliant.
455
+
456
+ ---
318
457
 
319
458
  ## ⚠️ Good to Know
320
459
 
321
460
  | | |
322
461
  |---|---|
323
- | 📌 **Not a backup solution** | Telegram can delete content. Use TAS alongside proper backups, not instead of them. |
324
- | 📌 **49 MB chunks** | Files are automatically split due to Telegram Bot API limits. Fully transparent. |
325
- | 📌 **Single-user** | Designed for personal use. Not multi-tenant. |
326
- | 📌 **FUSE = Linux/macOS** | Mount feature requires `libfuse`. CLI works everywhere Node.js runs. |
462
+ | 📌 **Not a replacement for backups** | Telegram can purge old messages. Use TAS alongside, not instead of, real backup solutions. |
463
+ | 📌 **19 MiB payload chunks** | Hosted Bot API uploads permit more, but `getFile` documents only 20 MB downloads. TAS stays below the read limit. |
464
+ | 📌 **Multi-bot is experimental** | It distributes chunks and preserves ownership mapping; it is not redundancy or ban protection. |
465
+ | 📌 **FUSE = Linux only for now** | macOS mount is disabled until a maintained modern macFUSE backend and macOS CI exist. |
466
+ | 📌 **Recovery needs config** | `index.db` can be rebuilt from the encrypted manifest only if `config.json`, password, manifest message, and owning bot survive. |
327
467
  | 📌 **No versioning (yet)** | Overwriting a file replaces the previous version. |
468
+ | 📌 **Internet required** | Telegram-backed — offline access requires files pulled locally first. |
328
469
 
329
- <br>
470
+ ---
330
471
 
331
472
  ## 🛠️ Development
332
473
 
333
474
  ```bash
334
475
  git clone https://github.com/ixchio/tas
335
476
  cd tas && npm install
336
- npm test # 71 tests, all passing
477
+
478
+ npm test # Run all 97 tests (crypto, paths, migrations, multi-bot, resume, manifest, sync, shares)
479
+ npm test -- --watch # Watch mode for active development
337
480
  ```
338
481
 
339
- PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
482
+ **Test coverage:** streaming encrypt/decrypt roundtrips · cross-API compat (buffer↔stream) · small-chunk stress testing · truncation/corruption error paths · Unicode filename handling · WAS1 binary header parsing · timing-safe comparison paths
340
483
 
341
- <br>
484
+ PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
485
+
486
+ ---
342
487
 
343
488
  ## 🌟 Contributing
344
489
 
345
- TAS is open source and we love contributions:
490
+ TAS is open source and contributions are genuinely appreciated:
346
491
 
347
- - 🐛 **Found a bug?** [Open an issue](https://github.com/ixchio/tas/issues)
348
- - 💡 **Have an idea?** [Start a discussion](https://github.com/ixchio/tas/issues)
349
- - 🔧 **Want to contribute?** Fork → Branch → PR → 🎉
492
+ - 🐛 **Found a bug?** [Open an issue](https://github.com/ixchio/tas/issues) — include `tas doctor` output
493
+ - 💡 **Have a feature idea?** [Start a discussion](https://github.com/ixchio/tas/discussions)
494
+ - 🔧 **Want to contribute code?** Fork → branch → PR → 🎉
495
+ - ⭐ **Just want to help?** A GitHub star dramatically increases discoverability
350
496
 
351
- <br>
497
+ ---
352
498
 
353
499
  ## 📄 License
354
500
 
355
- MIT — use it, fork it, ship it, sell it. Do whatever you want.
501
+ MIT — use it, fork it, ship it, sell it. Do whatever you want with it.
502
+
503
+ ---
504
+
505
+ ## Related Projects
506
+
507
+ If TAS fits your workflow, you might also find these useful:
508
+
509
+ - [rclone](https://github.com/rclone/rclone) — rsync for cloud storage (dozens of backends)
510
+ - [restic](https://github.com/restic/restic) — encrypted, deduplicated backup program
511
+ - [age](https://github.com/FiloSottile/age) — simple, modern file encryption tool
512
+ - [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole) — encrypted file transfer between machines
356
513
 
357
514
  ---
358
515
 
359
516
  <p align="center">
360
517
  <sub>Built with ☕ and stubbornness by <a href="https://github.com/ixchio">@ixchio</a></sub><br>
361
- <sub>If TAS saved you money, consider giving it a ⭐</sub>
518
+ <sub>If TAS saved you money, a ⭐ on GitHub is the best way to say thanks — it helps others find the project.</sub><br><br>
519
+ <a href="https://github.com/ixchio/tas/stargazers">
520
+ <img src="https://img.shields.io/github/stars/ixchio/tas?style=for-the-badge&logo=github&label=Star%20TAS&color=ffd700" alt="Star TAS on GitHub">
521
+ </a>
362
522
  </p>