yougile-cli 0.8.2
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/LICENSE +21 -0
- package/README.md +320 -0
- package/bin/yougile.js +17 -0
- package/package.json +67 -0
- package/scripts/build.ts +74 -0
- package/scripts/postinstall.js +95 -0
- package/yougile.config.schema.json +29 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 RainyPixel
|
|
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,320 @@
|
|
|
1
|
+
# YouGile Toolkit
|
|
2
|
+
|
|
3
|
+
CLI утилита для работы с [YouGile API](https://ru.yougile.com/) из командной строки.
|
|
4
|
+
|
|
5
|
+
## Особенности
|
|
6
|
+
|
|
7
|
+
- **Standalone бинарник** — работает без Node.js/Bun
|
|
8
|
+
- **Алиасы** — используйте имена колонок и стикеров вместо UUID
|
|
9
|
+
- **Markdown** — описания в Markdown автоматически конвертируются в HTML
|
|
10
|
+
- **Шаблоны** — создавайте задачи из YAML-шаблонов
|
|
11
|
+
- **Интерактивный режим** — удобный wizard для создания задач
|
|
12
|
+
- **Автообновление** — команда `upgrade` для обновления CLI
|
|
13
|
+
- **Чеклисты** — текстовый и JSON форматы
|
|
14
|
+
- **Дедлайны** — поддержка нескольких форматов дат
|
|
15
|
+
- **Спринты** — создание и управление стикерами спринтов
|
|
16
|
+
- **Загрузка файлов** — прикрепление к задачам
|
|
17
|
+
- **Scope система** — фильтрация по проектам и доскам
|
|
18
|
+
|
|
19
|
+
## Установка
|
|
20
|
+
|
|
21
|
+
### npm (рекомендуется)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g yougile-cli
|
|
25
|
+
# или
|
|
26
|
+
bun install -g yougile-cli
|
|
27
|
+
# или
|
|
28
|
+
pnpm install -g yougile-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### npx (без установки)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx yougile-cli --help
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Обновление
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm update -g yougile-cli
|
|
41
|
+
# или
|
|
42
|
+
yougile upgrade
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Быстрый старт
|
|
46
|
+
|
|
47
|
+
### 1. Инициализация
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yougile setup
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Создаст файл `yougile.config.json` и добавит его в `.gitignore`.
|
|
54
|
+
|
|
55
|
+
### 2. Настройка конфигурации
|
|
56
|
+
|
|
57
|
+
Отредактируйте `yougile.config.json`:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"companyId": "ваш-company-id",
|
|
62
|
+
"userId": "ваш-email@example.com",
|
|
63
|
+
"userPassword": "ваш-пароль"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> **Где найти `companyId`?**
|
|
68
|
+
> В URL вашего YouGile: `https://ru.yougile.com/team/{companyId}/...`
|
|
69
|
+
|
|
70
|
+
### 3. Получение API ключа
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
yougile auth
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Синхронизация алиасов
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
yougile sync
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Это загрузит названия колонок и стикеров, чтобы вы могли использовать их вместо UUID.
|
|
83
|
+
|
|
84
|
+
## Использование
|
|
85
|
+
|
|
86
|
+
### Интерактивный режим
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
yougile i
|
|
90
|
+
# или
|
|
91
|
+
yougile interactive
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Wizard для создания задач с выбором колонок, стикеров и шаблонов.
|
|
95
|
+
|
|
96
|
+
### Создание задач
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Базовое создание (с алиасами)
|
|
100
|
+
yougile create --title "Моя задача" --column "В работе"
|
|
101
|
+
|
|
102
|
+
# С описанием в Markdown
|
|
103
|
+
yougile create --title "Задача" --column "В работе" \
|
|
104
|
+
--description "## Описание\n- Пункт 1\n- Пункт 2"
|
|
105
|
+
|
|
106
|
+
# Со стикерами (по имени)
|
|
107
|
+
yougile create --title "Баг" --column "В работе" \
|
|
108
|
+
--priority "P-1" --type "Bug"
|
|
109
|
+
|
|
110
|
+
# Из шаблона
|
|
111
|
+
yougile create --template bugfix --title "Fix crash"
|
|
112
|
+
|
|
113
|
+
# С чеклистом
|
|
114
|
+
yougile create --title "Задача" --column "В работе" \
|
|
115
|
+
--checklist "TODO:[ ] Написать код:[x] Тесты"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Работа с задачами
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Список задач
|
|
122
|
+
yougile list
|
|
123
|
+
yougile list --column "В работе"
|
|
124
|
+
|
|
125
|
+
# Получить задачу
|
|
126
|
+
yougile get "task-id"
|
|
127
|
+
|
|
128
|
+
# Переместить
|
|
129
|
+
yougile move "task-id" "Готово"
|
|
130
|
+
|
|
131
|
+
# Обновить
|
|
132
|
+
yougile update "task-id" --complete
|
|
133
|
+
yougile update "task-id" --title "Новое название"
|
|
134
|
+
yougile update "task-id" --deadline "2025-12-31"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Шаблоны
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Создать примеры шаблонов
|
|
141
|
+
yougile template init
|
|
142
|
+
|
|
143
|
+
# Список шаблонов
|
|
144
|
+
yougile template list
|
|
145
|
+
|
|
146
|
+
# Показать шаблон
|
|
147
|
+
yougile template show bugfix
|
|
148
|
+
|
|
149
|
+
# Использовать шаблон
|
|
150
|
+
yougile create --template bugfix --title "Fix bug"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Шаблоны хранятся в YAML:
|
|
154
|
+
- `.yougile/templates/` — локальные (приоритет)
|
|
155
|
+
- `~/.config/yougile-toolkit/templates/` — глобальные
|
|
156
|
+
|
|
157
|
+
Пример шаблона (`bugfix.yaml`):
|
|
158
|
+
```yaml
|
|
159
|
+
name: bugfix
|
|
160
|
+
description: Шаблон для багфиксов
|
|
161
|
+
defaults:
|
|
162
|
+
stickers:
|
|
163
|
+
Priority: P-2
|
|
164
|
+
Type: Bug
|
|
165
|
+
checklist:
|
|
166
|
+
name: Bug Fix
|
|
167
|
+
items:
|
|
168
|
+
- Воспроизвести баг
|
|
169
|
+
- Написать тест
|
|
170
|
+
- Исправить
|
|
171
|
+
- Проверить
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Scope: Фильтрация по проекту/доске
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Показать проекты
|
|
178
|
+
yougile select-scope --list-projects
|
|
179
|
+
|
|
180
|
+
# Установить scope на проект
|
|
181
|
+
yougile select-scope --project "project-id"
|
|
182
|
+
|
|
183
|
+
# Установить scope на доску
|
|
184
|
+
yougile select-scope --board "board-id"
|
|
185
|
+
|
|
186
|
+
# Сбросить scope
|
|
187
|
+
yougile select-scope --reset
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Спринты
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Список спринтов
|
|
194
|
+
yougile sprint list
|
|
195
|
+
|
|
196
|
+
# Создать стикер спринтов
|
|
197
|
+
yougile sprint create --name "Спринты команды"
|
|
198
|
+
|
|
199
|
+
# Добавить спринт
|
|
200
|
+
yougile sprint add "sticker-id" --name "Sprint 1" \
|
|
201
|
+
--begin "2025-01-01" --end "2025-01-31"
|
|
202
|
+
|
|
203
|
+
# Обновить спринт
|
|
204
|
+
yougile sprint update "sticker-id" "sprint-id" --name "Sprint 1 Updated"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Файлы
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Загрузить файл
|
|
211
|
+
yougile upload "./document.pdf"
|
|
212
|
+
|
|
213
|
+
# Создать задачу с файлом
|
|
214
|
+
yougile create --title "Задача" --column "В работе" --attach "./file.pdf"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Синхронизация и обновление
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Синхронизировать алиасы
|
|
221
|
+
yougile sync
|
|
222
|
+
|
|
223
|
+
# Проверить обновления
|
|
224
|
+
yougile upgrade --check
|
|
225
|
+
|
|
226
|
+
# Обновить CLI
|
|
227
|
+
yougile upgrade
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Форматы
|
|
231
|
+
|
|
232
|
+
### Чеклисты
|
|
233
|
+
|
|
234
|
+
**Текстовый формат (рекомендуется):**
|
|
235
|
+
```bash
|
|
236
|
+
--checklist "TODO:[ ] Пункт 1:[x] Пункт 2"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
- `[ ]` — невыполненный
|
|
240
|
+
- `[x]` — выполненный
|
|
241
|
+
- `||` — разделитель между списками
|
|
242
|
+
|
|
243
|
+
### Даты
|
|
244
|
+
|
|
245
|
+
Поддерживаемые форматы:
|
|
246
|
+
- `YYYY-MM-DD` (2025-01-31)
|
|
247
|
+
- `DD.MM.YYYY` (31.01.2025)
|
|
248
|
+
- `YYYY-MM-DD HH:MM` (2025-01-31 23:59)
|
|
249
|
+
|
|
250
|
+
### Стикеры
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# По имени (рекомендуется, после yougile sync)
|
|
254
|
+
--priority "P-1" --type "Bug"
|
|
255
|
+
|
|
256
|
+
# Универсальный формат
|
|
257
|
+
--sticker "Priority=P-1" --sticker "Type=Bug"
|
|
258
|
+
|
|
259
|
+
# JSON (для сложных случаев)
|
|
260
|
+
--stickers '{"sticker-uuid":"state-uuid"}'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Конфигурация
|
|
264
|
+
|
|
265
|
+
### yougile.config.json
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"companyId": "uuid",
|
|
270
|
+
"userId": "email@example.com",
|
|
271
|
+
"userPassword": "password",
|
|
272
|
+
"apiKey": "key",
|
|
273
|
+
"projectId": "optional-project-scope",
|
|
274
|
+
"boardId": "optional-board-scope",
|
|
275
|
+
"aliases": {
|
|
276
|
+
"columns": {"В работе": "uuid"},
|
|
277
|
+
"stickers": {"Priority": {"_id": "uuid", "P-1": "state-uuid"}}
|
|
278
|
+
},
|
|
279
|
+
"settings": {
|
|
280
|
+
"autoSync": true,
|
|
281
|
+
"markdownEnabled": true
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Rate Limiting
|
|
287
|
+
|
|
288
|
+
YouGile API: **50 запросов в минуту** на компанию.
|
|
289
|
+
|
|
290
|
+
## Разработка
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Установить зависимости
|
|
294
|
+
bun install
|
|
295
|
+
|
|
296
|
+
# Запустить CLI в режиме разработки
|
|
297
|
+
bun run dev -- --help
|
|
298
|
+
# или напрямую
|
|
299
|
+
bun src/cli.ts --help
|
|
300
|
+
|
|
301
|
+
# Собрать бинарники
|
|
302
|
+
bun run build
|
|
303
|
+
|
|
304
|
+
# Тесты
|
|
305
|
+
bun test
|
|
306
|
+
|
|
307
|
+
# Проверка типов и линтинг
|
|
308
|
+
bun typecheck
|
|
309
|
+
bun lint
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Лицензия
|
|
313
|
+
|
|
314
|
+
MIT © [RainyPixel](https://gitverse.ru/RainyPixel)
|
|
315
|
+
|
|
316
|
+
## Ссылки
|
|
317
|
+
|
|
318
|
+
- [YouGile API Documentation](https://ru.yougile.com/api-v2)
|
|
319
|
+
- [Gitverse Repository](https://gitverse.ru/onreza/yougile-toolkit)
|
|
320
|
+
- [Issues](https://gitverse.ru/onreza/yougile-toolkit/tasktracker)
|
package/bin/yougile.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
|
+
const { join } = require("path");
|
|
6
|
+
|
|
7
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
8
|
+
const binPath = join(__dirname, "yougile" + ext);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
12
|
+
} catch (err) {
|
|
13
|
+
if (err.status !== undefined) {
|
|
14
|
+
process.exit(err.status);
|
|
15
|
+
}
|
|
16
|
+
throw err;
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yougile-cli",
|
|
3
|
+
"version": "0.8.2",
|
|
4
|
+
"description": "CLI утилита для работы с YouGile API из командной строки",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"yougile",
|
|
7
|
+
"cli",
|
|
8
|
+
"task-management",
|
|
9
|
+
"project-management",
|
|
10
|
+
"api",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://gitverse.ru/onreza/yougile-toolkit",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://gitverse.ru/onreza/yougile-toolkit/tasktracker"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://gitverse.ru/onreza/yougile-toolkit.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "RainyPixel",
|
|
24
|
+
"url": "https://gitverse.ru/RainyPixel"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"bin": {
|
|
28
|
+
"yougile": "bin/yougile.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"bin",
|
|
32
|
+
"yougile.config.schema.json",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"scripts"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"dev": "bun run src/cli.ts",
|
|
39
|
+
"build": "bun run scripts/build.ts",
|
|
40
|
+
"build:native": "bun build src/cli.ts --compile --minify --outfile=dist/yougile",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"lint": "biome check",
|
|
43
|
+
"lint:fix": "biome check --write",
|
|
44
|
+
"format": "biome format --write",
|
|
45
|
+
"test": "bun test",
|
|
46
|
+
"postinstall": "node scripts/postinstall.js",
|
|
47
|
+
"release": "onreza-release",
|
|
48
|
+
"release:dry": "onreza-release --dry-run"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@biomejs/biome": "^2.3.13",
|
|
52
|
+
"@commitlint/cli": "^20.4.0",
|
|
53
|
+
"@commitlint/config-conventional": "^20.4.0",
|
|
54
|
+
"@commitlint/types": "^20.4.0",
|
|
55
|
+
"@types/bun": "^1.3.8",
|
|
56
|
+
"bunli": "0.5.1",
|
|
57
|
+
"onreza-release": "^2.2.0",
|
|
58
|
+
"lefthook": "^2.0.16"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"typescript": "^5.9.3"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@bunli/core": "^0.5.2",
|
|
65
|
+
"zod": "^4.3.6"
|
|
66
|
+
}
|
|
67
|
+
}
|
package/scripts/build.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Скрипт сборки standalone бинарников для всех платформ
|
|
4
|
+
* Использует bun build --compile напрямую
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { $ } from "bun";
|
|
8
|
+
|
|
9
|
+
const ENTRY = "./src/cli.ts";
|
|
10
|
+
const OUTDIR = "./dist";
|
|
11
|
+
const TARGETS = [
|
|
12
|
+
"bun-linux-x64",
|
|
13
|
+
"bun-darwin-arm64",
|
|
14
|
+
"bun-windows-x64",
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
// Маппинг bun targets на имена платформ (совместимые с onreza-release)
|
|
18
|
+
const TARGET_MAP: Record<string, string> = {
|
|
19
|
+
"bun-linux-x64": "linux-x64",
|
|
20
|
+
"bun-darwin-arm64": "darwin-arm64",
|
|
21
|
+
"bun-windows-x64": "win32-x64",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
async function build() {
|
|
25
|
+
console.log("🔨 Building standalone binaries...\n");
|
|
26
|
+
|
|
27
|
+
// Очищаем dist
|
|
28
|
+
await $`rm -rf ${OUTDIR}`;
|
|
29
|
+
await $`mkdir -p ${OUTDIR}`;
|
|
30
|
+
|
|
31
|
+
for (const target of TARGETS) {
|
|
32
|
+
const dirName = TARGET_MAP[target];
|
|
33
|
+
const isWindows = target.includes("windows");
|
|
34
|
+
const binName = isWindows ? "cli.exe" : "cli";
|
|
35
|
+
const outPath = `${OUTDIR}/${dirName}/${binName}`;
|
|
36
|
+
|
|
37
|
+
console.log(` 📦 ${target}...`);
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await $`bun build ${ENTRY} --compile --minify --target=${target} --outfile=${outPath}`.quiet();
|
|
41
|
+
console.log(` ✅ ${outPath}`);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(` ❌ Failed: ${error}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log("\n📦 Creating archives...\n");
|
|
49
|
+
|
|
50
|
+
for (const target of TARGETS) {
|
|
51
|
+
const dirName = TARGET_MAP[target];
|
|
52
|
+
const archiveName = `${dirName}.tar.gz`;
|
|
53
|
+
|
|
54
|
+
console.log(` 📦 ${archiveName}...`);
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
await $`tar -czf ${OUTDIR}/${archiveName} -C ${OUTDIR} ${dirName}`.quiet();
|
|
58
|
+
// Удаляем директорию после архивации
|
|
59
|
+
await $`rm -rf ${OUTDIR}/${dirName}`.quiet();
|
|
60
|
+
console.log(` ✅ ${archiveName}`);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error(` ❌ Failed: ${error}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log("\n✅ Build complete!\n");
|
|
68
|
+
|
|
69
|
+
// Показываем размеры
|
|
70
|
+
const files = await $`ls -lh ${OUTDIR}/*.tar.gz`.text();
|
|
71
|
+
console.log(files);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
build();
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { platform, arch } = process;
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const http = require("http");
|
|
7
|
+
const { createWriteStream, chmodSync, mkdirSync } = require("fs");
|
|
8
|
+
const { join } = require("path");
|
|
9
|
+
const { createGunzip } = require("zlib");
|
|
10
|
+
const tar = require("tar");
|
|
11
|
+
|
|
12
|
+
const MANIFEST = {
|
|
13
|
+
"assets": {
|
|
14
|
+
"linux-x64": "https://gitverse.ru/sc/sbt/api/v1/attachments/2ffa1246-98b0-4953-a1c0-8caebe256d15",
|
|
15
|
+
"darwin-arm64": "https://gitverse.ru/sc/sbt/api/v1/attachments/6c6d1443-6a48-4d80-8889-66faf0a4b33e",
|
|
16
|
+
"win32-x64": "https://gitverse.ru/sc/sbt/api/v1/attachments/1fd283b0-4fbc-4caf-9c76-279607565bc5"
|
|
17
|
+
},
|
|
18
|
+
"binName": "yougile",
|
|
19
|
+
"version": "0.8.2"
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const platformKey = `${platform}-${arch}`;
|
|
23
|
+
const downloadUrl = MANIFEST.assets[platformKey];
|
|
24
|
+
|
|
25
|
+
if (!downloadUrl) {
|
|
26
|
+
console.warn(`⚠️ No binary available for ${platformKey}, skipping installation`);
|
|
27
|
+
console.warn(` Supported platforms: ${Object.keys(MANIFEST.assets).join(", ")}`);
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const binDir = join(__dirname, "..", "bin");
|
|
32
|
+
mkdirSync(binDir, { recursive: true });
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Downloads and extracts a tar.gz archive
|
|
36
|
+
*/
|
|
37
|
+
function download(url, redirectCount = 0) {
|
|
38
|
+
if (redirectCount > 5) {
|
|
39
|
+
return Promise.reject(new Error("Too many redirects"));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
const protocol = url.startsWith("https") ? https : http;
|
|
44
|
+
|
|
45
|
+
const request = protocol.get(url, (res) => {
|
|
46
|
+
// Handle redirects
|
|
47
|
+
if (res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307 || res.statusCode === 308) {
|
|
48
|
+
const location = res.headers.location;
|
|
49
|
+
if (!location) {
|
|
50
|
+
reject(new Error("Redirect without location header"));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
download(location, redirectCount + 1).then(resolve).catch(reject);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (res.statusCode !== 200) {
|
|
58
|
+
reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
res
|
|
63
|
+
.pipe(createGunzip())
|
|
64
|
+
.pipe(tar.extract({ cwd: binDir }))
|
|
65
|
+
.on("finish", resolve)
|
|
66
|
+
.on("error", reject);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
request.on("error", reject);
|
|
70
|
+
request.setTimeout(30000, () => {
|
|
71
|
+
request.destroy();
|
|
72
|
+
reject(new Error("Download timeout"));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`📦 Installing ${MANIFEST.binName} for ${platformKey}...`);
|
|
78
|
+
|
|
79
|
+
download(downloadUrl)
|
|
80
|
+
.then(() => {
|
|
81
|
+
const binPath = join(binDir, MANIFEST.binName);
|
|
82
|
+
if (platform !== "win32") {
|
|
83
|
+
try {
|
|
84
|
+
chmodSync(binPath, 0o755);
|
|
85
|
+
} catch (e) {
|
|
86
|
+
// Ignore chmod errors on some platforms
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
console.log(`✅ Installed ${MANIFEST.binName} v${MANIFEST.version}`);
|
|
90
|
+
})
|
|
91
|
+
.catch((err) => {
|
|
92
|
+
console.error(`❌ Failed to install binary: ${err.message}`);
|
|
93
|
+
console.error(` URL: ${downloadUrl}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"additionalProperties": false,
|
|
4
|
+
"description": "Configuration file for YouGile CLI toolkit",
|
|
5
|
+
"properties": {
|
|
6
|
+
"apiKey": {
|
|
7
|
+
"default": "",
|
|
8
|
+
"description": "API Key (generated by 'yougile auth' command)",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"companyId": {
|
|
12
|
+
"description": "Company ID (UUID format)",
|
|
13
|
+
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
|
|
14
|
+
"type": "string"
|
|
15
|
+
},
|
|
16
|
+
"userId": {
|
|
17
|
+
"description": "User email address",
|
|
18
|
+
"format": "email",
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"userPassword": {
|
|
22
|
+
"description": "User password",
|
|
23
|
+
"type": "string"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["companyId", "userId", "userPassword"],
|
|
27
|
+
"title": "YouGile Toolkit Configuration",
|
|
28
|
+
"type": "object"
|
|
29
|
+
}
|