@asagiri-design/labels-config 0.3.0 → 0.3.1

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/dist/cli.js CHANGED
@@ -1444,13 +1444,13 @@ function printUsage() {
1444
1444
  console.log(" " + colorize("labels-config sync --owner user --repo repo --file labels.json --dry-run", "gray"));
1445
1445
  console.log("");
1446
1446
  console.log(" # Batch sync to all org repositories");
1447
- console.log(" " + colorize("labels-config batch-sync --org BoxPistols --template prod-ja --dry-run", "gray"));
1447
+ console.log(" " + colorize("labels-config batch-sync --org your-org --template prod-ja --dry-run", "gray"));
1448
1448
  console.log("");
1449
1449
  console.log(" # Batch sync to specific repositories");
1450
- console.log(" " + colorize("labels-config batch-sync --repos owner/repo1,owner/repo2 --file labels.json", "gray"));
1450
+ console.log(" " + colorize("labels-config batch-sync --repos your-org/repo1,your-org/repo2 --file labels.json", "gray"));
1451
1451
  console.log("");
1452
1452
  console.log(" # Batch sync with filters");
1453
- console.log(" " + colorize("labels-config batch-sync --user BoxPistols --template react --filter-lang TypeScript --filter-vis public", "gray"));
1453
+ console.log(" " + colorize("labels-config batch-sync --user your-username --template react --filter-lang TypeScript --filter-vis public", "gray"));
1454
1454
  console.log("");
1455
1455
  console.log(" # Batch sync using config file");
1456
1456
  console.log(" " + colorize("labels-config batch-config batch-config.json --dry-run", "gray"));
package/dist/cli.mjs CHANGED
@@ -192,13 +192,13 @@ function printUsage() {
192
192
  console.log(" " + colorize("labels-config sync --owner user --repo repo --file labels.json --dry-run", "gray"));
193
193
  console.log("");
194
194
  console.log(" # Batch sync to all org repositories");
195
- console.log(" " + colorize("labels-config batch-sync --org BoxPistols --template prod-ja --dry-run", "gray"));
195
+ console.log(" " + colorize("labels-config batch-sync --org your-org --template prod-ja --dry-run", "gray"));
196
196
  console.log("");
197
197
  console.log(" # Batch sync to specific repositories");
198
- console.log(" " + colorize("labels-config batch-sync --repos owner/repo1,owner/repo2 --file labels.json", "gray"));
198
+ console.log(" " + colorize("labels-config batch-sync --repos your-org/repo1,your-org/repo2 --file labels.json", "gray"));
199
199
  console.log("");
200
200
  console.log(" # Batch sync with filters");
201
- console.log(" " + colorize("labels-config batch-sync --user BoxPistols --template react --filter-lang TypeScript --filter-vis public", "gray"));
201
+ console.log(" " + colorize("labels-config batch-sync --user your-username --template react --filter-lang TypeScript --filter-vis public", "gray"));
202
202
  console.log("");
203
203
  console.log(" # Batch sync using config file");
204
204
  console.log(" " + colorize("labels-config batch-config batch-config.json --dry-run", "gray"));
package/dist/index.d.mts CHANGED
@@ -292,7 +292,7 @@ declare class LabelManager {
292
292
  };
293
293
  }
294
294
 
295
- declare const version = "0.3.0";
295
+ declare const version = "0.3.1";
296
296
 
297
297
  /**
298
298
  * @boxpistols/labels-config
package/dist/index.d.ts CHANGED
@@ -292,7 +292,7 @@ declare class LabelManager {
292
292
  };
293
293
  }
294
294
 
295
- declare const version = "0.3.0";
295
+ declare const version = "0.3.1";
296
296
 
297
297
  /**
298
298
  * @boxpistols/labels-config
package/dist/index.js CHANGED
@@ -279,7 +279,7 @@ var LabelManager = class {
279
279
  };
280
280
 
281
281
  // src/version.ts
282
- var version = "0.3.0";
282
+ var version = "0.3.1";
283
283
 
284
284
  // src/index.ts
285
285
  var index_default = {
package/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  import "./chunk-QZ7TP4HQ.mjs";
18
18
 
19
19
  // src/version.ts
20
- var version = "0.3.0";
20
+ var version = "0.3.1";
21
21
 
22
22
  // src/index.ts
23
23
  var index_default = {
@@ -12,26 +12,26 @@
12
12
 
13
13
  ```bash
14
14
  # 組織の全リポジトリにテンプレートを適用
15
- labels-config batch-sync --org BoxPistols --template prod-ja
15
+ labels-config batch-sync --org your-org --template prod-ja
16
16
 
17
17
  # ドライランで確認
18
- labels-config batch-sync --org BoxPistols --template prod-ja --dry-run
18
+ labels-config batch-sync --org your-org --template prod-ja --dry-run
19
19
 
20
20
  # 特定の言語でフィルタリング
21
- labels-config batch-sync --org BoxPistols --template react --filter-lang TypeScript
21
+ labels-config batch-sync --org your-org --template react --filter-lang TypeScript
22
22
 
23
23
  # 公開リポジトリのみに適用
24
- labels-config batch-sync --org BoxPistols --template prod-ja --filter-vis public
24
+ labels-config batch-sync --org your-org --template prod-ja --filter-vis public
25
25
  ```
26
26
 
27
27
  #### ユーザーの全リポジトリに同期
28
28
 
29
29
  ```bash
30
30
  # ユーザーの全リポジトリに同期
31
- labels-config batch-sync --user BoxPistols --template prod-ja
31
+ labels-config batch-sync --user your-username --template prod-ja
32
32
 
33
33
  # プライベートリポジトリのみ
34
- labels-config batch-sync --user BoxPistols --template prod-ja --filter-vis private
34
+ labels-config batch-sync --user your-username --template prod-ja --filter-vis private
35
35
  ```
36
36
 
37
37
  #### 特定のリポジトリリストに同期
@@ -39,12 +39,12 @@ labels-config batch-sync --user BoxPistols --template prod-ja --filter-vis priva
39
39
  ```bash
40
40
  # カスタムラベルファイルを使用
41
41
  labels-config batch-sync \
42
- --repos BoxPistols/repo1,BoxPistols/repo2,BoxPistols/repo3 \
42
+ --repos your-org/repo1,your-org/repo2,your-org/repo3 \
43
43
  --file ./custom-labels.json
44
44
 
45
45
  # テンプレートを使用
46
46
  labels-config batch-sync \
47
- --repos BoxPistols/repo1,BoxPistols/repo2 \
47
+ --repos your-org/repo1,your-org/repo2 \
48
48
  --template prod-ja
49
49
  ```
50
50
 
@@ -52,8 +52,8 @@ labels-config batch-sync \
52
52
 
53
53
  | オプション | 説明 | 例 |
54
54
  |-----------|------|-----|
55
- | `--org <name>` | 組織名 | `--org BoxPistols` |
56
- | `--user <name>` | ユーザー名 | `--user BoxPistols` |
55
+ | `--org <name>` | 組織名 | `--org your-org` |
56
+ | `--user <name>` | ユーザー名 | `--user your-username` |
57
57
  | `--repos <list>` | リポジトリリスト(カンマ区切り) | `--repos owner/repo1,owner/repo2` |
58
58
  | `--template <name>` | テンプレート名 | `--template prod-ja` |
59
59
  | `--file <path>` | カスタムラベルファイル | `--file ./labels.json` |
@@ -74,7 +74,7 @@ labels-config batch-sync \
74
74
  ```json
75
75
  {
76
76
  "version": "1.0.0",
77
- "description": "BoxPistols organization batch label sync",
77
+ "description": "your-org organization batch label sync",
78
78
  "defaults": {
79
79
  "template": "prod-ja",
80
80
  "mode": "append",
@@ -82,7 +82,7 @@ labels-config batch-sync \
82
82
  },
83
83
  "targets": [
84
84
  {
85
- "organization": "BoxPistols",
85
+ "organization": "your-org",
86
86
  "filter": {
87
87
  "visibility": "public",
88
88
  "language": "TypeScript",
@@ -93,14 +93,14 @@ labels-config batch-sync \
93
93
  },
94
94
  {
95
95
  "repositories": [
96
- "BoxPistols/labels-config",
97
- "BoxPistols/my-project"
96
+ "your-org/labels-config",
97
+ "your-org/my-project"
98
98
  ],
99
99
  "template": "prod-ja",
100
100
  "mode": "replace"
101
101
  },
102
102
  {
103
- "user": "BoxPistols",
103
+ "user": "your-username",
104
104
  "filter": {
105
105
  "visibility": "private"
106
106
  },
@@ -174,7 +174,7 @@ labels-config batch-config batch-config.json --dry-run
174
174
  - 設定にないラベルは**保持**
175
175
 
176
176
  ```bash
177
- labels-config batch-sync --org BoxPistols --template prod-ja
177
+ labels-config batch-sync --org your-org --template prod-ja
178
178
  ```
179
179
 
180
180
  ### Replace モード
@@ -184,7 +184,7 @@ labels-config batch-sync --org BoxPistols --template prod-ja
184
184
  - 設定にないラベルを**削除**
185
185
 
186
186
  ```bash
187
- labels-config batch-sync --org BoxPistols --template prod-ja --delete-extra
187
+ labels-config batch-sync --org your-org --template prod-ja --delete-extra
188
188
  ```
189
189
 
190
190
  ---
@@ -195,7 +195,7 @@ labels-config batch-sync --org BoxPistols --template prod-ja --delete-extra
195
195
 
196
196
  ```bash
197
197
  labels-config batch-sync \
198
- --org BoxPistols \
198
+ --org your-org \
199
199
  --template react \
200
200
  --filter-lang TypeScript \
201
201
  --filter-vis public \
@@ -213,17 +213,17 @@ batch-config.json:
213
213
  },
214
214
  "targets": [
215
215
  {
216
- "organization": "BoxPistols",
216
+ "organization": "your-org",
217
217
  "filter": { "language": "TypeScript" },
218
218
  "template": "react"
219
219
  },
220
220
  {
221
- "organization": "BoxPistols",
221
+ "organization": "your-org",
222
222
  "filter": { "language": "Go" },
223
223
  "template": "minimal"
224
224
  },
225
225
  {
226
- "repositories": ["BoxPistols/special-project"],
226
+ "repositories": ["your-org/special-project"],
227
227
  "file": "./special-labels.json",
228
228
  "mode": "replace"
229
229
  }
@@ -278,10 +278,10 @@ jobs:
278
278
 
279
279
  ```bash
280
280
  # 並列数を増やす(高速化)
281
- labels-config batch-sync --org BoxPistols --template prod-ja --parallel 10
281
+ labels-config batch-sync --org your-org --template prod-ja --parallel 10
282
282
 
283
283
  # 並列数を減らす(安定性重視)
284
- labels-config batch-sync --org BoxPistols --template prod-ja --parallel 1
284
+ labels-config batch-sync --org your-org --template prod-ja --parallel 1
285
285
  ```
286
286
 
287
287
  ### レート制限への対応
@@ -301,9 +301,9 @@ GitHub API のレート制限を考慮して、並列数を調整してくださ
301
301
  一部のリポジトリで失敗しても、他のリポジトリの処理は継続されます:
302
302
 
303
303
  ```
304
- ✅ [1/10] BoxPistols/repo1
305
- ❌ [2/10] BoxPistols/repo2: Permission denied
306
- ✅ [3/10] BoxPistols/repo3
304
+ ✅ [1/10] your-org/repo1
305
+ ❌ [2/10] your-org/repo2: Permission denied
306
+ ✅ [3/10] your-org/repo3
307
307
  ...
308
308
 
309
309
  📊 Batch Sync Summary:
@@ -311,8 +311,8 @@ GitHub API のレート制限を考慮して、並列数を調整してくださ
311
311
  ❌ Failed: 2
312
312
 
313
313
  ❌ Failed repositories:
314
- - BoxPistols/repo2: Permission denied
315
- - BoxPistols/repo5: Repository not found
314
+ - your-org/repo2: Permission denied
315
+ - your-org/repo5: Repository not found
316
316
  ```
317
317
 
318
318
  ### ドライランでの事前確認
@@ -320,7 +320,7 @@ GitHub API のレート制限を考慮して、並列数を調整してくださ
320
320
  本番実行前に必ずドライランで確認してください:
321
321
 
322
322
  ```bash
323
- labels-config batch-sync --org BoxPistols --template prod-ja --dry-run
323
+ labels-config batch-sync --org your-org --template prod-ja --dry-run
324
324
  ```
325
325
 
326
326
  ---
@@ -339,7 +339,7 @@ A: はい、デフォルトの Append モードで可能です(`--delete-extra
339
339
 
340
340
  A: はい、`--org` オプションで可能です:
341
341
  ```bash
342
- labels-config batch-sync --org BoxPistols --template prod-ja
342
+ labels-config batch-sync --org your-org --template prod-ja
343
343
  ```
344
344
 
345
345
  ### Q: 特定の条件でフィルタリングできますか?
@@ -356,7 +356,7 @@ A: はい、以下のフィルタが利用可能です:
356
356
  ### 権限エラー
357
357
 
358
358
  ```
359
- Error: Permission denied for BoxPistols/repo1
359
+ Error: Permission denied for your-org/repo1
360
360
  ```
361
361
 
362
362
  **解決方法:**
@@ -378,13 +378,13 @@ Error: API rate limit exceeded
378
378
  ### リポジトリが見つからない
379
379
 
380
380
  ```
381
- Error: Repository not found: BoxPistols/repo1
381
+ Error: Repository not found: your-org/repo1
382
382
  ```
383
383
 
384
384
  **解決方法:**
385
385
  1. リポジトリ名のスペルを確認
386
386
  2. リポジトリへのアクセス権限を確認
387
- 3. `gh repo list BoxPistols` でリポジトリ一覧を確認
387
+ 3. `gh repo list your-org` でリポジトリ一覧を確認
388
388
 
389
389
  ---
390
390
 
package/docs/NPM_SETUP.md CHANGED
@@ -52,7 +52,7 @@
52
52
  | 項目 | 値 |
53
53
  |------|-----|
54
54
  | **Provider** | GitHub |
55
- | **Organization / Repository owner** | `BoxPistols` |
55
+ | **Organization / Repository owner** | `your-org` |
56
56
  | **Repository name** | `labels-config` |
57
57
  | **Workflow name** | (以下の3つを個別に追加) |
58
58
 
@@ -388,7 +388,7 @@ labels-config batch-sync --help
388
388
  - [Getting Started](./GETTING_STARTED.md) - 詳細な使い方
389
389
  - [Batch Sync](./BATCH_SYNC.md) - バッチ同期の詳細
390
390
  - [API Documentation](./API.md) - プログラマティックな使い方
391
- - [GitHub Repository](https://github.com/BoxPistols/labels-config) - ソースコード
391
+ - [GitHub Repository](https://github.com/your-org/labels-config) - ソースコード
392
392
 
393
393
  ---
394
394
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asagiri-design/labels-config",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Terminal-first label management system for GitHub repositories using gh CLI - No token required",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -75,6 +75,7 @@
75
75
  "vitest": "^1.0.4"
76
76
  },
77
77
  "dependencies": {
78
+ "zenn-cli": "^0.2.11",
78
79
  "zod": "^3.22.4"
79
80
  },
80
81
  "engines": {
@@ -1,285 +0,0 @@
1
- import {
2
- __publicField
3
- } from "./chunk-QZ7TP4HQ.mjs";
4
-
5
- // src/github/client.ts
6
- import { execSync } from "child_process";
7
- var GitHubClient = class {
8
- constructor(options) {
9
- __publicField(this, "owner");
10
- __publicField(this, "repo");
11
- __publicField(this, "repoPath");
12
- this.owner = options.owner;
13
- this.repo = options.repo;
14
- this.repoPath = `${this.owner}/${this.repo}`;
15
- }
16
- /**
17
- * Execute gh CLI command
18
- */
19
- exec(command) {
20
- try {
21
- return execSync(command, {
22
- encoding: "utf-8",
23
- stdio: ["pipe", "pipe", "pipe"]
24
- }).trim();
25
- } catch (error) {
26
- throw new Error(`gh CLI command failed: ${error.message}`);
27
- }
28
- }
29
- /**
30
- * Fetch all labels from repository
31
- */
32
- async fetchLabels() {
33
- try {
34
- const output = this.exec(
35
- `gh label list --repo ${this.repoPath} --json name,color,description --limit 1000`
36
- );
37
- if (!output) {
38
- return [];
39
- }
40
- const labels = JSON.parse(output);
41
- return labels.map((label) => ({
42
- name: label.name,
43
- color: label.color,
44
- description: label.description || ""
45
- }));
46
- } catch (error) {
47
- throw new Error(`Failed to fetch labels from ${this.repoPath}: ${error}`);
48
- }
49
- }
50
- /**
51
- * Create a new label
52
- */
53
- async createLabel(label) {
54
- try {
55
- const name = label.name.replace(/"/g, '\\"');
56
- const description = label.description.replace(/"/g, '\\"');
57
- const color = label.color.replace("#", "");
58
- this.exec(
59
- `gh label create "${name}" --color "${color}" --description "${description}" --repo ${this.repoPath}`
60
- );
61
- return {
62
- name: label.name,
63
- color: label.color,
64
- description: label.description
65
- };
66
- } catch (error) {
67
- throw new Error(`Failed to create label "${label.name}": ${error}`);
68
- }
69
- }
70
- /**
71
- * Update an existing label
72
- */
73
- async updateLabel(currentName, label) {
74
- try {
75
- const escapedCurrentName = currentName.replace(/"/g, '\\"');
76
- const args = [];
77
- if (label.name && label.name !== currentName) {
78
- args.push(`--name "${label.name.replace(/"/g, '\\"')}"`);
79
- }
80
- if (label.color) {
81
- args.push(`--color "${label.color.replace("#", "")}"`);
82
- }
83
- if (label.description !== void 0) {
84
- args.push(`--description "${label.description.replace(/"/g, '\\"')}"`);
85
- }
86
- if (args.length === 0) {
87
- return {
88
- name: currentName,
89
- color: label.color || "",
90
- description: label.description || ""
91
- };
92
- }
93
- this.exec(
94
- `gh label edit "${escapedCurrentName}" ${args.join(" ")} --repo ${this.repoPath}`
95
- );
96
- return {
97
- name: label.name || currentName,
98
- color: label.color || "",
99
- description: label.description || ""
100
- };
101
- } catch (error) {
102
- throw new Error(`Failed to update label "${currentName}": ${error}`);
103
- }
104
- }
105
- /**
106
- * Delete a label
107
- */
108
- async deleteLabel(name) {
109
- try {
110
- const escapedName = name.replace(/"/g, '\\"');
111
- this.exec(`gh label delete "${escapedName}" --repo ${this.repoPath} --yes`);
112
- } catch (error) {
113
- throw new Error(`Failed to delete label "${name}": ${error}`);
114
- }
115
- }
116
- /**
117
- * Check if label exists
118
- */
119
- async hasLabel(name) {
120
- try {
121
- const labels = await this.fetchLabels();
122
- return labels.some((label) => label.name.toLowerCase() === name.toLowerCase());
123
- } catch (error) {
124
- return false;
125
- }
126
- }
127
- };
128
-
129
- // src/github/sync.ts
130
- var _GitHubLabelSync = class _GitHubLabelSync {
131
- constructor(options) {
132
- __publicField(this, "client");
133
- __publicField(this, "options");
134
- this.client = new GitHubClient(options);
135
- this.options = options;
136
- }
137
- /**
138
- * Log message if verbose mode is enabled
139
- */
140
- log(message) {
141
- if (this.options.verbose) {
142
- console.log(`[labels-config] ${message}`);
143
- }
144
- }
145
- /**
146
- * Sync labels to GitHub repository with batch operations for better performance
147
- */
148
- async syncLabels(localLabels) {
149
- this.log("Fetching remote labels...");
150
- const remoteLabels = await this.client.fetchLabels();
151
- const result = {
152
- created: [],
153
- updated: [],
154
- deleted: [],
155
- unchanged: [],
156
- errors: []
157
- };
158
- const remoteLabelMap = new Map(remoteLabels.map((label) => [label.name.toLowerCase(), label]));
159
- const localLabelMap = new Map(localLabels.map((label) => [label.name.toLowerCase(), label]));
160
- const toCreate = [];
161
- const toUpdate = [];
162
- const toDelete = [];
163
- for (const label of localLabels) {
164
- const remoteLabel = remoteLabelMap.get(label.name.toLowerCase());
165
- if (!remoteLabel) {
166
- toCreate.push(label);
167
- } else if (this.hasChanges(label, remoteLabel)) {
168
- toUpdate.push({ current: remoteLabel.name, updated: label });
169
- } else {
170
- result.unchanged.push(label);
171
- this.log(`Unchanged label: ${label.name}`);
172
- }
173
- }
174
- if (this.options.deleteExtra) {
175
- for (const remoteLabel of remoteLabels) {
176
- if (!localLabelMap.has(remoteLabel.name.toLowerCase())) {
177
- toDelete.push(remoteLabel.name);
178
- }
179
- }
180
- }
181
- if (!this.options.dryRun) {
182
- for (let i = 0; i < toCreate.length; i += _GitHubLabelSync.BATCH_SIZE) {
183
- const batch = toCreate.slice(i, i + _GitHubLabelSync.BATCH_SIZE);
184
- const promises = batch.map(async (label) => {
185
- try {
186
- await this.client.createLabel(label);
187
- result.created.push(label);
188
- this.log(`Created label: ${label.name}`);
189
- } catch (error) {
190
- result.errors.push({
191
- name: label.name,
192
- error: error instanceof Error ? error.message : String(error)
193
- });
194
- this.log(`Error creating label "${label.name}": ${error}`);
195
- }
196
- });
197
- await Promise.all(promises);
198
- }
199
- for (let i = 0; i < toUpdate.length; i += _GitHubLabelSync.BATCH_SIZE) {
200
- const batch = toUpdate.slice(i, i + _GitHubLabelSync.BATCH_SIZE);
201
- const promises = batch.map(async ({ current, updated }) => {
202
- try {
203
- await this.client.updateLabel(current, updated);
204
- result.updated.push(updated);
205
- this.log(`Updated label: ${updated.name}`);
206
- } catch (error) {
207
- result.errors.push({
208
- name: updated.name,
209
- error: error instanceof Error ? error.message : String(error)
210
- });
211
- this.log(`Error updating label "${updated.name}": ${error}`);
212
- }
213
- });
214
- await Promise.all(promises);
215
- }
216
- for (let i = 0; i < toDelete.length; i += _GitHubLabelSync.BATCH_SIZE) {
217
- const batch = toDelete.slice(i, i + _GitHubLabelSync.BATCH_SIZE);
218
- const promises = batch.map(async (name) => {
219
- try {
220
- await this.client.deleteLabel(name);
221
- result.deleted.push(name);
222
- this.log(`Deleted label: ${name}`);
223
- } catch (error) {
224
- result.errors.push({
225
- name,
226
- error: error instanceof Error ? error.message : String(error)
227
- });
228
- this.log(`Error deleting label "${name}": ${error}`);
229
- }
230
- });
231
- await Promise.all(promises);
232
- }
233
- } else {
234
- result.created.push(...toCreate);
235
- result.updated.push(...toUpdate.map((op) => op.updated));
236
- result.deleted.push(...toDelete);
237
- toCreate.forEach((label) => this.log(`[DRY RUN] Would create label: ${label.name}`));
238
- toUpdate.forEach(({ updated }) => this.log(`[DRY RUN] Would update label: ${updated.name}`));
239
- toDelete.forEach((name) => this.log(`[DRY RUN] Would delete label: ${name}`));
240
- }
241
- return result;
242
- }
243
- /**
244
- * Check if label has changes
245
- */
246
- hasChanges(local, remote) {
247
- return local.color.toLowerCase() !== remote.color.toLowerCase() || local.description !== (remote.description || "");
248
- }
249
- /**
250
- * Fetch labels from GitHub
251
- */
252
- async fetchLabels() {
253
- const labels = await this.client.fetchLabels();
254
- return labels.map((label) => ({
255
- name: label.name,
256
- color: label.color,
257
- description: label.description || ""
258
- }));
259
- }
260
- /**
261
- * Delete a single label
262
- */
263
- async deleteLabel(name) {
264
- if (!this.options.dryRun) {
265
- await this.client.deleteLabel(name);
266
- }
267
- this.log(`Deleted label: ${name}`);
268
- }
269
- /**
270
- * Update a single label
271
- */
272
- async updateLabel(name, updates) {
273
- if (!this.options.dryRun) {
274
- await this.client.updateLabel(name, updates);
275
- }
276
- this.log(`Updated label: ${name}`);
277
- }
278
- };
279
- __publicField(_GitHubLabelSync, "BATCH_SIZE", 5);
280
- var GitHubLabelSync = _GitHubLabelSync;
281
-
282
- export {
283
- GitHubClient,
284
- GitHubLabelSync
285
- };
@@ -1,496 +0,0 @@
1
- import {
2
- validateLabels
3
- } from "./chunk-VU2JB66N.mjs";
4
- import {
5
- __publicField
6
- } from "./chunk-QZ7TP4HQ.mjs";
7
-
8
- // src/config/loader.ts
9
- var ConfigLoader = class {
10
- constructor(options = {}) {
11
- __publicField(this, "strict");
12
- this.strict = options.strict ?? true;
13
- }
14
- /**
15
- * Load labels from JSON object
16
- */
17
- loadFromJSON(data) {
18
- if (typeof data === "object" && data !== null && "labels" in data && Array.isArray(data.labels)) {
19
- const labels = data.labels;
20
- if (labels.length > 0 && "category" in labels[0]) {
21
- return labels.flatMap((cat) => cat.labels);
22
- }
23
- return validateLabels(labels);
24
- }
25
- return validateLabels(data);
26
- }
27
- /**
28
- * Load from JSON string
29
- */
30
- loadFromString(jsonString) {
31
- try {
32
- const data = JSON.parse(jsonString);
33
- return this.loadFromJSON(data);
34
- } catch (error) {
35
- throw new Error(
36
- `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`
37
- );
38
- }
39
- }
40
- /**
41
- * Load from registry object
42
- */
43
- loadRegistry(registry) {
44
- return this.loadFromJSON({ labels: registry.labels });
45
- }
46
- };
47
-
48
- // src/config/templates.ts
49
- var MINIMAL_TEMPLATE = [
50
- {
51
- name: "bug",
52
- color: "ff0000",
53
- description: "Something is broken"
54
- },
55
- {
56
- name: "feature",
57
- color: "00ff00",
58
- description: "New feature or request"
59
- },
60
- {
61
- name: "documentation",
62
- color: "0000ff",
63
- description: "Improvements or additions to documentation"
64
- }
65
- ];
66
- var createLabels = (labels) => labels;
67
- var GITHUB_STANDARD_TEMPLATE = createLabels([
68
- {
69
- name: "bug",
70
- color: "d73a4a",
71
- description: "Something is broken"
72
- },
73
- {
74
- name: "documentation",
75
- color: "0075ca",
76
- description: "Improvements or additions to documentation"
77
- },
78
- {
79
- name: "duplicate",
80
- color: "cfd3d7",
81
- description: "This issue or pull request already exists"
82
- },
83
- {
84
- name: "enhancement",
85
- color: "a2eeef",
86
- description: "New feature or request"
87
- },
88
- {
89
- name: "good first issue",
90
- color: "7057ff",
91
- description: "Good for newcomers"
92
- },
93
- {
94
- name: "help wanted",
95
- color: "008672",
96
- description: "Extra attention is needed"
97
- },
98
- {
99
- name: "invalid",
100
- color: "e4e669",
101
- description: "This does not seem right"
102
- },
103
- {
104
- name: "question",
105
- color: "d876e3",
106
- description: "Further information is requested"
107
- },
108
- {
109
- name: "wontfix",
110
- color: "ffffff",
111
- description: "This will not be worked on"
112
- }
113
- ]);
114
- var SDPF_EN_TEMPLATE = createLabels([
115
- {
116
- name: "API",
117
- color: "ffb300",
118
- description: "API integration and external services"
119
- },
120
- {
121
- name: "BFF",
122
- color: "7057ff",
123
- description: "Backend for Frontend integration"
124
- },
125
- {
126
- name: "CI/CD",
127
- color: "00ced1",
128
- description: "CI/CD and automation"
129
- },
130
- {
131
- name: "Component",
132
- color: "008672",
133
- description: "Component addition and updates"
134
- },
135
- {
136
- name: "Documentation",
137
- color: "332412",
138
- description: "Documentation additions and updates"
139
- },
140
- {
141
- name: "Hotfix",
142
- color: "ff6347",
143
- description: "Emergency fixes and hotfixes"
144
- },
145
- {
146
- name: "Refactoring",
147
- color: "a9a9a9",
148
- description: "Code refactoring and performance optimization"
149
- },
150
- {
151
- name: "Testing",
152
- color: "08a4d6",
153
- description: "Testing, E2E, and unit tests"
154
- },
155
- {
156
- name: "Type Definition",
157
- color: "e91e63",
158
- description: "TypeScript type definitions and type safety"
159
- },
160
- {
161
- name: "Design",
162
- color: "d876e3",
163
- description: "UI/UX design"
164
- },
165
- {
166
- name: "Specification",
167
- color: "d93f0b",
168
- description: "Specification changes"
169
- },
170
- {
171
- name: "Feature",
172
- color: "b3fa11",
173
- description: "New feature addition"
174
- },
175
- {
176
- name: "Environment",
177
- color: "c5def5",
178
- description: "Development environment and package updates"
179
- },
180
- {
181
- name: "Page",
182
- color: "16c9f5",
183
- description: "Page additions and updates"
184
- }
185
- ]);
186
- var SDPF_JA_TEMPLATE = createLabels([
187
- {
188
- name: "API\u9023\u643A",
189
- color: "ffb300",
190
- description: "API\u30FB\u5916\u90E8\u30B5\u30FC\u30D3\u30B9\u9023\u643A"
191
- },
192
- {
193
- name: "BFF",
194
- color: "7057ff",
195
- description: "BFF\u30FB\u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u9023\u643A"
196
- },
197
- {
198
- name: "CI/CD",
199
- color: "00ced1",
200
- description: "CI/CD\u30FB\u81EA\u52D5\u5316"
201
- },
202
- {
203
- name: "\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8",
204
- color: "008672",
205
- description: "\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u8FFD\u52A0\u30FB\u66F4\u65B0"
206
- },
207
- {
208
- name: "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
209
- color: "332412",
210
- description: "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u8FFD\u52A0\u30FB\u66F4\u65B0"
211
- },
212
- {
213
- name: "\u7DCA\u6025\u5BFE\u5FDC",
214
- color: "ff6347",
215
- description: "\u7DCA\u6025\u4FEE\u6B63\u30FBHotfix"
216
- },
217
- {
218
- name: "\u30EA\u30D5\u30A1\u30AF\u30BF",
219
- color: "a9a9a9",
220
- description: "\u30EA\u30D5\u30A1\u30AF\u30BF\u30EA\u30F3\u30B0\u30FB\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u6700\u9069\u5316\u30FB\u30B3\u30FC\u30C9\u6574\u7406"
221
- },
222
- {
223
- name: "\u30C6\u30B9\u30C8",
224
- color: "08a4d6",
225
- description: "\u30C6\u30B9\u30C8\u30FBE2E\u30FB\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8"
226
- },
227
- {
228
- name: "\u578B\u5B9A\u7FA9",
229
- color: "e91e63",
230
- description: "TypeScript\u578B\u5B9A\u7FA9\u30FB\u578B\u5B89\u5168\u6027"
231
- },
232
- {
233
- name: "\u30C7\u30B6\u30A4\u30F3",
234
- color: "d876e3",
235
- description: "UIUX\u30C7\u30B6\u30A4\u30F3"
236
- },
237
- {
238
- name: "\u4ED5\u69D8\u5909\u66F4",
239
- color: "d93f0b",
240
- description: "\u4ED5\u69D8\u5909\u66F4"
241
- },
242
- {
243
- name: "\u6A5F\u80FD\u8FFD\u52A0",
244
- color: "b3fa11",
245
- description: "\u6A5F\u80FD\u8FFD\u52A0"
246
- },
247
- {
248
- name: "\u74B0\u5883\u69CB\u7BC9",
249
- color: "c5def5",
250
- description: "\u958B\u767A\u74B0\u5883\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u8FFD\u52A0\u30FB\u5909\u66F4\u30FB\u66F4\u65B0"
251
- },
252
- {
253
- name: "\u753B\u9762\u8FFD\u52A0",
254
- color: "16c9f5",
255
- description: "\u753B\u9762\u306E\u8FFD\u52A0\u30FB\u66F4\u65B0"
256
- }
257
- ]);
258
- var SDPF_TEMPLATE = SDPF_JA_TEMPLATE;
259
- var REACT_TEMPLATE = createLabels([
260
- {
261
- name: "component",
262
- color: "61dafb",
263
- description: "React component development"
264
- },
265
- {
266
- name: "hook",
267
- color: "20232a",
268
- description: "Custom hooks implementation"
269
- },
270
- {
271
- name: "state-management",
272
- color: "764abc",
273
- description: "Redux, Zustand, Context API"
274
- },
275
- {
276
- name: "performance",
277
- color: "ffc107",
278
- description: "Performance optimization, memoization"
279
- },
280
- {
281
- name: "typescript",
282
- color: "3178c6",
283
- description: "TypeScript types and interfaces"
284
- },
285
- {
286
- name: "styling",
287
- color: "ff69b4",
288
- description: "CSS-in-JS, Tailwind, styled-components"
289
- },
290
- {
291
- name: "testing",
292
- color: "15c213",
293
- description: "Unit tests, React Testing Library"
294
- },
295
- {
296
- name: "bug",
297
- color: "d73a4a",
298
- description: "Bug fix required"
299
- },
300
- {
301
- name: "refactor",
302
- color: "fbca04",
303
- description: "Code refactoring"
304
- },
305
- {
306
- name: "accessibility",
307
- color: "0e8a16",
308
- description: "A11y improvements"
309
- }
310
- ]);
311
- var VUE_TEMPLATE = createLabels([
312
- {
313
- name: "component",
314
- color: "42b883",
315
- description: "Vue component development"
316
- },
317
- {
318
- name: "composable",
319
- color: "35495e",
320
- description: "Composition API, composables"
321
- },
322
- {
323
- name: "pinia",
324
- color: "ffd859",
325
- description: "Pinia state management"
326
- },
327
- {
328
- name: "vue-router",
329
- color: "3ba57a",
330
- description: "Vue Router navigation"
331
- },
332
- {
333
- name: "typescript",
334
- color: "3178c6",
335
- description: "TypeScript integration"
336
- },
337
- {
338
- name: "styling",
339
- color: "ff69b4",
340
- description: "Scoped CSS, CSS modules"
341
- },
342
- {
343
- name: "testing",
344
- color: "15c213",
345
- description: "Vitest, Vue Test Utils"
346
- },
347
- {
348
- name: "bug",
349
- color: "d73a4a",
350
- description: "Bug fix required"
351
- },
352
- {
353
- name: "performance",
354
- color: "ffc107",
355
- description: "Performance optimization"
356
- },
357
- {
358
- name: "accessibility",
359
- color: "0e8a16",
360
- description: "A11y improvements"
361
- }
362
- ]);
363
- var FRONTEND_TEMPLATE = createLabels([
364
- {
365
- name: "feature",
366
- color: "0e8a16",
367
- description: "New feature implementation"
368
- },
369
- {
370
- name: "bug",
371
- color: "d73a4a",
372
- description: "Bug fix required"
373
- },
374
- {
375
- name: "ui",
376
- color: "ff69b4",
377
- description: "UI/UX improvements"
378
- },
379
- {
380
- name: "styling",
381
- color: "c5def5",
382
- description: "CSS, styling updates"
383
- },
384
- {
385
- name: "responsive",
386
- color: "1d76db",
387
- description: "Responsive design, mobile support"
388
- },
389
- {
390
- name: "performance",
391
- color: "ffc107",
392
- description: "Performance optimization"
393
- },
394
- {
395
- name: "accessibility",
396
- color: "0052cc",
397
- description: "A11y improvements"
398
- },
399
- {
400
- name: "testing",
401
- color: "15c213",
402
- description: "Testing, E2E, unit tests"
403
- },
404
- {
405
- name: "dependencies",
406
- color: "0366d6",
407
- description: "Dependencies update"
408
- },
409
- {
410
- name: "documentation",
411
- color: "0075ca",
412
- description: "Documentation updates"
413
- },
414
- {
415
- name: "build",
416
- color: "fbca04",
417
- description: "Build system, bundler"
418
- },
419
- {
420
- name: "seo",
421
- color: "b60205",
422
- description: "SEO optimization"
423
- }
424
- ]);
425
- var AGILE_TEMPLATE = createLabels([
426
- {
427
- name: "story",
428
- color: "0e7490",
429
- description: "User story"
430
- },
431
- {
432
- name: "task",
433
- color: "4c72a0",
434
- description: "Implementation task"
435
- },
436
- {
437
- name: "spike",
438
- color: "ab47bc",
439
- description: "Research and exploration"
440
- },
441
- {
442
- name: "bug",
443
- color: "d32f2f",
444
- description: "Bug fix"
445
- },
446
- {
447
- name: "debt",
448
- color: "f57c00",
449
- description: "Technical debt"
450
- },
451
- {
452
- name: "blocked",
453
- color: "616161",
454
- description: "Blocked by another issue"
455
- },
456
- {
457
- name: "priority:critical",
458
- color: "ff0000",
459
- description: "Critical priority"
460
- },
461
- {
462
- name: "priority:high",
463
- color: "ff9800",
464
- description: "High priority"
465
- },
466
- {
467
- name: "priority:medium",
468
- color: "ffc107",
469
- description: "Medium priority"
470
- },
471
- {
472
- name: "priority:low",
473
- color: "cddc39",
474
- description: "Low priority"
475
- }
476
- ]);
477
- var CONFIG_TEMPLATES = {
478
- minimal: MINIMAL_TEMPLATE,
479
- github: GITHUB_STANDARD_TEMPLATE,
480
- react: REACT_TEMPLATE,
481
- vue: VUE_TEMPLATE,
482
- frontend: FRONTEND_TEMPLATE,
483
- "sdpf-en": SDPF_EN_TEMPLATE,
484
- "sdpf-ja": SDPF_JA_TEMPLATE,
485
- sdpf: SDPF_TEMPLATE,
486
- agile: AGILE_TEMPLATE
487
- };
488
- function listTemplates() {
489
- return Object.keys(CONFIG_TEMPLATES);
490
- }
491
-
492
- export {
493
- ConfigLoader,
494
- CONFIG_TEMPLATES,
495
- listTemplates
496
- };
@@ -1,247 +0,0 @@
1
- import {
2
- __publicField
3
- } from "./chunk-QZ7TP4HQ.mjs";
4
-
5
- // src/github/client.ts
6
- import { execSync } from "child_process";
7
- var GitHubClient = class {
8
- constructor(options) {
9
- __publicField(this, "owner");
10
- __publicField(this, "repo");
11
- __publicField(this, "repoPath");
12
- this.owner = options.owner;
13
- this.repo = options.repo;
14
- this.repoPath = `${this.owner}/${this.repo}`;
15
- }
16
- /**
17
- * Execute gh CLI command
18
- */
19
- exec(command) {
20
- try {
21
- return execSync(command, {
22
- encoding: "utf-8",
23
- stdio: ["pipe", "pipe", "pipe"]
24
- }).trim();
25
- } catch (error) {
26
- throw new Error(`gh CLI command failed: ${error.message}`);
27
- }
28
- }
29
- /**
30
- * Fetch all labels from repository
31
- */
32
- async fetchLabels() {
33
- try {
34
- const output = this.exec(
35
- `gh label list --repo ${this.repoPath} --json name,color,description --limit 1000`
36
- );
37
- if (!output) {
38
- return [];
39
- }
40
- const labels = JSON.parse(output);
41
- return labels.map((label) => ({
42
- name: label.name,
43
- color: label.color,
44
- description: label.description || ""
45
- }));
46
- } catch (error) {
47
- throw new Error(`Failed to fetch labels from ${this.repoPath}: ${error}`);
48
- }
49
- }
50
- /**
51
- * Create a new label
52
- */
53
- async createLabel(label) {
54
- try {
55
- const name = label.name.replace(/"/g, '\\"');
56
- const description = label.description.replace(/"/g, '\\"');
57
- const color = label.color.replace("#", "");
58
- this.exec(
59
- `gh label create "${name}" --color "${color}" --description "${description}" --repo ${this.repoPath}`
60
- );
61
- return {
62
- name: label.name,
63
- color: label.color,
64
- description: label.description
65
- };
66
- } catch (error) {
67
- throw new Error(`Failed to create label "${label.name}": ${error}`);
68
- }
69
- }
70
- /**
71
- * Update an existing label
72
- */
73
- async updateLabel(currentName, label) {
74
- try {
75
- const escapedCurrentName = currentName.replace(/"/g, '\\"');
76
- const args = [];
77
- if (label.name && label.name !== currentName) {
78
- args.push(`--name "${label.name.replace(/"/g, '\\"')}"`);
79
- }
80
- if (label.color) {
81
- args.push(`--color "${label.color.replace("#", "")}"`);
82
- }
83
- if (label.description !== void 0) {
84
- args.push(`--description "${label.description.replace(/"/g, '\\"')}"`);
85
- }
86
- if (args.length === 0) {
87
- return {
88
- name: currentName,
89
- color: label.color || "",
90
- description: label.description || ""
91
- };
92
- }
93
- this.exec(
94
- `gh label edit "${escapedCurrentName}" ${args.join(" ")} --repo ${this.repoPath}`
95
- );
96
- return {
97
- name: label.name || currentName,
98
- color: label.color || "",
99
- description: label.description || ""
100
- };
101
- } catch (error) {
102
- throw new Error(`Failed to update label "${currentName}": ${error}`);
103
- }
104
- }
105
- /**
106
- * Delete a label
107
- */
108
- async deleteLabel(name) {
109
- try {
110
- const escapedName = name.replace(/"/g, '\\"');
111
- this.exec(`gh label delete "${escapedName}" --repo ${this.repoPath} --yes`);
112
- } catch (error) {
113
- throw new Error(`Failed to delete label "${name}": ${error}`);
114
- }
115
- }
116
- /**
117
- * Check if label exists
118
- */
119
- async hasLabel(name) {
120
- try {
121
- const labels = await this.fetchLabels();
122
- return labels.some((label) => label.name.toLowerCase() === name.toLowerCase());
123
- } catch (error) {
124
- return false;
125
- }
126
- }
127
- };
128
-
129
- // src/github/sync.ts
130
- var GitHubLabelSync = class {
131
- constructor(options) {
132
- __publicField(this, "client");
133
- __publicField(this, "options");
134
- this.client = new GitHubClient(options);
135
- this.options = options;
136
- }
137
- /**
138
- * Log message if verbose mode is enabled
139
- */
140
- log(message) {
141
- if (this.options.verbose) {
142
- console.log(`[labels-config] ${message}`);
143
- }
144
- }
145
- /**
146
- * Sync labels to GitHub repository
147
- */
148
- async syncLabels(localLabels) {
149
- this.log("Fetching remote labels...");
150
- const remoteLabels = await this.client.fetchLabels();
151
- const result = {
152
- created: [],
153
- updated: [],
154
- deleted: [],
155
- unchanged: [],
156
- errors: []
157
- };
158
- const remoteLabelMap = new Map(remoteLabels.map((label) => [label.name.toLowerCase(), label]));
159
- const localLabelMap = new Map(localLabels.map((label) => [label.name.toLowerCase(), label]));
160
- for (const label of localLabels) {
161
- const remoteLabel = remoteLabelMap.get(label.name.toLowerCase());
162
- try {
163
- if (!remoteLabel) {
164
- if (!this.options.dryRun) {
165
- await this.client.createLabel(label);
166
- }
167
- result.created.push(label);
168
- this.log(`Created label: ${label.name}`);
169
- } else if (this.hasChanges(label, remoteLabel)) {
170
- if (!this.options.dryRun) {
171
- await this.client.updateLabel(remoteLabel.name, label);
172
- }
173
- result.updated.push(label);
174
- this.log(`Updated label: ${label.name}`);
175
- } else {
176
- result.unchanged.push(label);
177
- this.log(`Unchanged label: ${label.name}`);
178
- }
179
- } catch (error) {
180
- result.errors.push({
181
- name: label.name,
182
- error: error instanceof Error ? error.message : String(error)
183
- });
184
- this.log(`Error processing label "${label.name}": ${error}`);
185
- }
186
- }
187
- if (this.options.deleteExtra) {
188
- for (const remoteLabel of remoteLabels) {
189
- if (!localLabelMap.has(remoteLabel.name.toLowerCase())) {
190
- try {
191
- if (!this.options.dryRun) {
192
- await this.client.deleteLabel(remoteLabel.name);
193
- }
194
- result.deleted.push(remoteLabel.name);
195
- this.log(`Deleted label: ${remoteLabel.name}`);
196
- } catch (error) {
197
- result.errors.push({
198
- name: remoteLabel.name,
199
- error: error instanceof Error ? error.message : String(error)
200
- });
201
- }
202
- }
203
- }
204
- }
205
- return result;
206
- }
207
- /**
208
- * Check if label has changes
209
- */
210
- hasChanges(local, remote) {
211
- return local.color.toLowerCase() !== remote.color.toLowerCase() || local.description !== (remote.description || "");
212
- }
213
- /**
214
- * Fetch labels from GitHub
215
- */
216
- async fetchLabels() {
217
- const labels = await this.client.fetchLabels();
218
- return labels.map((label) => ({
219
- name: label.name,
220
- color: label.color,
221
- description: label.description || ""
222
- }));
223
- }
224
- /**
225
- * Delete a single label
226
- */
227
- async deleteLabel(name) {
228
- if (!this.options.dryRun) {
229
- await this.client.deleteLabel(name);
230
- }
231
- this.log(`Deleted label: ${name}`);
232
- }
233
- /**
234
- * Update a single label
235
- */
236
- async updateLabel(name, updates) {
237
- if (!this.options.dryRun) {
238
- await this.client.updateLabel(name, updates);
239
- }
240
- this.log(`Updated label: ${name}`);
241
- }
242
- };
243
-
244
- export {
245
- GitHubClient,
246
- GitHubLabelSync
247
- };