centy 0.0.5 → 0.0.9
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 +299 -0
- package/bin/run.js +14 -2
- package/dist/commands/install/daemon.d.ts +12 -0
- package/dist/commands/install/daemon.d.ts.map +1 -0
- package/dist/commands/install/daemon.js +41 -0
- package/dist/commands/install/daemon.js.map +1 -0
- package/dist/commands/shutdown.d.ts.map +1 -1
- package/dist/commands/shutdown.js +5 -0
- package/dist/commands/shutdown.js.map +1 -1
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +79 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/hooks/prerun.js +1 -1
- package/dist/hooks/prerun.js.map +1 -1
- package/dist/lib/install-daemon/checksum.d.ts +2 -0
- package/dist/lib/install-daemon/checksum.d.ts.map +1 -0
- package/dist/lib/install-daemon/checksum.js +31 -0
- package/dist/lib/install-daemon/checksum.js.map +1 -0
- package/dist/lib/install-daemon/download.d.ts +8 -0
- package/dist/lib/install-daemon/download.d.ts.map +1 -0
- package/dist/lib/install-daemon/download.js +40 -0
- package/dist/lib/install-daemon/download.js.map +1 -0
- package/dist/lib/install-daemon/errors.d.ts +23 -0
- package/dist/lib/install-daemon/errors.d.ts.map +1 -0
- package/dist/lib/install-daemon/errors.js +42 -0
- package/dist/lib/install-daemon/errors.js.map +1 -0
- package/dist/lib/install-daemon/extract.d.ts +2 -0
- package/dist/lib/install-daemon/extract.d.ts.map +1 -0
- package/dist/lib/install-daemon/extract.js +38 -0
- package/dist/lib/install-daemon/extract.js.map +1 -0
- package/dist/lib/install-daemon/github-api.d.ts +9 -0
- package/dist/lib/install-daemon/github-api.d.ts.map +1 -0
- package/dist/lib/install-daemon/github-api.js +60 -0
- package/dist/lib/install-daemon/github-api.js.map +1 -0
- package/dist/lib/install-daemon/index.d.ts +3 -0
- package/dist/lib/install-daemon/index.d.ts.map +1 -0
- package/dist/lib/install-daemon/index.js +2 -0
- package/dist/lib/install-daemon/index.js.map +1 -0
- package/dist/lib/install-daemon/install-daemon.d.ts +3 -0
- package/dist/lib/install-daemon/install-daemon.d.ts.map +1 -0
- package/dist/lib/install-daemon/install-daemon.js +100 -0
- package/dist/lib/install-daemon/install-daemon.js.map +1 -0
- package/dist/lib/install-daemon/platform.d.ts +3 -0
- package/dist/lib/install-daemon/platform.d.ts.map +1 -0
- package/dist/lib/install-daemon/platform.js +24 -0
- package/dist/lib/install-daemon/platform.js.map +1 -0
- package/dist/lib/install-daemon/types.d.ts +34 -0
- package/dist/lib/install-daemon/types.d.ts.map +1 -0
- package/dist/lib/install-daemon/types.js +7 -0
- package/dist/lib/install-daemon/types.js.map +1 -0
- package/dist/lib/start/daemon-binary-exists.d.ts +2 -0
- package/dist/lib/start/daemon-binary-exists.d.ts.map +1 -0
- package/dist/lib/start/daemon-binary-exists.js +10 -0
- package/dist/lib/start/daemon-binary-exists.js.map +1 -0
- package/dist/lib/start/find-daemon-binary.d.ts +2 -0
- package/dist/lib/start/find-daemon-binary.d.ts.map +1 -0
- package/dist/lib/start/find-daemon-binary.js +31 -0
- package/dist/lib/start/find-daemon-binary.js.map +1 -0
- package/dist/lib/start/wait-for-daemon.d.ts +7 -0
- package/dist/lib/start/wait-for-daemon.d.ts.map +1 -0
- package/dist/lib/start/wait-for-daemon.js +20 -0
- package/dist/lib/start/wait-for-daemon.js.map +1 -0
- package/dist/tui/App.d.ts +6 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +64 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/domain/DaemonPanel.d.ts +2 -0
- package/dist/tui/components/domain/DaemonPanel.d.ts.map +1 -0
- package/dist/tui/components/domain/DaemonPanel.js +35 -0
- package/dist/tui/components/domain/DaemonPanel.js.map +1 -0
- package/dist/tui/components/domain/IssueList.d.ts +2 -0
- package/dist/tui/components/domain/IssueList.d.ts.map +1 -0
- package/dist/tui/components/domain/IssueList.js +52 -0
- package/dist/tui/components/domain/IssueList.js.map +1 -0
- package/dist/tui/components/domain/ProjectList.d.ts +2 -0
- package/dist/tui/components/domain/ProjectList.d.ts.map +1 -0
- package/dist/tui/components/domain/ProjectList.js +54 -0
- package/dist/tui/components/domain/ProjectList.js.map +1 -0
- package/dist/tui/components/layout/Header.d.ts +7 -0
- package/dist/tui/components/layout/Header.d.ts.map +1 -0
- package/dist/tui/components/layout/Header.js +7 -0
- package/dist/tui/components/layout/Header.js.map +1 -0
- package/dist/tui/components/layout/MainPanel.d.ts +8 -0
- package/dist/tui/components/layout/MainPanel.d.ts.map +1 -0
- package/dist/tui/components/layout/MainPanel.js +5 -0
- package/dist/tui/components/layout/MainPanel.js.map +1 -0
- package/dist/tui/components/layout/Sidebar.d.ts +9 -0
- package/dist/tui/components/layout/Sidebar.d.ts.map +1 -0
- package/dist/tui/components/layout/Sidebar.js +11 -0
- package/dist/tui/components/layout/Sidebar.js.map +1 -0
- package/dist/tui/components/layout/StatusBar.d.ts +11 -0
- package/dist/tui/components/layout/StatusBar.d.ts.map +1 -0
- package/dist/tui/components/layout/StatusBar.js +8 -0
- package/dist/tui/components/layout/StatusBar.js.map +1 -0
- package/dist/tui/hooks/useDaemonActions.d.ts +12 -0
- package/dist/tui/hooks/useDaemonActions.d.ts.map +1 -0
- package/dist/tui/hooks/useDaemonActions.js +77 -0
- package/dist/tui/hooks/useDaemonActions.js.map +1 -0
- package/dist/tui/hooks/useDaemonConnection.d.ts +5 -0
- package/dist/tui/hooks/useDaemonConnection.d.ts.map +1 -0
- package/dist/tui/hooks/useDaemonConnection.js +24 -0
- package/dist/tui/hooks/useDaemonConnection.js.map +1 -0
- package/dist/tui/hooks/useDaemonInfo.d.ts +10 -0
- package/dist/tui/hooks/useDaemonInfo.d.ts.map +1 -0
- package/dist/tui/hooks/useDaemonInfo.js +26 -0
- package/dist/tui/hooks/useDaemonInfo.js.map +1 -0
- package/dist/tui/hooks/useIssues.d.ts +8 -0
- package/dist/tui/hooks/useIssues.d.ts.map +1 -0
- package/dist/tui/hooks/useIssues.js +36 -0
- package/dist/tui/hooks/useIssues.js.map +1 -0
- package/dist/tui/hooks/useNavigation.d.ts +11 -0
- package/dist/tui/hooks/useNavigation.d.ts.map +1 -0
- package/dist/tui/hooks/useNavigation.js +24 -0
- package/dist/tui/hooks/useNavigation.js.map +1 -0
- package/dist/tui/hooks/useProjects.d.ts +8 -0
- package/dist/tui/hooks/useProjects.d.ts.map +1 -0
- package/dist/tui/hooks/useProjects.js +36 -0
- package/dist/tui/hooks/useProjects.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +39 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/services/daemon-service.d.ts +28 -0
- package/dist/tui/services/daemon-service.d.ts.map +1 -0
- package/dist/tui/services/daemon-service.js +107 -0
- package/dist/tui/services/daemon-service.js.map +1 -0
- package/dist/tui/state/app-state.d.ts +78 -0
- package/dist/tui/state/app-state.d.ts.map +1 -0
- package/dist/tui/state/app-state.js +93 -0
- package/dist/tui/state/app-state.js.map +1 -0
- package/dist/tui/types/views.d.ts +11 -0
- package/dist/tui/types/views.d.ts.map +1 -0
- package/dist/tui/types/views.js +25 -0
- package/dist/tui/types/views.js.map +1 -0
- package/oclif.manifest.json +83 -1
- package/package.json +10 -3
package/README.md
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Centy CLI
|
|
2
|
+
|
|
3
|
+
CLI for managing project issues and docs via code in the `.centy` folder. Local-first, git-friendly issue and documentation tracking.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Using npm
|
|
9
|
+
npm install -g centy
|
|
10
|
+
|
|
11
|
+
# Using pnpm
|
|
12
|
+
pnpm add -g centy
|
|
13
|
+
|
|
14
|
+
# Or run directly with npx/pnpm dlx
|
|
15
|
+
pnpm dlx centy
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Install the Daemon
|
|
19
|
+
|
|
20
|
+
The CLI requires the centy daemon to be running. Install it with:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Install latest version
|
|
24
|
+
centy install daemon
|
|
25
|
+
|
|
26
|
+
# Install specific version
|
|
27
|
+
centy install daemon --version 0.1.0
|
|
28
|
+
|
|
29
|
+
# Force reinstall
|
|
30
|
+
centy install daemon --force
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Install the daemon (first time only)
|
|
37
|
+
centy install daemon
|
|
38
|
+
|
|
39
|
+
# Start the daemon
|
|
40
|
+
centy start
|
|
41
|
+
|
|
42
|
+
# Initialize centy in your project
|
|
43
|
+
centy init
|
|
44
|
+
|
|
45
|
+
# Create an issue
|
|
46
|
+
centy create issue --title "Fix login bug" --priority high
|
|
47
|
+
|
|
48
|
+
# List issues
|
|
49
|
+
centy list issues
|
|
50
|
+
|
|
51
|
+
# Open interactive TUI mode
|
|
52
|
+
centy
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Interactive TUI Mode
|
|
56
|
+
|
|
57
|
+
Running `centy` without any arguments opens a full-screen interactive terminal UI:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
┌─────────────────────────────────────────────────────┐
|
|
61
|
+
│ Centy ● Daemon: Connected │
|
|
62
|
+
├──────────────┬──────────────────────────────────────┤
|
|
63
|
+
│ Projects │ │
|
|
64
|
+
│ > Issues │ Issue List │
|
|
65
|
+
│ Docs │ ───────────────────────── │
|
|
66
|
+
│ Assets │ #1 [high] Fix login bug │
|
|
67
|
+
│ Config │ #2 [med] Add dark mode │
|
|
68
|
+
│ Daemon │ #3 [low] Update docs │
|
|
69
|
+
├──────────────┴──────────────────────────────────────┤
|
|
70
|
+
│ j/k: navigate Enter: select Tab: switch view q: quit │
|
|
71
|
+
└─────────────────────────────────────────────────────┘
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### TUI Keyboard Shortcuts
|
|
75
|
+
|
|
76
|
+
| Key | Action |
|
|
77
|
+
| --------- | ---------------------- |
|
|
78
|
+
| `j` / `↓` | Move down |
|
|
79
|
+
| `k` / `↑` | Move up |
|
|
80
|
+
| `Enter` | Select item |
|
|
81
|
+
| `Tab` | Switch view |
|
|
82
|
+
| `1-6` | Quick navigate to view |
|
|
83
|
+
| `q` | Quit |
|
|
84
|
+
|
|
85
|
+
## Commands
|
|
86
|
+
|
|
87
|
+
### Project Management
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Initialize a .centy folder
|
|
91
|
+
centy init
|
|
92
|
+
|
|
93
|
+
# Initialize with defaults (skip prompts)
|
|
94
|
+
centy init --force
|
|
95
|
+
|
|
96
|
+
# Register a project for tracking
|
|
97
|
+
centy register project
|
|
98
|
+
|
|
99
|
+
# Remove a project from tracking
|
|
100
|
+
centy untrack project
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Issues
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Create an issue (interactive prompts for missing fields)
|
|
107
|
+
centy create issue
|
|
108
|
+
|
|
109
|
+
# Create an issue with all options
|
|
110
|
+
centy create issue --title "Bug fix" --description "Fix the bug" --priority high --status open
|
|
111
|
+
|
|
112
|
+
# Short flags
|
|
113
|
+
centy create issue -t "Bug fix" -d "Description" -p high -s open
|
|
114
|
+
|
|
115
|
+
# List all issues
|
|
116
|
+
centy list issues
|
|
117
|
+
|
|
118
|
+
# Get a specific issue by display number or UUID
|
|
119
|
+
centy get issue 1
|
|
120
|
+
centy get issue abc123-uuid
|
|
121
|
+
|
|
122
|
+
# Update an issue
|
|
123
|
+
centy update issue 1 --status closed
|
|
124
|
+
centy update issue 1 --title "New title" --priority high
|
|
125
|
+
centy update issue 1 -s in-progress
|
|
126
|
+
|
|
127
|
+
# Delete an issue
|
|
128
|
+
centy delete issue 1
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Priority levels:** `low`, `medium`, `high`
|
|
132
|
+
**Default statuses:** `open`, `in-progress`, `closed`
|
|
133
|
+
|
|
134
|
+
### Documentation
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Create a doc (title required)
|
|
138
|
+
centy create doc --title "Getting Started"
|
|
139
|
+
|
|
140
|
+
# Create with content and custom slug
|
|
141
|
+
centy create doc --title "API Reference" --content "# API\nDocumentation here"
|
|
142
|
+
centy create doc --title "Guide" --slug my-custom-slug
|
|
143
|
+
|
|
144
|
+
# Use a template
|
|
145
|
+
centy create doc --title "New Feature" --template feature
|
|
146
|
+
|
|
147
|
+
# List all docs
|
|
148
|
+
centy list docs
|
|
149
|
+
|
|
150
|
+
# Get a specific doc by slug
|
|
151
|
+
centy get doc getting-started
|
|
152
|
+
|
|
153
|
+
# Update a doc
|
|
154
|
+
centy update doc getting-started
|
|
155
|
+
|
|
156
|
+
# Delete a doc
|
|
157
|
+
centy delete doc getting-started
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Assets
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Add an asset to an issue
|
|
164
|
+
centy add asset ./screenshot.png --issue 1
|
|
165
|
+
|
|
166
|
+
# Add with custom filename
|
|
167
|
+
centy add asset ./image.jpg --issue 1 --name my-image.jpg
|
|
168
|
+
|
|
169
|
+
# Add a shared asset (accessible by all issues)
|
|
170
|
+
centy add asset ./logo.png --shared
|
|
171
|
+
|
|
172
|
+
# List assets for an issue
|
|
173
|
+
centy list assets --issue 1
|
|
174
|
+
|
|
175
|
+
# List shared assets
|
|
176
|
+
centy list assets --shared
|
|
177
|
+
|
|
178
|
+
# Get an asset and save to file
|
|
179
|
+
centy get asset <asset-id> --output ./downloaded.png
|
|
180
|
+
|
|
181
|
+
# Delete an asset
|
|
182
|
+
centy delete asset <asset-id>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Daemon Management
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Install the daemon
|
|
189
|
+
centy install daemon
|
|
190
|
+
centy install daemon --version 0.1.0
|
|
191
|
+
centy install daemon --force
|
|
192
|
+
|
|
193
|
+
# Start the daemon
|
|
194
|
+
centy start
|
|
195
|
+
|
|
196
|
+
# Start in foreground (blocks terminal, useful for debugging)
|
|
197
|
+
centy start --foreground
|
|
198
|
+
|
|
199
|
+
# Get daemon info
|
|
200
|
+
centy info
|
|
201
|
+
|
|
202
|
+
# Restart the daemon
|
|
203
|
+
centy restart
|
|
204
|
+
|
|
205
|
+
# Shutdown the daemon gracefully
|
|
206
|
+
centy shutdown
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Project Info
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Get project configuration
|
|
213
|
+
centy config
|
|
214
|
+
centy config --json
|
|
215
|
+
|
|
216
|
+
# Get project manifest
|
|
217
|
+
centy manifest
|
|
218
|
+
|
|
219
|
+
# Get version info
|
|
220
|
+
centy version
|
|
221
|
+
|
|
222
|
+
# List all tracked projects
|
|
223
|
+
centy list projects
|
|
224
|
+
|
|
225
|
+
# Get info about a specific project
|
|
226
|
+
centy get project
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Migrations
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Update project to latest version (runs migrations)
|
|
233
|
+
centy update
|
|
234
|
+
|
|
235
|
+
# Update to a specific version
|
|
236
|
+
centy update --target 0.2.0
|
|
237
|
+
|
|
238
|
+
# Force update without confirmation
|
|
239
|
+
centy update --force
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## The .centy Folder
|
|
243
|
+
|
|
244
|
+
Centy stores all project data in a `.centy` folder that you can commit to git:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
.centy/
|
|
248
|
+
├── .centy-manifest.json # Project manifest with file hashes
|
|
249
|
+
├── config.json # Project configuration
|
|
250
|
+
├── README.md # Project README
|
|
251
|
+
├── issues/ # Issue files
|
|
252
|
+
│ └── <uuid>/
|
|
253
|
+
│ ├── issue.md # Issue content (markdown)
|
|
254
|
+
│ ├── metadata.json # Issue metadata (status, priority, timestamps)
|
|
255
|
+
│ └── assets/ # Issue-specific assets
|
|
256
|
+
├── docs/ # Documentation files
|
|
257
|
+
│ └── <slug>/
|
|
258
|
+
│ ├── doc.md # Doc content (markdown)
|
|
259
|
+
│ └── metadata.json # Doc metadata
|
|
260
|
+
└── assets/ # Shared assets (accessible by all issues)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
All files are human-readable markdown and JSON, making them easy to review in PRs and track in version control.
|
|
264
|
+
|
|
265
|
+
## Requirements
|
|
266
|
+
|
|
267
|
+
- Node.js >= 20.0.0
|
|
268
|
+
- Centy Daemon (install with `centy install daemon`)
|
|
269
|
+
|
|
270
|
+
### Supported Platforms
|
|
271
|
+
|
|
272
|
+
The daemon supports:
|
|
273
|
+
- macOS (Intel & Apple Silicon)
|
|
274
|
+
- Linux (x86_64 & ARM64)
|
|
275
|
+
- Windows (x86_64)
|
|
276
|
+
|
|
277
|
+
## Development
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Clone the repository
|
|
281
|
+
git clone https://github.com/centy-io/centy-cli.git
|
|
282
|
+
cd centy-cli
|
|
283
|
+
|
|
284
|
+
# Install dependencies
|
|
285
|
+
pnpm install
|
|
286
|
+
|
|
287
|
+
# Build
|
|
288
|
+
pnpm build
|
|
289
|
+
|
|
290
|
+
# Run tests
|
|
291
|
+
pnpm test
|
|
292
|
+
|
|
293
|
+
# Run the CLI locally
|
|
294
|
+
./bin/run.js --help
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## License
|
|
298
|
+
|
|
299
|
+
MIT
|
package/bin/run.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
import { execute } from '@oclif/core'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Check if running with no arguments (or just --interactive flag)
|
|
5
|
+
const args = process.argv.slice(2)
|
|
6
|
+
const hasCommand = args.length > 0 && !args[0].startsWith('-')
|
|
7
|
+
const isHelp = args.includes('--help') || args.includes('-h')
|
|
8
|
+
const isInteractive = args.includes('--interactive') || args.includes('-i')
|
|
9
|
+
|
|
10
|
+
// Launch TUI mode if no command provided (or explicit --interactive flag)
|
|
11
|
+
if ((!hasCommand && !isHelp) || isInteractive) {
|
|
12
|
+
const { startTUI } = await import('../dist/tui/index.js')
|
|
13
|
+
await startTUI()
|
|
14
|
+
} else {
|
|
15
|
+
await execute({ dir: import.meta.url })
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class InstallDaemon extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
version: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
'skip-checksum': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/commands/install/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAI5C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,QAAQ,WAKvB;IAED,OAAgB,KAAK;;;;MAcpB;IAEY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBlC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { installDaemon } from '../../lib/install-daemon/index.js';
|
|
3
|
+
export default class InstallDaemon extends Command {
|
|
4
|
+
static description = 'Download and install the centy daemon binary';
|
|
5
|
+
static examples = [
|
|
6
|
+
'<%= config.bin %> install daemon',
|
|
7
|
+
'<%= config.bin %> install daemon --version 0.1.0',
|
|
8
|
+
'<%= config.bin %> install daemon --force',
|
|
9
|
+
'<%= config.bin %> install daemon --skip-checksum',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
version: Flags.string({
|
|
13
|
+
char: 'v',
|
|
14
|
+
description: 'Specific version to install (default: latest)',
|
|
15
|
+
}),
|
|
16
|
+
force: Flags.boolean({
|
|
17
|
+
char: 'f',
|
|
18
|
+
description: 'Force reinstall even if already installed',
|
|
19
|
+
default: false,
|
|
20
|
+
}),
|
|
21
|
+
'skip-checksum': Flags.boolean({
|
|
22
|
+
description: 'Skip SHA256 checksum verification',
|
|
23
|
+
default: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { flags } = await this.parse(InstallDaemon);
|
|
28
|
+
const result = await installDaemon({
|
|
29
|
+
version: flags.version,
|
|
30
|
+
force: flags.force,
|
|
31
|
+
skipChecksum: flags['skip-checksum'],
|
|
32
|
+
log: msg => this.log(msg),
|
|
33
|
+
warn: msg => this.warn(msg),
|
|
34
|
+
});
|
|
35
|
+
if (!result.success) {
|
|
36
|
+
this.error(result.error ?? 'Failed to install daemon');
|
|
37
|
+
}
|
|
38
|
+
this.log(`Daemon ${result.version} installed successfully to ${result.installPath}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/commands/install/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AAEjE,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAU,WAAW,GAAG,8CAA8C,CAAA;IAE5E,MAAM,CAAU,QAAQ,GAAG;QACzB,kCAAkC;QAClC,kDAAkD;QAClD,0CAA0C;QAC1C,kDAAkD;KACnD,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,+CAA+C;SAC7D,CAAC;QACF,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,2CAA2C;YACxD,OAAO,EAAE,KAAK;SACf,CAAC;QACF,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC;YAC7B,WAAW,EAAE,mCAAmC;YAChD,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAA;IAEM,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAEjD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;YACjC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC;YACpC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACzB,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SAC5B,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,CAAC,GAAG,CACN,UAAU,MAAM,CAAC,OAAO,8BAA8B,MAAM,CAAC,WAAW,EAAE,CAC3E,CAAA;IACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAI5C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,OAAgB,WAAW,SAAyC;IAEpE,OAAgB,QAAQ,WAGvB;IAED,OAAgB,KAAK;;MAMpB;IAEY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAI5C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,OAAgB,WAAW,SAAyC;IAEpE,OAAgB,QAAQ,WAGvB;IAED,OAAgB,KAAK;;MAMpB;IAEY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA4BlC"}
|
|
@@ -29,6 +29,11 @@ export default class Shutdown extends Command {
|
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
31
|
const msg = error instanceof Error ? error.message : String(error);
|
|
32
|
+
// CANCELLED error means daemon shut down before responding - this is success
|
|
33
|
+
if (msg.includes('CANCELLED')) {
|
|
34
|
+
this.log('Daemon shutdown initiated');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
32
37
|
if (msg.includes('UNAVAILABLE') || msg.includes('ECONNREFUSED')) {
|
|
33
38
|
this.error('Centy daemon is not running. Please start the daemon first.');
|
|
34
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAU,WAAW,GAAG,sCAAsC,CAAA;IAEpE,MAAM,CAAU,QAAQ,GAAG;QACzB,4BAA4B;QAC5B,sCAAsC;KACvC,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,kCAAkC;YAC/C,OAAO,EAAE,CAAC;SACX,CAAC;KACH,CAAA;IAEM,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAE5C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC;gBACpC,YAAY,EAAE,KAAK,CAAC,KAAK;aAC1B,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC9B,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAA;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAClE,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBAChE,IAAI,CAAC,KAAK,CACR,6DAA6D,CAC9D,CAAA;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;IACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/commands/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAE7D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAU,WAAW,GAAG,sCAAsC,CAAA;IAEpE,MAAM,CAAU,QAAQ,GAAG;QACzB,4BAA4B;QAC5B,sCAAsC;KACvC,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,kCAAkC;YAC/C,OAAO,EAAE,CAAC;SACX,CAAC;KACH,CAAA;IAEM,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAE5C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC;gBACpC,YAAY,EAAE,KAAK,CAAC,KAAK;aAC1B,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC9B,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,2BAA2B,CAAC,CAAA;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAClE,6EAA6E;YAC7E,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;gBACrC,OAAM;YACR,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBAChE,IAAI,CAAC,KAAK,CACR,6DAA6D,CAC9D,CAAA;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Start extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
foreground: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
private startForeground;
|
|
10
|
+
private startBackground;
|
|
11
|
+
private handleSpawnError;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAO5C,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,OAAO;IACxC,OAAgB,WAAW,SAA2B;IAEtD,OAAgB,QAAQ,WAIvB;IAED,OAAgB,KAAK;;MAMpB;IAEY,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAqBnB,eAAe;YAoBf,eAAe;IAqB7B,OAAO,CAAC,gBAAgB;CASzB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { Command, Flags } from '@oclif/core';
|
|
3
|
+
import { checkDaemonConnection } from '../daemon/check-daemon-connection.js';
|
|
4
|
+
import { daemonBinaryExists } from '../lib/start/daemon-binary-exists.js';
|
|
5
|
+
import { findDaemonBinary } from '../lib/start/find-daemon-binary.js';
|
|
6
|
+
import { waitForDaemon } from '../lib/start/wait-for-daemon.js';
|
|
7
|
+
export default class Start extends Command {
|
|
8
|
+
static description = 'Start the centy daemon';
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> start',
|
|
11
|
+
'<%= config.bin %> start --foreground',
|
|
12
|
+
'<%= config.bin %> start -f',
|
|
13
|
+
];
|
|
14
|
+
static flags = {
|
|
15
|
+
foreground: Flags.boolean({
|
|
16
|
+
char: 'f',
|
|
17
|
+
description: 'Run daemon in foreground (blocks terminal)',
|
|
18
|
+
default: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async run() {
|
|
22
|
+
const { flags } = await this.parse(Start);
|
|
23
|
+
const status = await checkDaemonConnection();
|
|
24
|
+
if (status.connected) {
|
|
25
|
+
this.log('Daemon is already running');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const daemonPath = findDaemonBinary();
|
|
29
|
+
if (!daemonBinaryExists(daemonPath)) {
|
|
30
|
+
this.error(`Daemon binary not found at: ${daemonPath}`);
|
|
31
|
+
}
|
|
32
|
+
if (flags.foreground) {
|
|
33
|
+
await this.startForeground(daemonPath);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
await this.startBackground(daemonPath);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async startForeground(daemonPath) {
|
|
40
|
+
this.log('Starting daemon in foreground mode...');
|
|
41
|
+
const child = spawn(daemonPath, [], { stdio: 'inherit' });
|
|
42
|
+
child.on('error', error => {
|
|
43
|
+
this.handleSpawnError(error, daemonPath);
|
|
44
|
+
});
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
child.on('exit', code => {
|
|
47
|
+
if (code === 0) {
|
|
48
|
+
resolve();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
reject(new Error(`Daemon exited with code ${code}`));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async startBackground(daemonPath) {
|
|
57
|
+
this.log('Starting daemon in background...');
|
|
58
|
+
const child = spawn(daemonPath, [], { detached: true, stdio: 'ignore' });
|
|
59
|
+
child.on('error', error => {
|
|
60
|
+
this.handleSpawnError(error, daemonPath);
|
|
61
|
+
});
|
|
62
|
+
child.unref();
|
|
63
|
+
const started = await waitForDaemon();
|
|
64
|
+
if (started) {
|
|
65
|
+
this.log('Daemon started successfully');
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
this.error('Daemon process started but is not responding. Check daemon logs for errors.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
handleSpawnError(error, daemonPath) {
|
|
72
|
+
if (error.code === 'ENOENT') {
|
|
73
|
+
this.error(`Could not find centy-daemon binary at: ${daemonPath}. ` +
|
|
74
|
+
'Make sure the daemon is built and accessible.');
|
|
75
|
+
}
|
|
76
|
+
this.error(`Failed to start daemon: ${error.message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/prerun.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { checkDaemonConnection } from '../daemon/check-daemon-connection.js';
|
|
2
|
-
const EXCLUDED_COMMANDS = ['info', 'shutdown', 'restart'];
|
|
2
|
+
const EXCLUDED_COMMANDS = ['info', 'shutdown', 'restart', 'start', 'install'];
|
|
3
3
|
const hook = async function (options) {
|
|
4
4
|
if (EXCLUDED_COMMANDS.includes(options.Command.id)) {
|
|
5
5
|
return;
|
package/dist/hooks/prerun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAE5E,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAE5E,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;AAE7E,MAAM,IAAI,GAAmB,KAAK,WAAW,OAAO;IAClD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACnD,OAAM;IACR,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,EAAE,CAAA;IACtD,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,YAAY,GAChB,gBAAgB,CAAC,KAAK,KAAK,IAAI,IAAI,gBAAgB,CAAC,KAAK,KAAK,SAAS;YACrE,CAAC,CAAC,gBAAgB,CAAC,KAAK;YACxB,CAAC,CAAC,6DAA6D,CAAA;QACnE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.d.ts","sourceRoot":"","sources":["../../../src/lib/install-daemon/checksum.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAkBlB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
import { ChecksumNotFoundError } from './errors.js';
|
|
4
|
+
export async function verifyChecksum(filePath, fileName, checksumContent) {
|
|
5
|
+
const lines = checksumContent.trim().split('\n');
|
|
6
|
+
const checksumMap = new Map();
|
|
7
|
+
for (const line of lines) {
|
|
8
|
+
const match = line.match(/^([a-f0-9]{64})\s+(.+)$/);
|
|
9
|
+
if (match) {
|
|
10
|
+
checksumMap.set(match[2], match[1]);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const expectedHash = checksumMap.get(fileName);
|
|
14
|
+
if (!expectedHash) {
|
|
15
|
+
throw new ChecksumNotFoundError(fileName);
|
|
16
|
+
}
|
|
17
|
+
const actualHash = await calculateSha256(filePath);
|
|
18
|
+
return actualHash === expectedHash;
|
|
19
|
+
}
|
|
20
|
+
async function calculateSha256(filePath) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const hash = createHash('sha256');
|
|
23
|
+
const stream = createReadStream(filePath);
|
|
24
|
+
stream.on('data', chunk => {
|
|
25
|
+
hash.update(chunk);
|
|
26
|
+
});
|
|
27
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
28
|
+
stream.on('error', reject);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.js","sourceRoot":"","sources":["../../../src/lib/install-daemon/checksum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,QAAgB,EAChB,eAAuB;IAEvB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;QACnD,IAAI,KAAK,EAAE,CAAC;YACV,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,qBAAqB,CAAC,QAAQ,CAAC,CAAA;IAC3C,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAA;IAClD,OAAO,UAAU,KAAK,YAAY,CAAA;AACpC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,QAAgB;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;QACjC,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;QAEzC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;YACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GithubRelease } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Download operations for daemon installation
|
|
4
|
+
* Multiple exports allowed for related download operations
|
|
5
|
+
*/
|
|
6
|
+
export declare function downloadAsset(url: string, destPath: string): Promise<void>;
|
|
7
|
+
export declare function downloadChecksums(release: GithubRelease): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/lib/install-daemon/download.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* eslint-disable single-export/single-export */
|
|
2
|
+
import { createWriteStream } from 'node:fs';
|
|
3
|
+
import { pipeline } from 'node:stream/promises';
|
|
4
|
+
import { Readable } from 'node:stream';
|
|
5
|
+
import { DownloadError } from './errors.js';
|
|
6
|
+
/**
|
|
7
|
+
* Download operations for daemon installation
|
|
8
|
+
* Multiple exports allowed for related download operations
|
|
9
|
+
*/
|
|
10
|
+
export async function downloadAsset(url, destPath) {
|
|
11
|
+
const response = await fetch(url, {
|
|
12
|
+
headers: {
|
|
13
|
+
'User-Agent': 'centy-cli',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new DownloadError(`Failed to download: ${response.status} ${response.statusText}`);
|
|
18
|
+
}
|
|
19
|
+
if (!response.body) {
|
|
20
|
+
throw new DownloadError('No response body');
|
|
21
|
+
}
|
|
22
|
+
const fileStream = createWriteStream(destPath);
|
|
23
|
+
await pipeline(Readable.fromWeb(response.body), fileStream);
|
|
24
|
+
}
|
|
25
|
+
export async function downloadChecksums(release) {
|
|
26
|
+
const checksumAsset = release.assets.find(a => a.name === 'checksums-sha256.txt');
|
|
27
|
+
if (!checksumAsset) {
|
|
28
|
+
throw new DownloadError('Checksum file not found in release');
|
|
29
|
+
}
|
|
30
|
+
const response = await fetch(checksumAsset.browser_download_url, {
|
|
31
|
+
headers: {
|
|
32
|
+
'User-Agent': 'centy-cli',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new DownloadError(`Failed to download checksums: ${response.status}`);
|
|
37
|
+
}
|
|
38
|
+
return response.text();
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/lib/install-daemon/download.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,QAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO,EAAE;YACP,YAAY,EAAE,WAAW;SAC1B;KACF,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,aAAa,CACrB,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAChE,CAAA;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC,CAAA;IAC7C,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC9C,MAAM,QAAQ,CACZ,QAAQ,CAAC,OAAO,CACd,QAAQ,CAAC,IAAyD,CACnE,EACD,UAAU,CACX,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAsB;IAEtB,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,sBAAsB,CACvC,CAAA;IACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,aAAa,CAAC,oCAAoC,CAAC,CAAA;IAC/D,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,oBAAoB,EAAE;QAC/D,OAAO,EAAE;YACP,YAAY,EAAE,WAAW;SAC1B;KACF,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,aAAa,CAAC,iCAAiC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for install-daemon module
|
|
3
|
+
* Multiple exports allowed for related error class hierarchy
|
|
4
|
+
*/
|
|
5
|
+
export declare class InstallDaemonError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class PlatformNotSupportedError extends InstallDaemonError {
|
|
9
|
+
constructor(platform: string, arch: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class ChecksumNotFoundError extends InstallDaemonError {
|
|
12
|
+
constructor(fileName: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class DownloadError extends InstallDaemonError {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class ReleaseNotFoundError extends InstallDaemonError {
|
|
18
|
+
constructor(version: string);
|
|
19
|
+
}
|
|
20
|
+
export declare class GithubApiError extends InstallDaemonError {
|
|
21
|
+
constructor(message: string);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/lib/install-daemon/errors.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,yBAA0B,SAAQ,kBAAkB;gBACnD,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAI3C;AAED,qBAAa,qBAAsB,SAAQ,kBAAkB;gBAC/C,QAAQ,EAAE,MAAM;CAI7B;AAED,qBAAa,aAAc,SAAQ,kBAAkB;gBACvC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,oBAAqB,SAAQ,kBAAkB;gBAC9C,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,cAAe,SAAQ,kBAAkB;gBACxC,OAAO,EAAE,MAAM;CAI5B"}
|