@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.
- package/dist/cli/claude-context.js +17 -17
- package/dist/cli/claude-context.js.map +1 -1
- package/dist/cli.js +227 -232
- package/dist/cli.js.map +1 -1
- package/dist/index.js +2 -637
- package/dist/src-CezXcNYi.js +1318 -0
- package/dist/src-CezXcNYi.js.map +1 -0
- package/package.json +6 -6
- package/dist/index-v2-CqFKwTm8.js +0 -687
- package/dist/index-v2-CqFKwTm8.js.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdirSync
|
|
2
|
+
import { copyFileSync, existsSync, mkdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
//#
|
|
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"],"
|
|
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 {
|
|
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:
|
|
6
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
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
|
-
|
|
323
|
-
|
|
315
|
+
console.error("Fatal error:", error);
|
|
316
|
+
process.exit(1);
|
|
324
317
|
});
|
|
325
|
-
//#
|
|
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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"}
|