aethel 0.1.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/.env.example +2 -0
- package/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/docs/ARCHITECTURE.md +237 -0
- package/package.json +60 -0
- package/src/cli.js +1063 -0
- package/src/core/auth.js +288 -0
- package/src/core/config.js +117 -0
- package/src/core/diff.js +254 -0
- package/src/core/drive-api.js +1442 -0
- package/src/core/ignore.js +146 -0
- package/src/core/local-fs.js +109 -0
- package/src/core/remote-cache.js +65 -0
- package/src/core/snapshot.js +159 -0
- package/src/core/staging.js +125 -0
- package/src/core/sync.js +227 -0
- package/src/tui/app.js +1025 -0
- package/src/tui/index.js +10 -0
package/.env.example
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
- Initial npm release of the Aethel CLI and Ink TUI
|
|
6
|
+
- Google Drive OAuth authentication and workspace initialization
|
|
7
|
+
- Git-style sync workflow with snapshot, diff, staging, pull, push, and commit
|
|
8
|
+
- Conflict resolution, restore, ignore management, and history inspection
|
|
9
|
+
- Duplicate-folder detection and reconciliation for Google Drive
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Aethel Contributors
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Aethel
|
|
2
|
+
|
|
3
|
+
Git-style Google Drive sync CLI with an interactive terminal UI.
|
|
4
|
+
|
|
5
|
+
Aethel lets you manage a local workspace mirrored to Google Drive using
|
|
6
|
+
familiar commands (`init`, `status`, `diff`, `add`, `commit`, `pull`, `push`)
|
|
7
|
+
and ships with a dual-pane TUI for browsing, uploading, and deleting files
|
|
8
|
+
across local and remote directories.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g aethel
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or install from source:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/aethel/aethel.git
|
|
20
|
+
cd aethel
|
|
21
|
+
npm install
|
|
22
|
+
npm run install:cli # symlinks `aethel` into ~/.local/bin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Requirements:** Node.js >= 18
|
|
26
|
+
|
|
27
|
+
## Release Readiness
|
|
28
|
+
|
|
29
|
+
- npm package metadata is defined in `package.json`
|
|
30
|
+
- publish contents are restricted through the `files` allowlist
|
|
31
|
+
- local secrets such as `credentials.json` and `token.json` are excluded from Git and npm publish
|
|
32
|
+
- release validation runs with `npm test` and `npm run pack:check`
|
|
33
|
+
|
|
34
|
+
## GitHub Automation
|
|
35
|
+
|
|
36
|
+
- `CI`: runs `npm ci`, `npm test`, and `npm run pack:check` on every push and pull request across Node.js 18, 20, and 22
|
|
37
|
+
- `Release`: publishes to npm with trusted publishing when a GitHub Release is published or when the workflow is triggered manually
|
|
38
|
+
- `Dependabot`: opens weekly dependency update PRs for npm packages and GitHub Actions
|
|
39
|
+
|
|
40
|
+
To enable npm trusted publishing, configure a trusted publisher for package `aethel` on npm with:
|
|
41
|
+
|
|
42
|
+
- provider: GitHub Actions
|
|
43
|
+
- owner: `CCJ-0617`
|
|
44
|
+
- repository: `Aethel`
|
|
45
|
+
- workflow filename: `release.yml`
|
|
46
|
+
|
|
47
|
+
After trusted publishing works once, disable token-based publishing in npm package settings and revoke any old npm automation tokens.
|
|
48
|
+
|
|
49
|
+
## Google Cloud Setup
|
|
50
|
+
|
|
51
|
+
1. Create a project in the [Google Cloud Console](https://console.cloud.google.com/).
|
|
52
|
+
2. Enable the **Google Drive API**.
|
|
53
|
+
3. Create an **OAuth 2.0 Client ID** (application type: Desktop).
|
|
54
|
+
4. Download the credentials JSON and save it as `credentials.json` in your
|
|
55
|
+
project root (or set `GOOGLE_DRIVE_CREDENTIALS_PATH`).
|
|
56
|
+
|
|
57
|
+
Keep `credentials.json` and `token.json` local only. Do not commit them to GitHub.
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Authenticate and verify access
|
|
63
|
+
aethel auth
|
|
64
|
+
|
|
65
|
+
# Initialize a sync workspace
|
|
66
|
+
aethel init --local-path ./workspace
|
|
67
|
+
|
|
68
|
+
# Optional: target a specific Drive folder
|
|
69
|
+
aethel init --local-path ./workspace \
|
|
70
|
+
--drive-folder <folder-id> \
|
|
71
|
+
--drive-folder-name "My Project"
|
|
72
|
+
|
|
73
|
+
# Check status and sync
|
|
74
|
+
aethel status
|
|
75
|
+
aethel diff --side all
|
|
76
|
+
aethel add --all
|
|
77
|
+
aethel commit -m "initial sync"
|
|
78
|
+
aethel pull -m "pull"
|
|
79
|
+
aethel push -m "push"
|
|
80
|
+
aethel log -n 10
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Commands
|
|
84
|
+
|
|
85
|
+
| Command | Description |
|
|
86
|
+
|---------|-------------|
|
|
87
|
+
| `auth` | Run OAuth flow, create `token.json`, verify Drive access |
|
|
88
|
+
| `init` | Initialize a local sync workspace |
|
|
89
|
+
| `status` | Show workspace status (local vs remote changes) |
|
|
90
|
+
| `diff` | Show detailed file differences |
|
|
91
|
+
| `add` | Stage changes for commit |
|
|
92
|
+
| `reset` | Unstage changes |
|
|
93
|
+
| `commit` | Execute staged sync operations |
|
|
94
|
+
| `pull` | Fetch remote changes and commit |
|
|
95
|
+
| `push` | Stage and push local changes |
|
|
96
|
+
| `log` | Show sync history |
|
|
97
|
+
| `fetch` | Refresh remote state without applying changes |
|
|
98
|
+
| `resolve` | Resolve conflicts by choosing local, remote, or both |
|
|
99
|
+
| `ignore` | List, test, or create `.aethelignore` patterns |
|
|
100
|
+
| `show` | Show a saved snapshot |
|
|
101
|
+
| `restore` | Restore files from the last snapshot |
|
|
102
|
+
| `rm` | Remove local files and stage remote deletion |
|
|
103
|
+
| `mv` | Move or rename local files |
|
|
104
|
+
| `clean` | List and optionally trash/delete accessible Drive files |
|
|
105
|
+
| `dedupe-folders` | Detect and merge duplicate remote folders |
|
|
106
|
+
| `tui` | Launch interactive terminal UI |
|
|
107
|
+
|
|
108
|
+
## TUI
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
aethel tui
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Dual-pane file browser with local filesystem on the left and Google Drive on
|
|
115
|
+
the right.
|
|
116
|
+
|
|
117
|
+
| Key | Action |
|
|
118
|
+
|-----|--------|
|
|
119
|
+
| `Tab` | Switch focus between Local / Drive pane |
|
|
120
|
+
| `Left` / `Right` | Navigate up / into directories |
|
|
121
|
+
| `u` | Upload selected local file or folder to current Drive directory |
|
|
122
|
+
| `s` | Batch sync local folder contents to current Drive directory |
|
|
123
|
+
| `U` | Upload from a manually entered local path |
|
|
124
|
+
| `n` | Rename selected local item |
|
|
125
|
+
| `x` | Delete selected local item |
|
|
126
|
+
| `Space` | Toggle selection in Drive pane |
|
|
127
|
+
| `t` / `d` | Trash / permanently delete selected Drive items |
|
|
128
|
+
| `/` | Filter by name |
|
|
129
|
+
|
|
130
|
+
## Deduplication
|
|
131
|
+
|
|
132
|
+
When duplicate folders accumulate from multi-device conflicts, run:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Dry run — report duplicates without changing anything
|
|
136
|
+
aethel dedupe-folders
|
|
137
|
+
|
|
138
|
+
# Execute — merge duplicates and trash empty losers
|
|
139
|
+
aethel dedupe-folders --execute
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The deduplication engine processes folders deepest-first to guarantee
|
|
143
|
+
single-pass convergence, caches child state in memory to minimize API calls,
|
|
144
|
+
and runs independent merge groups in parallel. Paths matching `.aethelignore`
|
|
145
|
+
are excluded automatically.
|
|
146
|
+
|
|
147
|
+
## Ignore Patterns
|
|
148
|
+
|
|
149
|
+
Create a `.aethelignore` file (gitignore syntax) in your workspace root to
|
|
150
|
+
exclude paths from sync and deduplication:
|
|
151
|
+
|
|
152
|
+
```gitignore
|
|
153
|
+
.venv/
|
|
154
|
+
node_modules/
|
|
155
|
+
__pycache__/
|
|
156
|
+
.idea/
|
|
157
|
+
.vscode/
|
|
158
|
+
dist/
|
|
159
|
+
build/
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
A default `.aethelignore` is created on `init`.
|
|
163
|
+
|
|
164
|
+
## Environment Variables
|
|
165
|
+
|
|
166
|
+
| Variable | Default | Description |
|
|
167
|
+
|----------|---------|-------------|
|
|
168
|
+
| `GOOGLE_DRIVE_CREDENTIALS_PATH` | `credentials.json` | Path to OAuth credentials |
|
|
169
|
+
| `GOOGLE_DRIVE_TOKEN_PATH` | `token.json` | Path to cached OAuth token |
|
|
170
|
+
| `AETHEL_DRIVE_CONCURRENCY` | `40` | Max concurrent Drive API requests |
|
|
171
|
+
|
|
172
|
+
## Architecture
|
|
173
|
+
|
|
174
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for module structure and data
|
|
175
|
+
flow.
|
|
176
|
+
|
|
177
|
+
## Publishing
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npm test
|
|
181
|
+
npm run pack:check
|
|
182
|
+
npm publish
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For a GitHub release, push the tagged version and create a release that matches
|
|
186
|
+
the published npm version.
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Aethel Architecture
|
|
2
|
+
|
|
3
|
+
## 1. Project Positioning
|
|
4
|
+
|
|
5
|
+
Aethel is a synchronization tool that uses Google Drive as its remote storage. It exposes two interface layers:
|
|
6
|
+
|
|
7
|
+
- CLI: provides a Git-like workflow with `auth`, `init`, `status`, `diff`, `add`, `commit`, `pull`, and `push`.
|
|
8
|
+
- TUI: provides an interactive dual-pane interface for local files and Google Drive.
|
|
9
|
+
|
|
10
|
+
The core design is not a live mirror between local storage and Drive. Instead, synchronization is managed through a `snapshot + diff + staging + execute` pipeline.
|
|
11
|
+
|
|
12
|
+
## 2. Module Layers
|
|
13
|
+
|
|
14
|
+
### 2.1 Entry Layer
|
|
15
|
+
|
|
16
|
+
- `src/cli.js`
|
|
17
|
+
- Command-line entry point
|
|
18
|
+
- Parses commands, assembles workspace state, and invokes core sync capabilities
|
|
19
|
+
- `src/tui/index.js`
|
|
20
|
+
- Starts the Ink TUI
|
|
21
|
+
- `src/tui/app.js`
|
|
22
|
+
- Implements dual-pane file browsing, filtering, uploads, deletion, and interactive operations
|
|
23
|
+
|
|
24
|
+
### 2.2 Core Capability Layer
|
|
25
|
+
|
|
26
|
+
- `src/core/auth.js`
|
|
27
|
+
- OAuth authentication
|
|
28
|
+
- Creates and reads `token.json`
|
|
29
|
+
- `src/core/drive-api.js`
|
|
30
|
+
- Google Drive API wrapper
|
|
31
|
+
- Listing, downloading, uploading, deleting, folder creation, and batch operations
|
|
32
|
+
- `src/core/local-fs.js`
|
|
33
|
+
- Local filesystem operations
|
|
34
|
+
- `src/core/snapshot.js`
|
|
35
|
+
- Scans local files, computes md5 hashes, and builds snapshots
|
|
36
|
+
- `src/core/diff.js`
|
|
37
|
+
- Compares snapshot / remote / local state and produces change sets
|
|
38
|
+
- `src/core/staging.js`
|
|
39
|
+
- Manages the staging area
|
|
40
|
+
- `src/core/sync.js`
|
|
41
|
+
- Executes staged operations
|
|
42
|
+
- `src/core/config.js`
|
|
43
|
+
- Manages `.aethel/` state files
|
|
44
|
+
- `src/core/ignore.js`
|
|
45
|
+
- Manages `.aethelignore`
|
|
46
|
+
- `src/core/remote-cache.js`
|
|
47
|
+
- Short-lived cache for remote listings
|
|
48
|
+
|
|
49
|
+
### 2.3 State Storage Layer
|
|
50
|
+
|
|
51
|
+
After workspace initialization, the project root contains:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
.aethel/
|
|
55
|
+
config.json
|
|
56
|
+
index.json
|
|
57
|
+
.hash-cache.json
|
|
58
|
+
snapshots/
|
|
59
|
+
latest.json
|
|
60
|
+
history/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `config.json`: sync root configuration
|
|
64
|
+
- `index.json`: currently staged operations
|
|
65
|
+
- `.hash-cache.json`: local file hash cache
|
|
66
|
+
- `snapshots/latest.json`: baseline state after the most recent successful sync
|
|
67
|
+
- `snapshots/history/`: archived older snapshots
|
|
68
|
+
|
|
69
|
+
## 3. Core Data Flow
|
|
70
|
+
|
|
71
|
+
```mermaid
|
|
72
|
+
flowchart LR
|
|
73
|
+
User["User"]
|
|
74
|
+
CLI["CLI / TUI"]
|
|
75
|
+
Auth["auth.js"]
|
|
76
|
+
Config["config.js"]
|
|
77
|
+
Local["snapshot.js + local-fs.js"]
|
|
78
|
+
Cache["remote-cache.js"]
|
|
79
|
+
Drive["drive-api.js"]
|
|
80
|
+
Diff["diff.js"]
|
|
81
|
+
Stage["staging.js"]
|
|
82
|
+
Sync["sync.js"]
|
|
83
|
+
State[".aethel state"]
|
|
84
|
+
Google["Google Drive"]
|
|
85
|
+
Disk["Local Files"]
|
|
86
|
+
|
|
87
|
+
User --> CLI
|
|
88
|
+
CLI --> Auth
|
|
89
|
+
CLI --> Config
|
|
90
|
+
CLI --> Local
|
|
91
|
+
CLI --> Cache
|
|
92
|
+
CLI --> Drive
|
|
93
|
+
Local --> Disk
|
|
94
|
+
Cache --> State
|
|
95
|
+
Config --> State
|
|
96
|
+
Drive --> Google
|
|
97
|
+
Local --> Diff
|
|
98
|
+
Drive --> Diff
|
|
99
|
+
State --> Diff
|
|
100
|
+
Diff --> Stage
|
|
101
|
+
Stage --> State
|
|
102
|
+
Stage --> Sync
|
|
103
|
+
Sync --> Disk
|
|
104
|
+
Sync --> Google
|
|
105
|
+
Sync --> State
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 4. Synchronization Model
|
|
109
|
+
|
|
110
|
+
### 4.1 Baseline
|
|
111
|
+
|
|
112
|
+
Aethel uses `snapshot` as the shared baseline:
|
|
113
|
+
|
|
114
|
+
- `snapshot.files`: remote file information from the last sync
|
|
115
|
+
- `snapshot.localFiles`: local file information from the last sync
|
|
116
|
+
|
|
117
|
+
That means the system does not compare only "local vs remote". It also asks:
|
|
118
|
+
|
|
119
|
+
- Has Drive changed since the last sync?
|
|
120
|
+
- Has local state changed since the last sync?
|
|
121
|
+
- Did both sides modify the same path?
|
|
122
|
+
|
|
123
|
+
### 4.2 Diff Categories
|
|
124
|
+
|
|
125
|
+
`src/core/diff.js` classifies changes as:
|
|
126
|
+
|
|
127
|
+
- `remote_added`
|
|
128
|
+
- `remote_modified`
|
|
129
|
+
- `remote_deleted`
|
|
130
|
+
- `local_added`
|
|
131
|
+
- `local_modified`
|
|
132
|
+
- `local_deleted`
|
|
133
|
+
- `conflict`
|
|
134
|
+
|
|
135
|
+
It also provides default suggested actions for each category:
|
|
136
|
+
|
|
137
|
+
- Drive added/modified -> `download`
|
|
138
|
+
- Drive deleted -> `delete_local`
|
|
139
|
+
- Local added/modified -> `upload`
|
|
140
|
+
- Local deleted -> `delete_remote`
|
|
141
|
+
- Both sides changed the same path -> `conflict`
|
|
142
|
+
|
|
143
|
+
### 4.3 Execution Model
|
|
144
|
+
|
|
145
|
+
`commit` is not a Git commit. It executes the synchronization actions currently staged:
|
|
146
|
+
|
|
147
|
+
1. Read `index.json`
|
|
148
|
+
2. Route each entry by action as `download / upload / delete_local / delete_remote`
|
|
149
|
+
3. Execute local and remote operations
|
|
150
|
+
4. Clear staged entries
|
|
151
|
+
5. Rebuild the snapshot and write the new state to `.aethel/snapshots/latest.json`
|
|
152
|
+
|
|
153
|
+
## 5. Relationship Between TUI and CLI
|
|
154
|
+
|
|
155
|
+
Both interfaces share the same core modules. The difference is only the interaction surface:
|
|
156
|
+
|
|
157
|
+
- CLI is oriented toward predictable, scriptable sync workflows
|
|
158
|
+
- TUI is oriented toward manual inspection, fast operations, and hands-on Drive / Local management
|
|
159
|
+
|
|
160
|
+
The TUI is not a separate synchronization engine. It directly calls `drive-api.js` and `local-fs.js` for interactive file management.
|
|
161
|
+
|
|
162
|
+
## 6. Recommended Workflow
|
|
163
|
+
|
|
164
|
+
### 6.1 Initial Workspace Setup
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npm install
|
|
168
|
+
npm run auth
|
|
169
|
+
node src/cli.js init --local-path ./workspace --drive-folder <drive-folder-id>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Use this when:
|
|
173
|
+
|
|
174
|
+
- Starting a new project
|
|
175
|
+
- Creating a new sync root
|
|
176
|
+
- Intentionally syncing only a specific Drive folder
|
|
177
|
+
|
|
178
|
+
### 6.2 Day-to-Day Sync Workflow
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
node src/cli.js status
|
|
182
|
+
node src/cli.js diff --side all
|
|
183
|
+
node src/cli.js add --all
|
|
184
|
+
node src/cli.js commit -m "sync"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This is the most reasonable standard flow because:
|
|
188
|
+
|
|
189
|
+
1. `status` gives you the overall state first
|
|
190
|
+
2. `diff` shows details and conflicts
|
|
191
|
+
3. `add --all` stages the default suggested actions
|
|
192
|
+
4. `commit` performs the actual synchronization
|
|
193
|
+
|
|
194
|
+
This preserves a manual confirmation point and helps avoid pushing a bad state to Drive or overwriting local files by mistake.
|
|
195
|
+
|
|
196
|
+
### 6.3 When Conflicts Occur
|
|
197
|
+
|
|
198
|
+
Recommended flow:
|
|
199
|
+
|
|
200
|
+
1. Run `status` or `diff`
|
|
201
|
+
2. Identify `conflict` entries
|
|
202
|
+
3. Decide explicitly whether to keep local, keep remote, or keep both
|
|
203
|
+
4. Then stage and commit
|
|
204
|
+
|
|
205
|
+
Why:
|
|
206
|
+
|
|
207
|
+
- In Aethel, a conflict means both sides changed the same path after the snapshot
|
|
208
|
+
- This should not be resolved automatically because it can cause silent overwrites
|
|
209
|
+
|
|
210
|
+
### 6.4 When Manual Inspection Is Needed
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm run tui
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The TUI is useful for:
|
|
217
|
+
|
|
218
|
+
- Browsing the Drive structure
|
|
219
|
+
- Selecting items and deleting them
|
|
220
|
+
- Uploading files or entire folders directly from local storage
|
|
221
|
+
- Finding files quickly with filters
|
|
222
|
+
|
|
223
|
+
If the goal is traceable, repeatable synchronization, the CLI workflow should still be the default choice.
|
|
224
|
+
|
|
225
|
+
## 7. Recommended Practices
|
|
226
|
+
|
|
227
|
+
- Use a single Drive root folder as the workspace remote root instead of syncing the entire My Drive directly.
|
|
228
|
+
- Run `status` or `diff` before every `commit`.
|
|
229
|
+
- Treat `.aethelignore` as a synchronization boundary control file, not just a UI filter.
|
|
230
|
+
- Keep `.hash-cache.json` for large workspaces to avoid recomputing all md5 values every time.
|
|
231
|
+
- Prefer the TUI or a dry run for risky operations before executing them for real.
|
|
232
|
+
|
|
233
|
+
## 8. Future Improvements
|
|
234
|
+
|
|
235
|
+
- Split CLI commands and state transitions into a service layer to reduce how much workflow logic is aggregated in `src/cli.js`.
|
|
236
|
+
- Add documentation for the snapshot schema and index schema.
|
|
237
|
+
- Add automated tests, especially around diff/conflict handling and the sync executor.
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aethel",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Git-style Google Drive sync CLI with interactive TUI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/aethel/aethel.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/aethel/aethel#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/aethel/aethel/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"google-drive",
|
|
17
|
+
"sync",
|
|
18
|
+
"cli",
|
|
19
|
+
"tui",
|
|
20
|
+
"backup",
|
|
21
|
+
"drive",
|
|
22
|
+
"file-manager"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"aethel": "./src/cli.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"src/",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"README.md",
|
|
31
|
+
"CHANGELOG.md",
|
|
32
|
+
"docs/ARCHITECTURE.md",
|
|
33
|
+
".env.example"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"start": "node src/cli.js",
|
|
37
|
+
"auth": "node src/cli.js auth",
|
|
38
|
+
"clean": "node src/cli.js clean",
|
|
39
|
+
"install:cli": "bash scripts/install.sh",
|
|
40
|
+
"pack:check": "npm pack --dry-run",
|
|
41
|
+
"prepublishOnly": "npm test && npm run pack:check",
|
|
42
|
+
"test": "node --test",
|
|
43
|
+
"tui": "node src/cli.js tui"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"chalk": "^5.3.0",
|
|
47
|
+
"commander": "^12.1.0",
|
|
48
|
+
"googleapis": "^140.0.1",
|
|
49
|
+
"ignore": "^7.0.5",
|
|
50
|
+
"ink": "^5.1.0",
|
|
51
|
+
"ink-select-input": "^6.0.0",
|
|
52
|
+
"ink-spinner": "^5.0.0",
|
|
53
|
+
"ink-text-input": "^6.0.0",
|
|
54
|
+
"open": "^10.1.0",
|
|
55
|
+
"react": "^18.3.1"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18"
|
|
59
|
+
}
|
|
60
|
+
}
|