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 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
+ }
@@ -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
+ }