@happyvertical/github-actions 0.80.0 → 0.80.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.
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, mkdirSync, copyFileSync } from "node:fs";
2
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- const __dirname$1 = dirname(fileURLToPath(import.meta.url));
6
- const pkgRoot = join(__dirname$1, "../..");
7
- const targetDir = join(process.cwd(), ".claude");
8
- if (!existsSync(targetDir)) {
9
- mkdirSync(targetDir, { recursive: true });
10
- }
11
- const pkgName = "github-actions";
12
- const agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
13
- const metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
14
- if (existsSync(agentMdSrc)) {
15
- copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
16
- }
17
- if (existsSync(metaSrc)) {
18
- copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
19
- }
5
+ //#region src/cli/claude-context.ts
6
+ /**
7
+ * CLI script to install agent context for @happyvertical/github-actions
8
+ * Run the published context installer binary for this package.
9
+ */
10
+ var pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "../..");
11
+ var targetDir = join(process.cwd(), ".claude");
12
+ if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });
13
+ var pkgName = "github-actions";
14
+ var agentMdSrc = existsSync(join(pkgRoot, "AGENT.md")) ? join(pkgRoot, "AGENT.md") : join(pkgRoot, "CLAUDE.md");
15
+ var metaSrc = existsSync(join(pkgRoot, "metadata.json")) ? join(pkgRoot, "metadata.json") : join(pkgRoot, ".claude-meta.json");
16
+ if (existsSync(agentMdSrc)) copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));
17
+ if (existsSync(metaSrc)) copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));
20
18
  console.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);
21
- //# sourceMappingURL=claude-context.js.map
19
+ //#endregion
20
+
21
+ //# sourceMappingURL=claude-context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-context.js","sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/github-actions\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(__dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'github-actions';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"names":["__dirname"],"mappings":";;;;AASA,MAAMA,cAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,MAAM,UAAU,KAAKA,aAAW,OAAO;AACvC,MAAM,YAAY,KAAK,QAAQ,IAAA,GAAO,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAC1C;AAEA,MAAM,UAAU;AAChB,MAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,MAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GAAG;AAC1B,eAAa,YAAY,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC;AAChE;AAEA,IAAI,WAAW,OAAO,GAAG;AACvB,eAAa,SAAS,KAAK,WAAW,QAAQ,OAAO,YAAY,CAAC;AACpE;AAEA,QAAQ,IAAI,8BAA8B,OAAO,sBAAsB;"}
1
+ {"version":3,"file":"claude-context.js","names":[],"sources":["../../src/cli/claude-context.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI script to install agent context for @happyvertical/github-actions\n * Run the published context installer binary for this package.\n */\nimport { copyFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkgRoot = join(__dirname, '../..');\nconst targetDir = join(process.cwd(), '.claude');\n\nif (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n}\n\nconst pkgName = 'github-actions';\nconst agentMdSrc = existsSync(join(pkgRoot, 'AGENT.md'))\n ? join(pkgRoot, 'AGENT.md')\n : join(pkgRoot, 'CLAUDE.md');\nconst metaSrc = existsSync(join(pkgRoot, 'metadata.json'))\n ? join(pkgRoot, 'metadata.json')\n : join(pkgRoot, '.claude-meta.json');\n\nif (existsSync(agentMdSrc)) {\n copyFileSync(agentMdSrc, join(targetDir, `have-${pkgName}.md`));\n}\n\nif (existsSync(metaSrc)) {\n copyFileSync(metaSrc, join(targetDir, `have-${pkgName}.meta.json`));\n}\n\nconsole.log(`✓ Installed @happyvertical/${pkgName} context to .claude/`);\n"],"mappings":";;;;;;;;;AAUA,IAAM,UAAU,KADE,QAAQ,cAAc,OAAO,KAAK,GAAG,CAClC,GAAW,OAAO;AACvC,IAAM,YAAY,KAAK,QAAQ,IAAI,GAAG,SAAS;AAE/C,IAAI,CAAC,WAAW,SAAS,GACvB,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1C,IAAM,UAAU;AAChB,IAAM,aAAa,WAAW,KAAK,SAAS,UAAU,CAAC,IACnD,KAAK,SAAS,UAAU,IACxB,KAAK,SAAS,WAAW;AAC7B,IAAM,UAAU,WAAW,KAAK,SAAS,eAAe,CAAC,IACrD,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,mBAAmB;AAErC,IAAI,WAAW,UAAU,GACvB,aAAa,YAAY,KAAK,WAAW,QAAQ,QAAQ,IAAI,CAAC;AAGhE,IAAI,WAAW,OAAO,GACpB,aAAa,SAAS,KAAK,WAAW,QAAQ,QAAQ,WAAW,CAAC;AAGpE,QAAQ,IAAI,8BAA8B,QAAQ,qBAAqB"}
package/dist/cli.js CHANGED
@@ -1,104 +1,92 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from "node:fs";
3
- import "@happyvertical/projects";
2
+ import { C as getAllStandardLabels, b as AREA_LABEL_TEMPLATE, n as triageIssue } from "./src-CezXcNYi.js";
4
3
  import { getRepository } from "@happyvertical/repos";
5
- import "node:https";
6
- import { l as getAllStandardLabels, A as AREA_LABEL_TEMPLATE, v as triageIssue } from "./index-v2-CqFKwTm8.js";
4
+ import { readFileSync } from "node:fs";
5
+ //#region src/labels-cli.ts
6
+ /**
7
+ * Label Management CLI
8
+ *
9
+ * Apply standard labels across repositories
10
+ */
11
+ /**
12
+ * Apply standard labels to a repository
13
+ */
7
14
  async function applyStandardLabels(options) {
8
- console.log(
9
- `
10
- 🏷️ Applying standard labels to ${options.owner}/${options.repo}`
11
- );
12
- if (options.dryRun) {
13
- console.log("🔍 DRY RUN MODE - No changes will be made\n");
14
- }
15
- try {
16
- const repo = await getRepository({
17
- type: "github",
18
- owner: options.owner,
19
- repo: options.repo,
20
- token: options.token
21
- });
22
- const standardLabels = getAllStandardLabels();
23
- const labelsToApply = [...standardLabels];
24
- if (options.includeArea) {
25
- const areaLabels = options.areaLabels ? options.areaLabels.map((name) => ({
26
- name: `area: ${name}`,
27
- color: "fbca04",
28
- description: `${name.charAt(0).toUpperCase() + name.slice(1)} area`
29
- })) : AREA_LABEL_TEMPLATE;
30
- labelsToApply.push(...areaLabels);
31
- }
32
- console.log(`📋 Found ${labelsToApply.length} labels to create/update:
33
- `);
34
- const byCategory = {};
35
- for (const label of labelsToApply) {
36
- const category = label.name.split(":")[0];
37
- if (!byCategory[category]) {
38
- byCategory[category] = [];
39
- }
40
- byCategory[category].push(label);
41
- }
42
- for (const [category, labels] of Object.entries(byCategory)) {
43
- console.log(` ${category}:`);
44
- for (const label of labels) {
45
- console.log(
46
- ` - ${label.name} (#${label.color}) - ${label.description}`
47
- );
48
- }
49
- }
50
- if (options.dryRun) {
51
- console.log("\n✅ Dry run complete - no changes made");
52
- return;
53
- }
54
- console.log("\n🔧 Creating/updating labels...\n");
55
- let created = 0;
56
- let updated = 0;
57
- let errors = 0;
58
- for (const label of labelsToApply) {
59
- try {
60
- const existingLabels = await repo.listLabels();
61
- const existing = existingLabels.find((l) => l.name === label.name);
62
- if (existing) {
63
- await repo.updateLabel(label.name, {
64
- name: label.name,
65
- color: label.color,
66
- description: label.description
67
- });
68
- console.log(` ✅ Updated: ${label.name}`);
69
- updated++;
70
- } else {
71
- await repo.createLabel({
72
- name: label.name,
73
- color: label.color,
74
- description: label.description
75
- });
76
- console.log(` ✨ Created: ${label.name}`);
77
- created++;
78
- }
79
- } catch (error) {
80
- console.error(
81
- ` ❌ Error with ${label.name}: ${error.message}`
82
- );
83
- errors++;
84
- }
85
- }
86
- console.log(`
87
- ✅ Label sync complete!`);
88
- console.log(` Created: ${created}`);
89
- console.log(` Updated: ${updated}`);
90
- if (errors > 0) {
91
- console.log(` Errors: ${errors}`);
92
- }
93
- } catch (error) {
94
- console.error("❌ Failed to apply labels:", error.message);
95
- throw error;
96
- }
15
+ console.log(`\n🏷️ Applying standard labels to ${options.owner}/${options.repo}`);
16
+ if (options.dryRun) console.log("🔍 DRY RUN MODE - No changes will be made\n");
17
+ try {
18
+ const repo = await getRepository({
19
+ type: "github",
20
+ owner: options.owner,
21
+ repo: options.repo,
22
+ token: options.token
23
+ });
24
+ const labelsToApply = [...getAllStandardLabels()];
25
+ if (options.includeArea) {
26
+ const areaLabels = options.areaLabels ? options.areaLabels.map((name) => ({
27
+ name: `area: ${name}`,
28
+ color: "fbca04",
29
+ description: `${name.charAt(0).toUpperCase() + name.slice(1)} area`
30
+ })) : AREA_LABEL_TEMPLATE;
31
+ labelsToApply.push(...areaLabels);
32
+ }
33
+ console.log(`📋 Found ${labelsToApply.length} labels to create/update:\n`);
34
+ const byCategory = {};
35
+ for (const label of labelsToApply) {
36
+ const category = label.name.split(":")[0];
37
+ if (!byCategory[category]) byCategory[category] = [];
38
+ byCategory[category].push(label);
39
+ }
40
+ for (const [category, labels] of Object.entries(byCategory)) {
41
+ console.log(` ${category}:`);
42
+ for (const label of labels) console.log(` - ${label.name} (#${label.color}) - ${label.description}`);
43
+ }
44
+ if (options.dryRun) {
45
+ console.log("\n✅ Dry run complete - no changes made");
46
+ return;
47
+ }
48
+ console.log("\n🔧 Creating/updating labels...\n");
49
+ let created = 0;
50
+ let updated = 0;
51
+ let errors = 0;
52
+ for (const label of labelsToApply) try {
53
+ if ((await repo.listLabels()).find((l) => l.name === label.name)) {
54
+ await repo.updateLabel(label.name, {
55
+ name: label.name,
56
+ color: label.color,
57
+ description: label.description
58
+ });
59
+ console.log(` ✅ Updated: ${label.name}`);
60
+ updated++;
61
+ } else {
62
+ await repo.createLabel({
63
+ name: label.name,
64
+ color: label.color,
65
+ description: label.description
66
+ });
67
+ console.log(` ✨ Created: ${label.name}`);
68
+ created++;
69
+ }
70
+ } catch (error) {
71
+ console.error(` ❌ Error with ${label.name}: ${error.message}`);
72
+ errors++;
73
+ }
74
+ console.log(`\n✅ Label sync complete!`);
75
+ console.log(` Created: ${created}`);
76
+ console.log(` Updated: ${updated}`);
77
+ if (errors > 0) console.log(` Errors: ${errors}`);
78
+ } catch (error) {
79
+ console.error("❌ Failed to apply labels:", error.message);
80
+ throw error;
81
+ }
97
82
  }
83
+ /**
84
+ * CLI entry point
85
+ */
98
86
  async function main$1() {
99
- const args = process.argv.slice(2);
100
- if (args.includes("--help") || args.includes("-h")) {
101
- console.log(`
87
+ const args = process.argv.slice(2);
88
+ if (args.includes("--help") || args.includes("-h")) {
89
+ console.log(`
102
90
  Label Management CLI
103
91
 
104
92
  Usage: github-actions labels [options]
@@ -125,149 +113,154 @@ Examples:
125
113
  Environment Variables:
126
114
  GITHUB_TOKEN GitHub personal access token
127
115
  `);
128
- process.exit(0);
129
- }
130
- const token = args[args.indexOf("--token") + 1] || process.env.GITHUB_TOKEN;
131
- const owner = args[args.indexOf("--owner") + 1];
132
- const repo = args[args.indexOf("--repo") + 1];
133
- const dryRun = args.includes("--dry-run");
134
- const includeArea = args.includes("--include-area");
135
- const areaLabels = [];
136
- let i = 0;
137
- while ((i = args.indexOf("--area", i)) !== -1) {
138
- areaLabels.push(args[i + 1]);
139
- i++;
140
- }
141
- if (!token) {
142
- console.error("❌ Error: GitHub token is required");
143
- console.error(" Use --token <token> or set GITHUB_TOKEN env var");
144
- process.exit(1);
145
- }
146
- if (!owner || !repo) {
147
- console.error("❌ Error: --owner and --repo are required");
148
- process.exit(1);
149
- }
150
- await applyStandardLabels({
151
- token,
152
- owner,
153
- repo,
154
- dryRun,
155
- includeArea,
156
- areaLabels: areaLabels.length > 0 ? areaLabels : void 0
157
- });
158
- }
159
- if (import.meta.url === `file://${process.argv[1]}`) {
160
- main$1().catch((error) => {
161
- console.error("Fatal error:", error);
162
- process.exit(1);
163
- });
116
+ process.exit(0);
117
+ }
118
+ const token = args[args.indexOf("--token") + 1] || process.env.GITHUB_TOKEN;
119
+ const owner = args[args.indexOf("--owner") + 1];
120
+ const repo = args[args.indexOf("--repo") + 1];
121
+ const dryRun = args.includes("--dry-run");
122
+ const includeArea = args.includes("--include-area");
123
+ const areaLabels = [];
124
+ let i = 0;
125
+ while ((i = args.indexOf("--area", i)) !== -1) {
126
+ areaLabels.push(args[i + 1]);
127
+ i++;
128
+ }
129
+ if (!token) {
130
+ console.error("❌ Error: GitHub token is required");
131
+ console.error(" Use --token <token> or set GITHUB_TOKEN env var");
132
+ process.exit(1);
133
+ }
134
+ if (!owner || !repo) {
135
+ console.error("❌ Error: --owner and --repo are required");
136
+ process.exit(1);
137
+ }
138
+ await applyStandardLabels({
139
+ token,
140
+ owner,
141
+ repo,
142
+ dryRun,
143
+ includeArea,
144
+ areaLabels: areaLabels.length > 0 ? areaLabels : void 0
145
+ });
164
146
  }
147
+ if (import.meta.url === `file://${process.argv[1]}`) main$1().catch((error) => {
148
+ console.error("Fatal error:", error);
149
+ process.exit(1);
150
+ });
151
+ //#endregion
152
+ //#region src/cli.ts
153
+ /**
154
+ * CLI Interface for GitHub Actions
155
+ *
156
+ * Usage:
157
+ * github-actions triage
158
+ *
159
+ * Environment Variables:
160
+ * GITHUB_TOKEN - GitHub authentication token
161
+ * GITHUB_REPOSITORY - Repository (owner/repo)
162
+ * ISSUE_NUMBER - Issue number to triage
163
+ * ISSUE_TITLE - Issue title
164
+ * ISSUE_BODY - Issue body (optional)
165
+ * ISSUE_AUTHOR - Issue author username
166
+ * CONFIG - JSON config string or file path (optional)
167
+ */
165
168
  async function main() {
166
- const command = process.argv[2];
167
- if (!command || command === "--help" || command === "-h") {
168
- showHelp();
169
- process.exit(0);
170
- }
171
- if (command === "triage") {
172
- await runTriage();
173
- } else if (command === "labels") {
174
- await runLabels();
175
- } else {
176
- console.error(`Unknown command: ${command}`);
177
- showHelp();
178
- process.exit(1);
179
- }
169
+ const command = process.argv[2];
170
+ if (!command || command === "--help" || command === "-h") {
171
+ showHelp();
172
+ process.exit(0);
173
+ }
174
+ if (command === "triage") await runTriage();
175
+ else if (command === "labels") await runLabels();
176
+ else {
177
+ console.error(`Unknown command: ${command}`);
178
+ showHelp();
179
+ process.exit(1);
180
+ }
180
181
  }
181
182
  async function runLabels() {
182
- const args = process.argv.slice(3);
183
- const token = args[args.indexOf("--token") + 1] || process.env.GITHUB_TOKEN;
184
- const owner = args[args.indexOf("--owner") + 1];
185
- const repo = args[args.indexOf("--repo") + 1];
186
- const dryRun = args.includes("--dry-run");
187
- const includeArea = args.includes("--include-area");
188
- const areaLabels = [];
189
- let i = 0;
190
- while ((i = args.indexOf("--area", i)) !== -1) {
191
- areaLabels.push(args[i + 1]);
192
- i++;
193
- }
194
- if (!token) {
195
- console.error("❌ Error: GitHub token is required");
196
- console.error(" Use --token <token> or set GITHUB_TOKEN env var");
197
- process.exit(1);
198
- }
199
- if (!owner || !repo) {
200
- console.error("❌ Error: --owner and --repo are required");
201
- process.exit(1);
202
- }
203
- await applyStandardLabels({
204
- token,
205
- owner,
206
- repo,
207
- dryRun,
208
- includeArea,
209
- areaLabels: areaLabels.length > 0 ? areaLabels : void 0
210
- });
183
+ const args = process.argv.slice(3);
184
+ const token = args[args.indexOf("--token") + 1] || process.env.GITHUB_TOKEN;
185
+ const owner = args[args.indexOf("--owner") + 1];
186
+ const repo = args[args.indexOf("--repo") + 1];
187
+ const dryRun = args.includes("--dry-run");
188
+ const includeArea = args.includes("--include-area");
189
+ const areaLabels = [];
190
+ let i = 0;
191
+ while ((i = args.indexOf("--area", i)) !== -1) {
192
+ areaLabels.push(args[i + 1]);
193
+ i++;
194
+ }
195
+ if (!token) {
196
+ console.error("❌ Error: GitHub token is required");
197
+ console.error(" Use --token <token> or set GITHUB_TOKEN env var");
198
+ process.exit(1);
199
+ }
200
+ if (!owner || !repo) {
201
+ console.error("❌ Error: --owner and --repo are required");
202
+ process.exit(1);
203
+ }
204
+ await applyStandardLabels({
205
+ token,
206
+ owner,
207
+ repo,
208
+ dryRun,
209
+ includeArea,
210
+ areaLabels: areaLabels.length > 0 ? areaLabels : void 0
211
+ });
211
212
  }
212
213
  async function runTriage() {
213
- const token = process.env.GITHUB_TOKEN;
214
- const repository = process.env.GITHUB_REPOSITORY;
215
- const issueNumber = process.env.ISSUE_NUMBER;
216
- const issueTitle = process.env.ISSUE_TITLE;
217
- const issueBody = process.env.ISSUE_BODY;
218
- const issueAuthor = process.env.ISSUE_AUTHOR;
219
- if (!token || !repository || !issueNumber || !issueTitle || !issueAuthor) {
220
- console.error("Missing required environment variables:");
221
- console.error(" GITHUB_TOKEN");
222
- console.error(" GITHUB_REPOSITORY");
223
- console.error(" ISSUE_NUMBER");
224
- console.error(" ISSUE_TITLE");
225
- console.error(" ISSUE_AUTHOR");
226
- process.exit(1);
227
- }
228
- const [owner, repo] = repository.split("/");
229
- const config = loadConfig();
230
- const context = {
231
- token,
232
- owner,
233
- repo,
234
- issueNumber: parseInt(issueNumber, 10),
235
- issueTitle,
236
- issueBody,
237
- issueAuthor,
238
- config
239
- };
240
- const result = await triageIssue(context);
241
- if (!result.success) {
242
- console.error("Triage failed");
243
- process.exit(1);
244
- }
245
- console.log("Triage successful");
246
- process.exit(0);
214
+ const token = process.env.GITHUB_TOKEN;
215
+ const repository = process.env.GITHUB_REPOSITORY;
216
+ const issueNumber = process.env.ISSUE_NUMBER;
217
+ const issueTitle = process.env.ISSUE_TITLE;
218
+ const issueBody = process.env.ISSUE_BODY;
219
+ const issueAuthor = process.env.ISSUE_AUTHOR;
220
+ if (!token || !repository || !issueNumber || !issueTitle || !issueAuthor) {
221
+ console.error("Missing required environment variables:");
222
+ console.error(" GITHUB_TOKEN");
223
+ console.error(" GITHUB_REPOSITORY");
224
+ console.error(" ISSUE_NUMBER");
225
+ console.error(" ISSUE_TITLE");
226
+ console.error(" ISSUE_AUTHOR");
227
+ process.exit(1);
228
+ }
229
+ const [owner, repo] = repository.split("/");
230
+ const config = loadConfig();
231
+ if (!(await triageIssue({
232
+ token,
233
+ owner,
234
+ repo,
235
+ issueNumber: parseInt(issueNumber, 10),
236
+ issueTitle,
237
+ issueBody,
238
+ issueAuthor,
239
+ config
240
+ })).success) {
241
+ console.error("Triage failed");
242
+ process.exit(1);
243
+ }
244
+ console.log("Triage successful");
245
+ process.exit(0);
247
246
  }
248
247
  function loadConfig() {
249
- const configEnv = process.env.CONFIG;
250
- if (!configEnv) {
251
- return {
252
- repoDescription: "GitHub repository"
253
- };
254
- }
255
- try {
256
- return JSON.parse(configEnv);
257
- } catch {
258
- try {
259
- const configFile = readFileSync(configEnv, "utf-8");
260
- return JSON.parse(configFile);
261
- } catch (error) {
262
- console.error("Error loading config:", error.message);
263
- return {
264
- repoDescription: "GitHub repository"
265
- };
266
- }
267
- }
248
+ const configEnv = process.env.CONFIG;
249
+ if (!configEnv) return { repoDescription: "GitHub repository" };
250
+ try {
251
+ return JSON.parse(configEnv);
252
+ } catch {
253
+ try {
254
+ const configFile = readFileSync(configEnv, "utf-8");
255
+ return JSON.parse(configFile);
256
+ } catch (error) {
257
+ console.error("Error loading config:", error.message);
258
+ return { repoDescription: "GitHub repository" };
259
+ }
260
+ }
268
261
  }
269
262
  function showHelp() {
270
- console.log(`
263
+ console.log(`
271
264
  @happyvertical/github-actions CLI
272
265
 
273
266
  Usage:
@@ -319,7 +312,9 @@ Examples:
319
312
  `);
320
313
  }
321
314
  main().catch((error) => {
322
- console.error("Fatal error:", error);
323
- process.exit(1);
315
+ console.error("Fatal error:", error);
316
+ process.exit(1);
324
317
  });
325
- //# sourceMappingURL=cli.js.map
318
+ //#endregion
319
+
320
+ //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/labels-cli.ts","../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Label Management CLI\n *\n * Apply standard labels across repositories\n */\n\nimport { getRepository } from '@happyvertical/repos';\nimport {\n AREA_LABEL_TEMPLATE,\n getAllStandardLabels,\n type LabelDefinition,\n} from './shared/labels.js';\n\ninterface CliOptions {\n token: string;\n owner: string;\n repo: string;\n dryRun?: boolean;\n includeArea?: boolean;\n areaLabels?: string[];\n}\n\n/**\n * Apply standard labels to a repository\n */\nexport async function applyStandardLabels(options: CliOptions): Promise<void> {\n console.log(\n `\\n🏷️ Applying standard labels to ${options.owner}/${options.repo}`,\n );\n\n if (options.dryRun) {\n console.log('🔍 DRY RUN MODE - No changes will be made\\n');\n }\n\n try {\n const repo = await getRepository({\n type: 'github',\n owner: options.owner,\n repo: options.repo,\n token: options.token,\n });\n\n // Get standard labels\n const standardLabels = getAllStandardLabels();\n\n // Add area labels if requested\n const labelsToApply: LabelDefinition[] = [...standardLabels];\n\n if (options.includeArea) {\n const areaLabels = options.areaLabels\n ? options.areaLabels.map((name) => ({\n name: `area: ${name}`,\n color: 'fbca04',\n description: `${name.charAt(0).toUpperCase() + name.slice(1)} area`,\n }))\n : AREA_LABEL_TEMPLATE;\n\n labelsToApply.push(...areaLabels);\n }\n\n console.log(`📋 Found ${labelsToApply.length} labels to create/update:\\n`);\n\n // Group by category for display\n const byCategory: Record<string, LabelDefinition[]> = {};\n for (const label of labelsToApply) {\n const category = label.name.split(':')[0];\n if (!byCategory[category]) {\n byCategory[category] = [];\n }\n byCategory[category].push(label);\n }\n\n for (const [category, labels] of Object.entries(byCategory)) {\n console.log(` ${category}:`);\n for (const label of labels) {\n console.log(\n ` - ${label.name} (#${label.color}) - ${label.description}`,\n );\n }\n }\n\n if (options.dryRun) {\n console.log('\\n✅ Dry run complete - no changes made');\n return;\n }\n\n // Apply labels\n console.log('\\n🔧 Creating/updating labels...\\n');\n\n let created = 0;\n let updated = 0;\n let errors = 0;\n\n for (const label of labelsToApply) {\n try {\n // Try to update first\n const existingLabels = await repo.listLabels();\n const existing = existingLabels.find((l) => l.name === label.name);\n\n if (existing) {\n await repo.updateLabel(label.name, {\n name: label.name,\n color: label.color,\n description: label.description,\n });\n console.log(` ✅ Updated: ${label.name}`);\n updated++;\n } else {\n await repo.createLabel({\n name: label.name,\n color: label.color,\n description: label.description,\n });\n console.log(` ✨ Created: ${label.name}`);\n created++;\n }\n } catch (error) {\n console.error(\n ` ❌ Error with ${label.name}: ${(error as Error).message}`,\n );\n errors++;\n }\n }\n\n console.log(`\\n✅ Label sync complete!`);\n console.log(` Created: ${created}`);\n console.log(` Updated: ${updated}`);\n if (errors > 0) {\n console.log(` Errors: ${errors}`);\n }\n } catch (error) {\n console.error('❌ Failed to apply labels:', (error as Error).message);\n throw error;\n }\n}\n\n/**\n * CLI entry point\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\nLabel Management CLI\n\nUsage: github-actions labels [options]\n\nOptions:\n --token <token> GitHub token (or GITHUB_TOKEN env var)\n --owner <owner> Repository owner\n --repo <repo> Repository name\n --dry-run Preview changes without applying\n --include-area Include area labels\n --area <label> Custom area label (can be used multiple times)\n -h, --help Show this help message\n\nExamples:\n # Dry run\n github-actions labels --owner happyvertical --repo sdk --dry-run\n\n # Apply standard labels\n github-actions labels --owner happyvertical --repo sdk\n\n # Apply with custom area labels\n github-actions labels --owner happyvertical --repo sdk --include-area --area core --area api --area ui\n\nEnvironment Variables:\n GITHUB_TOKEN GitHub personal access token\n`);\n process.exit(0);\n }\n\n const token = args[args.indexOf('--token') + 1] || process.env.GITHUB_TOKEN;\n const owner = args[args.indexOf('--owner') + 1];\n const repo = args[args.indexOf('--repo') + 1];\n const dryRun = args.includes('--dry-run');\n const includeArea = args.includes('--include-area');\n\n // Parse custom area labels\n const areaLabels: string[] = [];\n let i = 0;\n while ((i = args.indexOf('--area', i)) !== -1) {\n areaLabels.push(args[i + 1]);\n i++;\n }\n\n if (!token) {\n console.error('❌ Error: GitHub token is required');\n console.error(' Use --token <token> or set GITHUB_TOKEN env var');\n process.exit(1);\n }\n\n if (!owner || !repo) {\n console.error('❌ Error: --owner and --repo are required');\n process.exit(1);\n }\n\n await applyStandardLabels({\n token,\n owner,\n repo,\n dryRun,\n includeArea,\n areaLabels: areaLabels.length > 0 ? areaLabels : undefined,\n });\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n });\n}\n","#!/usr/bin/env node\n\n/**\n * CLI Interface for GitHub Actions\n *\n * Usage:\n * github-actions triage\n *\n * Environment Variables:\n * GITHUB_TOKEN - GitHub authentication token\n * GITHUB_REPOSITORY - Repository (owner/repo)\n * ISSUE_NUMBER - Issue number to triage\n * ISSUE_TITLE - Issue title\n * ISSUE_BODY - Issue body (optional)\n * ISSUE_AUTHOR - Issue author username\n * CONFIG - JSON config string or file path (optional)\n */\n\nimport { readFileSync } from 'node:fs';\nimport { type TriageConfig, type TriageContext, triageIssue } from './index.js';\nimport { applyStandardLabels } from './labels-cli.js';\n\nasync function main() {\n const command = process.argv[2];\n\n if (!command || command === '--help' || command === '-h') {\n showHelp();\n process.exit(0);\n }\n\n if (command === 'triage') {\n await runTriage();\n } else if (command === 'labels') {\n await runLabels();\n } else {\n console.error(`Unknown command: ${command}`);\n showHelp();\n process.exit(1);\n }\n}\n\nasync function runLabels() {\n const args = process.argv.slice(3);\n const token = args[args.indexOf('--token') + 1] || process.env.GITHUB_TOKEN;\n const owner = args[args.indexOf('--owner') + 1];\n const repo = args[args.indexOf('--repo') + 1];\n const dryRun = args.includes('--dry-run');\n const includeArea = args.includes('--include-area');\n\n // Parse custom area labels\n const areaLabels: string[] = [];\n let i = 0;\n while ((i = args.indexOf('--area', i)) !== -1) {\n areaLabels.push(args[i + 1]);\n i++;\n }\n\n if (!token) {\n console.error('❌ Error: GitHub token is required');\n console.error(' Use --token <token> or set GITHUB_TOKEN env var');\n process.exit(1);\n }\n\n if (!owner || !repo) {\n console.error('❌ Error: --owner and --repo are required');\n process.exit(1);\n }\n\n await applyStandardLabels({\n token,\n owner,\n repo,\n dryRun,\n includeArea,\n areaLabels: areaLabels.length > 0 ? areaLabels : undefined,\n });\n}\n\nasync function runTriage() {\n // Get required environment variables\n const token = process.env.GITHUB_TOKEN;\n const repository = process.env.GITHUB_REPOSITORY;\n const issueNumber = process.env.ISSUE_NUMBER;\n const issueTitle = process.env.ISSUE_TITLE;\n const issueBody = process.env.ISSUE_BODY;\n const issueAuthor = process.env.ISSUE_AUTHOR;\n\n if (!token || !repository || !issueNumber || !issueTitle || !issueAuthor) {\n console.error('Missing required environment variables:');\n console.error(' GITHUB_TOKEN');\n console.error(' GITHUB_REPOSITORY');\n console.error(' ISSUE_NUMBER');\n console.error(' ISSUE_TITLE');\n console.error(' ISSUE_AUTHOR');\n process.exit(1);\n }\n\n const [owner, repo] = repository.split('/');\n\n // Load configuration\n const config = loadConfig();\n\n // Build context\n const context: TriageContext = {\n token,\n owner,\n repo,\n issueNumber: parseInt(issueNumber, 10),\n issueTitle,\n issueBody,\n issueAuthor,\n config,\n };\n\n // Run triage\n const result = await triageIssue(context);\n\n if (!result.success) {\n console.error('Triage failed');\n process.exit(1);\n }\n\n console.log('Triage successful');\n process.exit(0);\n}\n\nfunction loadConfig(): TriageConfig {\n const configEnv = process.env.CONFIG;\n\n if (!configEnv) {\n // Default config\n return {\n repoDescription: 'GitHub repository',\n };\n }\n\n try {\n // Try to parse as JSON\n return JSON.parse(configEnv) as TriageConfig;\n } catch {\n // Try to read as file path\n try {\n const configFile = readFileSync(configEnv, 'utf-8');\n return JSON.parse(configFile) as TriageConfig;\n } catch (error) {\n console.error('Error loading config:', (error as Error).message);\n return {\n repoDescription: 'GitHub repository',\n };\n }\n }\n}\n\nfunction showHelp() {\n console.log(`\n@happyvertical/github-actions CLI\n\nUsage:\n github-actions <command> [options]\n\nCommands:\n triage Run AI-powered issue triage\n labels Apply standard labels to repository\n\nEnvironment Variables:\n GITHUB_TOKEN GitHub authentication token (required)\n GITHUB_REPOSITORY Repository in owner/repo format (required)\n ISSUE_NUMBER Issue number to triage (required)\n ISSUE_TITLE Issue title (required)\n ISSUE_BODY Issue body (optional)\n ISSUE_AUTHOR Issue author username (required)\n CONFIG JSON config string or file path (optional)\n\nConfig Format:\n {\n \"repoDescription\": \"Repository description for AI\",\n \"packagePattern\": \"@happyvertical/*\",\n \"packageExamples\": [\"@happyvertical/ai\", \"@happyvertical/sql\"],\n \"projectEnabled\": true,\n \"projectId\": \"PVT_xxx\",\n \"statusFieldId\": \"PVTSSF_xxx\",\n \"statusOptions\": {\n \"To Do\": \"option_id_1\",\n \"In Progress\": \"option_id_2\"\n }\n }\n\nExamples:\n # Basic triage with environment variables\n export GITHUB_TOKEN=\"ghp_xxx\"\n export GITHUB_REPOSITORY=\"owner/repo\"\n export ISSUE_NUMBER=\"123\"\n export ISSUE_TITLE=\"Bug report\"\n export ISSUE_AUTHOR=\"username\"\n github-actions triage\n\n # Triage with config file\n export CONFIG=\".github/triage-config.json\"\n github-actions triage\n\n # Triage with inline config\n export CONFIG='{\"repoDescription\":\"My project\",\"packagePattern\":\"@myorg/*\"}'\n github-actions triage\n`);\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n"],"names":["main"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":[],"sources":["../src/labels-cli.ts","../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Label Management CLI\n *\n * Apply standard labels across repositories\n */\n\nimport { getRepository } from '@happyvertical/repos';\nimport {\n AREA_LABEL_TEMPLATE,\n getAllStandardLabels,\n type LabelDefinition,\n} from './shared/labels.js';\n\ninterface CliOptions {\n token: string;\n owner: string;\n repo: string;\n dryRun?: boolean;\n includeArea?: boolean;\n areaLabels?: string[];\n}\n\n/**\n * Apply standard labels to a repository\n */\nexport async function applyStandardLabels(options: CliOptions): Promise<void> {\n console.log(\n `\\n🏷️ Applying standard labels to ${options.owner}/${options.repo}`,\n );\n\n if (options.dryRun) {\n console.log('🔍 DRY RUN MODE - No changes will be made\\n');\n }\n\n try {\n const repo = await getRepository({\n type: 'github',\n owner: options.owner,\n repo: options.repo,\n token: options.token,\n });\n\n // Get standard labels\n const standardLabels = getAllStandardLabels();\n\n // Add area labels if requested\n const labelsToApply: LabelDefinition[] = [...standardLabels];\n\n if (options.includeArea) {\n const areaLabels = options.areaLabels\n ? options.areaLabels.map((name) => ({\n name: `area: ${name}`,\n color: 'fbca04',\n description: `${name.charAt(0).toUpperCase() + name.slice(1)} area`,\n }))\n : AREA_LABEL_TEMPLATE;\n\n labelsToApply.push(...areaLabels);\n }\n\n console.log(`📋 Found ${labelsToApply.length} labels to create/update:\\n`);\n\n // Group by category for display\n const byCategory: Record<string, LabelDefinition[]> = {};\n for (const label of labelsToApply) {\n const category = label.name.split(':')[0];\n if (!byCategory[category]) {\n byCategory[category] = [];\n }\n byCategory[category].push(label);\n }\n\n for (const [category, labels] of Object.entries(byCategory)) {\n console.log(` ${category}:`);\n for (const label of labels) {\n console.log(\n ` - ${label.name} (#${label.color}) - ${label.description}`,\n );\n }\n }\n\n if (options.dryRun) {\n console.log('\\n✅ Dry run complete - no changes made');\n return;\n }\n\n // Apply labels\n console.log('\\n🔧 Creating/updating labels...\\n');\n\n let created = 0;\n let updated = 0;\n let errors = 0;\n\n for (const label of labelsToApply) {\n try {\n // Try to update first\n const existingLabels = await repo.listLabels();\n const existing = existingLabels.find((l) => l.name === label.name);\n\n if (existing) {\n await repo.updateLabel(label.name, {\n name: label.name,\n color: label.color,\n description: label.description,\n });\n console.log(` ✅ Updated: ${label.name}`);\n updated++;\n } else {\n await repo.createLabel({\n name: label.name,\n color: label.color,\n description: label.description,\n });\n console.log(` ✨ Created: ${label.name}`);\n created++;\n }\n } catch (error) {\n console.error(\n ` ❌ Error with ${label.name}: ${(error as Error).message}`,\n );\n errors++;\n }\n }\n\n console.log(`\\n✅ Label sync complete!`);\n console.log(` Created: ${created}`);\n console.log(` Updated: ${updated}`);\n if (errors > 0) {\n console.log(` Errors: ${errors}`);\n }\n } catch (error) {\n console.error('❌ Failed to apply labels:', (error as Error).message);\n throw error;\n }\n}\n\n/**\n * CLI entry point\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.includes('--help') || args.includes('-h')) {\n console.log(`\nLabel Management CLI\n\nUsage: github-actions labels [options]\n\nOptions:\n --token <token> GitHub token (or GITHUB_TOKEN env var)\n --owner <owner> Repository owner\n --repo <repo> Repository name\n --dry-run Preview changes without applying\n --include-area Include area labels\n --area <label> Custom area label (can be used multiple times)\n -h, --help Show this help message\n\nExamples:\n # Dry run\n github-actions labels --owner happyvertical --repo sdk --dry-run\n\n # Apply standard labels\n github-actions labels --owner happyvertical --repo sdk\n\n # Apply with custom area labels\n github-actions labels --owner happyvertical --repo sdk --include-area --area core --area api --area ui\n\nEnvironment Variables:\n GITHUB_TOKEN GitHub personal access token\n`);\n process.exit(0);\n }\n\n const token = args[args.indexOf('--token') + 1] || process.env.GITHUB_TOKEN;\n const owner = args[args.indexOf('--owner') + 1];\n const repo = args[args.indexOf('--repo') + 1];\n const dryRun = args.includes('--dry-run');\n const includeArea = args.includes('--include-area');\n\n // Parse custom area labels\n const areaLabels: string[] = [];\n let i = 0;\n while ((i = args.indexOf('--area', i)) !== -1) {\n areaLabels.push(args[i + 1]);\n i++;\n }\n\n if (!token) {\n console.error('❌ Error: GitHub token is required');\n console.error(' Use --token <token> or set GITHUB_TOKEN env var');\n process.exit(1);\n }\n\n if (!owner || !repo) {\n console.error('❌ Error: --owner and --repo are required');\n process.exit(1);\n }\n\n await applyStandardLabels({\n token,\n owner,\n repo,\n dryRun,\n includeArea,\n areaLabels: areaLabels.length > 0 ? areaLabels : undefined,\n });\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n });\n}\n","#!/usr/bin/env node\n\n/**\n * CLI Interface for GitHub Actions\n *\n * Usage:\n * github-actions triage\n *\n * Environment Variables:\n * GITHUB_TOKEN - GitHub authentication token\n * GITHUB_REPOSITORY - Repository (owner/repo)\n * ISSUE_NUMBER - Issue number to triage\n * ISSUE_TITLE - Issue title\n * ISSUE_BODY - Issue body (optional)\n * ISSUE_AUTHOR - Issue author username\n * CONFIG - JSON config string or file path (optional)\n */\n\nimport { readFileSync } from 'node:fs';\nimport { type TriageConfig, type TriageContext, triageIssue } from './index.js';\nimport { applyStandardLabels } from './labels-cli.js';\n\nasync function main() {\n const command = process.argv[2];\n\n if (!command || command === '--help' || command === '-h') {\n showHelp();\n process.exit(0);\n }\n\n if (command === 'triage') {\n await runTriage();\n } else if (command === 'labels') {\n await runLabels();\n } else {\n console.error(`Unknown command: ${command}`);\n showHelp();\n process.exit(1);\n }\n}\n\nasync function runLabels() {\n const args = process.argv.slice(3);\n const token = args[args.indexOf('--token') + 1] || process.env.GITHUB_TOKEN;\n const owner = args[args.indexOf('--owner') + 1];\n const repo = args[args.indexOf('--repo') + 1];\n const dryRun = args.includes('--dry-run');\n const includeArea = args.includes('--include-area');\n\n // Parse custom area labels\n const areaLabels: string[] = [];\n let i = 0;\n while ((i = args.indexOf('--area', i)) !== -1) {\n areaLabels.push(args[i + 1]);\n i++;\n }\n\n if (!token) {\n console.error('❌ Error: GitHub token is required');\n console.error(' Use --token <token> or set GITHUB_TOKEN env var');\n process.exit(1);\n }\n\n if (!owner || !repo) {\n console.error('❌ Error: --owner and --repo are required');\n process.exit(1);\n }\n\n await applyStandardLabels({\n token,\n owner,\n repo,\n dryRun,\n includeArea,\n areaLabels: areaLabels.length > 0 ? areaLabels : undefined,\n });\n}\n\nasync function runTriage() {\n // Get required environment variables\n const token = process.env.GITHUB_TOKEN;\n const repository = process.env.GITHUB_REPOSITORY;\n const issueNumber = process.env.ISSUE_NUMBER;\n const issueTitle = process.env.ISSUE_TITLE;\n const issueBody = process.env.ISSUE_BODY;\n const issueAuthor = process.env.ISSUE_AUTHOR;\n\n if (!token || !repository || !issueNumber || !issueTitle || !issueAuthor) {\n console.error('Missing required environment variables:');\n console.error(' GITHUB_TOKEN');\n console.error(' GITHUB_REPOSITORY');\n console.error(' ISSUE_NUMBER');\n console.error(' ISSUE_TITLE');\n console.error(' ISSUE_AUTHOR');\n process.exit(1);\n }\n\n const [owner, repo] = repository.split('/');\n\n // Load configuration\n const config = loadConfig();\n\n // Build context\n const context: TriageContext = {\n token,\n owner,\n repo,\n issueNumber: parseInt(issueNumber, 10),\n issueTitle,\n issueBody,\n issueAuthor,\n config,\n };\n\n // Run triage\n const result = await triageIssue(context);\n\n if (!result.success) {\n console.error('Triage failed');\n process.exit(1);\n }\n\n console.log('Triage successful');\n process.exit(0);\n}\n\nfunction loadConfig(): TriageConfig {\n const configEnv = process.env.CONFIG;\n\n if (!configEnv) {\n // Default config\n return {\n repoDescription: 'GitHub repository',\n };\n }\n\n try {\n // Try to parse as JSON\n return JSON.parse(configEnv) as TriageConfig;\n } catch {\n // Try to read as file path\n try {\n const configFile = readFileSync(configEnv, 'utf-8');\n return JSON.parse(configFile) as TriageConfig;\n } catch (error) {\n console.error('Error loading config:', (error as Error).message);\n return {\n repoDescription: 'GitHub repository',\n };\n }\n }\n}\n\nfunction showHelp() {\n console.log(`\n@happyvertical/github-actions CLI\n\nUsage:\n github-actions <command> [options]\n\nCommands:\n triage Run AI-powered issue triage\n labels Apply standard labels to repository\n\nEnvironment Variables:\n GITHUB_TOKEN GitHub authentication token (required)\n GITHUB_REPOSITORY Repository in owner/repo format (required)\n ISSUE_NUMBER Issue number to triage (required)\n ISSUE_TITLE Issue title (required)\n ISSUE_BODY Issue body (optional)\n ISSUE_AUTHOR Issue author username (required)\n CONFIG JSON config string or file path (optional)\n\nConfig Format:\n {\n \"repoDescription\": \"Repository description for AI\",\n \"packagePattern\": \"@happyvertical/*\",\n \"packageExamples\": [\"@happyvertical/ai\", \"@happyvertical/sql\"],\n \"projectEnabled\": true,\n \"projectId\": \"PVT_xxx\",\n \"statusFieldId\": \"PVTSSF_xxx\",\n \"statusOptions\": {\n \"To Do\": \"option_id_1\",\n \"In Progress\": \"option_id_2\"\n }\n }\n\nExamples:\n # Basic triage with environment variables\n export GITHUB_TOKEN=\"ghp_xxx\"\n export GITHUB_REPOSITORY=\"owner/repo\"\n export ISSUE_NUMBER=\"123\"\n export ISSUE_TITLE=\"Bug report\"\n export ISSUE_AUTHOR=\"username\"\n github-actions triage\n\n # Triage with config file\n export CONFIG=\".github/triage-config.json\"\n github-actions triage\n\n # Triage with inline config\n export CONFIG='{\"repoDescription\":\"My project\",\"packagePattern\":\"@myorg/*\"}'\n github-actions triage\n`);\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n"],"mappings":"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"}