@bretwardjames/ghp-cli 0.1.0

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.
Files changed (94) hide show
  1. package/README.md +176 -0
  2. package/dist/branch-linker.d.ts +15 -0
  3. package/dist/branch-linker.d.ts.map +1 -0
  4. package/dist/branch-linker.js +60 -0
  5. package/dist/branch-linker.js.map +1 -0
  6. package/dist/commands/add-issue.d.ts +11 -0
  7. package/dist/commands/add-issue.d.ts.map +1 -0
  8. package/dist/commands/add-issue.js +228 -0
  9. package/dist/commands/add-issue.js.map +1 -0
  10. package/dist/commands/assign.d.ts +6 -0
  11. package/dist/commands/assign.d.ts.map +1 -0
  12. package/dist/commands/assign.js +44 -0
  13. package/dist/commands/assign.js.map +1 -0
  14. package/dist/commands/auth.d.ts +6 -0
  15. package/dist/commands/auth.d.ts.map +1 -0
  16. package/dist/commands/auth.js +31 -0
  17. package/dist/commands/auth.js.map +1 -0
  18. package/dist/commands/comment.d.ts +6 -0
  19. package/dist/commands/comment.d.ts.map +1 -0
  20. package/dist/commands/comment.js +83 -0
  21. package/dist/commands/comment.js.map +1 -0
  22. package/dist/commands/config.d.ts +5 -0
  23. package/dist/commands/config.d.ts.map +1 -0
  24. package/dist/commands/config.js +94 -0
  25. package/dist/commands/config.js.map +1 -0
  26. package/dist/commands/done.d.ts +2 -0
  27. package/dist/commands/done.d.ts.map +1 -0
  28. package/dist/commands/done.js +54 -0
  29. package/dist/commands/done.js.map +1 -0
  30. package/dist/commands/link-branch.d.ts +2 -0
  31. package/dist/commands/link-branch.d.ts.map +1 -0
  32. package/dist/commands/link-branch.js +44 -0
  33. package/dist/commands/link-branch.js.map +1 -0
  34. package/dist/commands/move.d.ts +2 -0
  35. package/dist/commands/move.d.ts.map +1 -0
  36. package/dist/commands/move.js +53 -0
  37. package/dist/commands/move.js.map +1 -0
  38. package/dist/commands/open.d.ts +6 -0
  39. package/dist/commands/open.d.ts.map +1 -0
  40. package/dist/commands/open.js +189 -0
  41. package/dist/commands/open.js.map +1 -0
  42. package/dist/commands/plan.d.ts +2 -0
  43. package/dist/commands/plan.d.ts.map +1 -0
  44. package/dist/commands/plan.js +403 -0
  45. package/dist/commands/plan.js.map +1 -0
  46. package/dist/commands/pr.d.ts +7 -0
  47. package/dist/commands/pr.d.ts.map +1 -0
  48. package/dist/commands/pr.js +102 -0
  49. package/dist/commands/pr.js.map +1 -0
  50. package/dist/commands/set-field.d.ts +2 -0
  51. package/dist/commands/set-field.d.ts.map +1 -0
  52. package/dist/commands/set-field.js +69 -0
  53. package/dist/commands/set-field.js.map +1 -0
  54. package/dist/commands/slice.d.ts +8 -0
  55. package/dist/commands/slice.d.ts.map +1 -0
  56. package/dist/commands/slice.js +85 -0
  57. package/dist/commands/slice.js.map +1 -0
  58. package/dist/commands/start.d.ts +7 -0
  59. package/dist/commands/start.d.ts.map +1 -0
  60. package/dist/commands/start.js +153 -0
  61. package/dist/commands/start.js.map +1 -0
  62. package/dist/commands/switch.d.ts +2 -0
  63. package/dist/commands/switch.d.ts.map +1 -0
  64. package/dist/commands/switch.js +44 -0
  65. package/dist/commands/switch.js.map +1 -0
  66. package/dist/commands/unlink-branch.d.ts +2 -0
  67. package/dist/commands/unlink-branch.d.ts.map +1 -0
  68. package/dist/commands/unlink-branch.js +28 -0
  69. package/dist/commands/unlink-branch.js.map +1 -0
  70. package/dist/commands/work.d.ts +9 -0
  71. package/dist/commands/work.d.ts.map +1 -0
  72. package/dist/commands/work.js +118 -0
  73. package/dist/commands/work.js.map +1 -0
  74. package/dist/config.d.ts +44 -0
  75. package/dist/config.d.ts.map +1 -0
  76. package/dist/config.js +88 -0
  77. package/dist/config.js.map +1 -0
  78. package/dist/git-utils.d.ts +55 -0
  79. package/dist/git-utils.d.ts.map +1 -0
  80. package/dist/git-utils.js +140 -0
  81. package/dist/git-utils.js.map +1 -0
  82. package/dist/github-api.d.ts +110 -0
  83. package/dist/github-api.d.ts.map +1 -0
  84. package/dist/github-api.js +579 -0
  85. package/dist/github-api.js.map +1 -0
  86. package/dist/index.d.ts +3 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +149 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/types.d.ts +37 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +2 -0
  93. package/dist/types.js.map +1 -0
  94. package/package.json +48 -0
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # ghp-cli
2
+
3
+ GitHub Projects CLI - manage project boards from your terminal.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g ghp-cli
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Authenticate with GitHub
15
+ ghp auth
16
+
17
+ # View your assigned items
18
+ ghp work
19
+
20
+ # View project board
21
+ ghp plan
22
+
23
+ # Create an issue
24
+ ghp add "Fix login bug"
25
+ ```
26
+
27
+ ## Commands
28
+
29
+ ### Views
30
+
31
+ ```bash
32
+ # Your work (sidebar view)
33
+ ghp work
34
+ ghp work --status "In Progress"
35
+ ghp work --hide-done
36
+
37
+ # Project board
38
+ ghp plan
39
+ ghp plan --mine # Only my items
40
+ ghp plan --status Backlog # List view for single status
41
+ ghp plan --slice type=Bug # Filter by field
42
+ ghp plan bugs # Use configured shortcut
43
+ ```
44
+
45
+ ### Issue Management
46
+
47
+ ```bash
48
+ # Create issue (opens editor with template)
49
+ ghp add "Issue title"
50
+ ghp add -t bug_report # Use specific template
51
+ ghp add --list-templates # List available templates
52
+
53
+ # View issue details
54
+ ghp open 123
55
+ ghp open 123 --browser # Open in browser
56
+
57
+ # Add comment
58
+ ghp comment 123 -m "Fixed in latest commit"
59
+ ghp comment 123 # Opens editor
60
+ ```
61
+
62
+ ### Workflow
63
+
64
+ ```bash
65
+ # Start working on an issue (creates branch, updates status)
66
+ ghp start 123
67
+
68
+ # Mark as done
69
+ ghp done 123
70
+
71
+ # Move to different status
72
+ ghp move 123 "In Review"
73
+
74
+ # Assign users
75
+ ghp assign 123 @username
76
+ ghp assign 123 # Assign to self
77
+ ```
78
+
79
+ ### Branch Management
80
+
81
+ ```bash
82
+ # Switch to issue's branch
83
+ ghp switch 123
84
+
85
+ # Link current branch to issue
86
+ ghp link-branch 123
87
+
88
+ # Unlink branch
89
+ ghp unlink-branch 123
90
+ ```
91
+
92
+ ### Configuration
93
+
94
+ ```bash
95
+ # View config
96
+ ghp config --list
97
+
98
+ # Edit config file
99
+ ghp config --edit
100
+
101
+ # Set individual values
102
+ ghp config mainBranch main
103
+ ```
104
+
105
+ ## Configuration
106
+
107
+ Config file: `~/.config/ghp-cli/config.json`
108
+
109
+ ```json
110
+ {
111
+ "mainBranch": "main",
112
+ "branchPattern": "{user}/{number}-{title}",
113
+ "startWorkingStatus": "In Progress",
114
+ "doneStatus": "Done",
115
+
116
+ "defaults": {
117
+ "plan": {
118
+ "mine": true
119
+ },
120
+ "addIssue": {
121
+ "template": "bug_report",
122
+ "status": "Backlog"
123
+ }
124
+ },
125
+
126
+ "shortcuts": {
127
+ "bugs": {
128
+ "status": "Backlog",
129
+ "slice": ["type=Bug"]
130
+ },
131
+ "mywork": {
132
+ "status": "In Progress",
133
+ "mine": true
134
+ }
135
+ }
136
+ }
137
+ ```
138
+
139
+ ### Shortcuts
140
+
141
+ Define shortcuts for common `ghp plan` filters:
142
+
143
+ ```bash
144
+ ghp plan bugs # Expands to: ghp plan --status Backlog --slice type=Bug
145
+ ghp plan mywork # Expands to: ghp plan --status "In Progress" --mine
146
+ ```
147
+
148
+ ### Slice Filters
149
+
150
+ Filter by any field:
151
+
152
+ ```bash
153
+ --slice type=Bug # Issue type (org-level)
154
+ --slice label=frontend # Labels
155
+ --slice assignee=username # Assignee
156
+ --slice Priority=High # Custom project fields
157
+ --slice Size=Small # Custom project fields
158
+ ```
159
+
160
+ ## Issue Templates
161
+
162
+ Place templates in `.github/ISSUE_TEMPLATE/` in your repo. When creating issues, you can:
163
+
164
+ - Select a template interactively (if no default set)
165
+ - Use `-t <name>` to specify a template
166
+ - Set `defaults.addIssue.template` in config for auto-selection
167
+
168
+ ## Requirements
169
+
170
+ - Node.js >= 18
171
+ - GitHub account with Projects access
172
+ - `gh` CLI recommended (for auth token)
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,15 @@
1
+ interface BranchLink {
2
+ branch: string;
3
+ issueNumber: number;
4
+ issueTitle: string;
5
+ itemId: string;
6
+ repo: string;
7
+ linkedAt: string;
8
+ }
9
+ export declare function linkBranch(branch: string, issueNumber: number, issueTitle: string, itemId: string, repo: string): void;
10
+ export declare function unlinkBranch(repo: string, issueNumber: number): boolean;
11
+ export declare function getBranchForIssue(repo: string, issueNumber: number): string | null;
12
+ export declare function getIssueForBranch(repo: string, branch: string): BranchLink | null;
13
+ export declare function getAllLinksForRepo(repo: string): BranchLink[];
14
+ export {};
15
+ //# sourceMappingURL=branch-linker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-linker.d.ts","sourceRoot":"","sources":["../src/branch-linker.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB;AAwBD,wBAAgB,UAAU,CACtB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACb,IAAI,CAkBN;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAUvE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIlF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAGjF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAG7D"}
@@ -0,0 +1,60 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+ const DATA_DIR = join(homedir(), '.config', 'ghp-cli');
5
+ const LINKS_FILE = join(DATA_DIR, 'branch-links.json');
6
+ function loadLinks() {
7
+ try {
8
+ if (existsSync(LINKS_FILE)) {
9
+ const data = readFileSync(LINKS_FILE, 'utf-8');
10
+ return JSON.parse(data);
11
+ }
12
+ }
13
+ catch {
14
+ // Ignore errors
15
+ }
16
+ return [];
17
+ }
18
+ function saveLinks(links) {
19
+ if (!existsSync(DATA_DIR)) {
20
+ mkdirSync(DATA_DIR, { recursive: true });
21
+ }
22
+ writeFileSync(LINKS_FILE, JSON.stringify(links, null, 2));
23
+ }
24
+ export function linkBranch(branch, issueNumber, issueTitle, itemId, repo) {
25
+ const links = loadLinks();
26
+ // Remove existing link for this branch or issue in this repo
27
+ const filtered = links.filter(l => !(l.repo === repo && (l.branch === branch || l.issueNumber === issueNumber)));
28
+ filtered.push({
29
+ branch,
30
+ issueNumber,
31
+ issueTitle,
32
+ itemId,
33
+ repo,
34
+ linkedAt: new Date().toISOString(),
35
+ });
36
+ saveLinks(filtered);
37
+ }
38
+ export function unlinkBranch(repo, issueNumber) {
39
+ const links = loadLinks();
40
+ const filtered = links.filter(l => !(l.repo === repo && l.issueNumber === issueNumber));
41
+ if (filtered.length === links.length) {
42
+ return false; // Nothing was removed
43
+ }
44
+ saveLinks(filtered);
45
+ return true;
46
+ }
47
+ export function getBranchForIssue(repo, issueNumber) {
48
+ const links = loadLinks();
49
+ const link = links.find(l => l.repo === repo && l.issueNumber === issueNumber);
50
+ return link?.branch || null;
51
+ }
52
+ export function getIssueForBranch(repo, branch) {
53
+ const links = loadLinks();
54
+ return links.find(l => l.repo === repo && l.branch === branch) || null;
55
+ }
56
+ export function getAllLinksForRepo(repo) {
57
+ const links = loadLinks();
58
+ return links.filter(l => l.repo === repo);
59
+ }
60
+ //# sourceMappingURL=branch-linker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-linker.js","sourceRoot":"","sources":["../src/branch-linker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ interface AddIssueOptions {
2
+ body?: string;
3
+ project?: string;
4
+ status?: string;
5
+ edit?: boolean;
6
+ template?: string;
7
+ listTemplates?: boolean;
8
+ }
9
+ export declare function addIssueCommand(title: string, options: AddIssueOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=add-issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-issue.d.ts","sourceRoot":"","sources":["../../src/commands/add-issue.ts"],"names":[],"mappings":"AASA,UAAU,eAAe;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AA6DD,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6L5F"}
@@ -0,0 +1,228 @@
1
+ import chalk from 'chalk';
2
+ import { api } from '../github-api.js';
3
+ import { detectRepository } from '../git-utils.js';
4
+ import { getAddIssueDefaults } from '../config.js';
5
+ import { spawn } from 'child_process';
6
+ import { writeFileSync, readFileSync, unlinkSync, existsSync, readdirSync } from 'fs';
7
+ import { tmpdir } from 'os';
8
+ import { join } from 'path';
9
+ async function openEditor(initialContent) {
10
+ const editor = process.env.EDITOR || process.env.VISUAL || 'vim';
11
+ const tmpFile = join(tmpdir(), `ghp-issue-${Date.now()}.md`);
12
+ writeFileSync(tmpFile, initialContent);
13
+ return new Promise((resolve, reject) => {
14
+ const child = spawn(editor, [tmpFile], {
15
+ stdio: 'inherit',
16
+ });
17
+ child.on('exit', (code) => {
18
+ if (code !== 0) {
19
+ if (existsSync(tmpFile))
20
+ unlinkSync(tmpFile);
21
+ reject(new Error(`Editor exited with code ${code}`));
22
+ return;
23
+ }
24
+ try {
25
+ const content = readFileSync(tmpFile, 'utf-8');
26
+ unlinkSync(tmpFile);
27
+ resolve(content);
28
+ }
29
+ catch (err) {
30
+ reject(err);
31
+ }
32
+ });
33
+ });
34
+ }
35
+ function getTemplates() {
36
+ const templateDir = join(process.cwd(), '.github', 'ISSUE_TEMPLATE');
37
+ const templates = [];
38
+ try {
39
+ if (!existsSync(templateDir))
40
+ return templates;
41
+ const files = readdirSync(templateDir);
42
+ for (const file of files) {
43
+ if (file === 'config.yml' || file === 'config.yaml')
44
+ continue;
45
+ if (!file.endsWith('.md') && !file.endsWith('.yml') && !file.endsWith('.yaml'))
46
+ continue;
47
+ const content = readFileSync(join(templateDir, file), 'utf-8');
48
+ // Parse name from frontmatter
49
+ const nameMatch = content.match(/^name:\s*["']?(.+?)["']?\s*$/m);
50
+ const name = nameMatch ? nameMatch[1] : file.replace(/\.(md|ya?ml)$/, '');
51
+ // Remove frontmatter for body
52
+ const bodyContent = content.replace(/^---[\s\S]*?---\n?/, '');
53
+ templates.push({ name, filename: file, content: bodyContent });
54
+ }
55
+ }
56
+ catch {
57
+ // No templates directory or error reading
58
+ }
59
+ return templates;
60
+ }
61
+ export async function addIssueCommand(title, options) {
62
+ // Handle --list-templates
63
+ if (options.listTemplates) {
64
+ const templates = getTemplates();
65
+ if (templates.length === 0) {
66
+ console.log(chalk.dim('No templates found in .github/ISSUE_TEMPLATE/'));
67
+ }
68
+ else {
69
+ console.log(chalk.bold('Available templates:'));
70
+ for (const t of templates) {
71
+ const preview = t.content.trim().split('\n')[0].substring(0, 50);
72
+ console.log(` ${chalk.cyan(t.name)} ${chalk.dim(`(${t.filename})`)}`);
73
+ if (preview)
74
+ console.log(` ${chalk.dim(preview)}...`);
75
+ }
76
+ }
77
+ return;
78
+ }
79
+ const repo = await detectRepository();
80
+ if (!repo) {
81
+ console.error(chalk.red('Error:'), 'Not in a git repository with a GitHub remote');
82
+ process.exit(1);
83
+ }
84
+ const authenticated = await api.authenticate();
85
+ if (!authenticated) {
86
+ console.error(chalk.red('Error:'), 'Not authenticated. Run', chalk.cyan('ghp auth'));
87
+ process.exit(1);
88
+ }
89
+ // Load defaults from config
90
+ const defaults = getAddIssueDefaults();
91
+ // Get projects
92
+ const projects = await api.getProjects(repo);
93
+ if (projects.length === 0) {
94
+ console.error(chalk.red('Error:'), 'No GitHub Projects found for this repository');
95
+ process.exit(1);
96
+ }
97
+ // Select project (CLI > config default > first project)
98
+ const projectName = options.project || defaults.project;
99
+ let project = projects[0];
100
+ if (projectName) {
101
+ const found = projects.find(p => p.title.toLowerCase().includes(projectName.toLowerCase()));
102
+ if (!found) {
103
+ console.error(chalk.red('Error:'), `Project "${projectName}" not found`);
104
+ console.log('Available projects:', projects.map(p => p.title).join(', '));
105
+ process.exit(1);
106
+ }
107
+ project = found;
108
+ }
109
+ // Handle template and editor
110
+ let body = options.body || '';
111
+ const templates = getTemplates();
112
+ // Determine which template to use (CLI > config default)
113
+ let templateName = options.template || defaults.template;
114
+ // If no template specified and templates exist, prompt user to pick one
115
+ if (!templateName && templates.length > 0 && !options.body) {
116
+ console.log(chalk.bold('Select a template:'));
117
+ templates.forEach((t, i) => console.log(` ${i + 1}. ${t.name}`));
118
+ console.log(` ${templates.length + 1}. ${chalk.dim('Blank issue')}`);
119
+ console.log();
120
+ const readline = await import('readline');
121
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
122
+ const choice = await new Promise(resolve => {
123
+ rl.question('Template number: ', (answer) => {
124
+ rl.close();
125
+ resolve(answer.trim());
126
+ });
127
+ });
128
+ const idx = parseInt(choice, 10) - 1;
129
+ if (idx >= 0 && idx < templates.length) {
130
+ templateName = templates[idx].name;
131
+ }
132
+ console.log();
133
+ }
134
+ let usingTemplate = false;
135
+ if (templateName) {
136
+ const template = templates.find(t => t.filename.toLowerCase().includes(templateName.toLowerCase()) ||
137
+ t.name.toLowerCase().includes(templateName.toLowerCase()));
138
+ if (template) {
139
+ body = template.content;
140
+ usingTemplate = true;
141
+ }
142
+ else if (templates.length > 0) {
143
+ console.error(chalk.red('Error:'), `Template "${templateName}" not found`);
144
+ console.log('Available templates:', templates.map(t => t.name).join(', '));
145
+ process.exit(1);
146
+ }
147
+ else {
148
+ console.error(chalk.red('Error:'), `Template "${templateName}" not found`);
149
+ console.log(chalk.dim('No templates in .github/ISSUE_TEMPLATE/'));
150
+ process.exit(1);
151
+ }
152
+ }
153
+ // Open editor if: using template (always), -e flag, or no body provided
154
+ if (usingTemplate || options.edit || !options.body) {
155
+ const header = `# ${title || 'Issue Title'}\n\n`;
156
+ try {
157
+ const edited = await openEditor(header + body);
158
+ // Extract title from first line if it changed
159
+ const lines = edited.split('\n');
160
+ if (lines[0].startsWith('# ')) {
161
+ title = lines[0].slice(2).trim();
162
+ body = lines.slice(1).join('\n').trim();
163
+ }
164
+ else {
165
+ body = edited.trim();
166
+ }
167
+ }
168
+ catch (err) {
169
+ console.error(chalk.red('Error:'), 'Editor failed:', err);
170
+ process.exit(1);
171
+ }
172
+ }
173
+ // Validate title
174
+ if (!title || title === 'Issue Title') {
175
+ console.error(chalk.red('Error:'), 'Issue title is required');
176
+ process.exit(1);
177
+ }
178
+ // Determine status (CLI > config default > interactive picker)
179
+ let statusName = options.status || defaults.status;
180
+ const statusField = await api.getStatusField(project.id);
181
+ if (!statusName && statusField && statusField.options.length > 0) {
182
+ console.log(chalk.bold('Select initial status:'));
183
+ statusField.options.forEach((opt, i) => console.log(` ${i + 1}. ${opt.name}`));
184
+ console.log();
185
+ const readline = await import('readline');
186
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
187
+ const choice = await new Promise(resolve => {
188
+ rl.question('Status number: ', (answer) => {
189
+ rl.close();
190
+ resolve(answer.trim());
191
+ });
192
+ });
193
+ const idx = parseInt(choice, 10) - 1;
194
+ if (idx >= 0 && idx < statusField.options.length) {
195
+ statusName = statusField.options[idx].name;
196
+ }
197
+ console.log();
198
+ }
199
+ console.log(chalk.dim(`Creating issue in ${project.title}...`));
200
+ // Create the issue
201
+ const issue = await api.createIssue(repo, title, body);
202
+ if (!issue) {
203
+ console.error(chalk.red('Error:'), 'Failed to create issue');
204
+ process.exit(1);
205
+ }
206
+ console.log(chalk.green('Created:'), `#${issue.number} ${title}`);
207
+ // Add to project
208
+ const itemId = await api.addToProject(project.id, issue.id);
209
+ if (!itemId) {
210
+ console.error(chalk.yellow('Warning:'), 'Issue created but failed to add to project');
211
+ return;
212
+ }
213
+ console.log(chalk.green('Added to:'), project.title);
214
+ // Set initial status
215
+ if (statusName && statusField) {
216
+ const option = statusField.options.find(o => o.name.toLowerCase() === statusName.toLowerCase());
217
+ if (option) {
218
+ await api.updateItemStatus(project.id, itemId, statusField.fieldId, option.id);
219
+ console.log(chalk.green('Status:'), statusName);
220
+ }
221
+ else {
222
+ console.log(chalk.yellow('Warning:'), `Status "${statusName}" not found`);
223
+ }
224
+ }
225
+ console.log();
226
+ console.log(chalk.dim(`Start working: ${chalk.cyan(`ghp start ${issue.number}`)}`));
227
+ }
228
+ //# sourceMappingURL=add-issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-issue.js","sourceRoot":"","sources":["../../src/commands/add-issue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface AssignOptions {
2
+ remove?: boolean;
3
+ }
4
+ export declare function assignCommand(issue: string, users: string[], options: AssignOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=assign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign.d.ts","sourceRoot":"","sources":["../../src/commands/assign.ts"],"names":[],"mappings":"AAQA,UAAU,aAAa;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,aAAa,CAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,aAAa,GACvB,OAAO,CAAC,IAAI,CAAC,CAsCf"}
@@ -0,0 +1,44 @@
1
+ import chalk from 'chalk';
2
+ import { exec } from 'child_process';
3
+ import { promisify } from 'util';
4
+ import { api } from '../github-api.js';
5
+ import { detectRepository } from '../git-utils.js';
6
+ const execAsync = promisify(exec);
7
+ export async function assignCommand(issue, users, options) {
8
+ const issueNumber = parseInt(issue, 10);
9
+ if (isNaN(issueNumber)) {
10
+ console.error(chalk.red('Error:'), 'Issue must be a number');
11
+ process.exit(1);
12
+ }
13
+ // Detect repository
14
+ const repo = await detectRepository();
15
+ if (!repo) {
16
+ console.error(chalk.red('Error:'), 'Not in a git repository with a GitHub remote');
17
+ process.exit(1);
18
+ }
19
+ // Authenticate
20
+ const authenticated = await api.authenticate();
21
+ if (!authenticated) {
22
+ console.error(chalk.red('Error:'), 'Not authenticated. Run', chalk.cyan('ghp auth'));
23
+ process.exit(1);
24
+ }
25
+ // Default to self if no users specified
26
+ const assignees = users.length > 0 ? users : [api.username];
27
+ const assigneeList = assignees.join(',');
28
+ try {
29
+ if (options.remove) {
30
+ await execAsync(`gh issue edit ${issueNumber} --remove-assignee "${assigneeList}"`);
31
+ console.log(chalk.green('✓'), `Removed ${assigneeList} from #${issueNumber}`);
32
+ }
33
+ else {
34
+ await execAsync(`gh issue edit ${issueNumber} --add-assignee "${assigneeList}"`);
35
+ console.log(chalk.green('✓'), `Assigned ${assigneeList} to #${issueNumber}`);
36
+ }
37
+ }
38
+ catch (error) {
39
+ const err = error;
40
+ console.error(chalk.red('Error:'), err.stderr || 'Failed to update assignees');
41
+ process.exit(1);
42
+ }
43
+ }
44
+ //# sourceMappingURL=assign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign.js","sourceRoot":"","sources":["../../src/commands/assign.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAMlC,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,KAAa,EACb,KAAe,EACf,OAAsB;IAEtB,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,oBAAoB;IACpB,MAAM,IAAI,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACtC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,8CAA8C,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,eAAe;IACf,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;IAC/C,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,wBAAwB,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,wCAAwC;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAS,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEzC,IAAI,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,SAAS,CAAC,iBAAiB,WAAW,uBAAuB,YAAY,GAAG,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,WAAW,YAAY,UAAU,WAAW,EAAE,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACJ,MAAM,SAAS,CAAC,iBAAiB,WAAW,oBAAoB,YAAY,GAAG,CAAC,CAAC;YACjF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,YAAY,YAAY,QAAQ,WAAW,EAAE,CAAC,CAAC;QACjF,CAAC;IACL,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,KAA4B,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,IAAI,4BAA4B,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface AuthOptions {
2
+ status?: boolean;
3
+ }
4
+ export declare function authCommand(options: AuthOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BrE"}
@@ -0,0 +1,31 @@
1
+ import chalk from 'chalk';
2
+ import { api } from '../github-api.js';
3
+ export async function authCommand(options) {
4
+ const authenticated = await api.authenticate();
5
+ if (options.status) {
6
+ if (authenticated) {
7
+ console.log(chalk.green('✓ Authenticated as'), chalk.bold(api.username));
8
+ }
9
+ else {
10
+ console.log(chalk.red('✗ Not authenticated'));
11
+ console.log();
12
+ console.log('To authenticate, either:');
13
+ console.log(' 1. Run', chalk.cyan('gh auth login'), '(recommended)');
14
+ console.log(' 2. Set', chalk.cyan('GITHUB_TOKEN'), 'environment variable');
15
+ }
16
+ return;
17
+ }
18
+ if (authenticated) {
19
+ console.log(chalk.green('✓ Already authenticated as'), chalk.bold(api.username));
20
+ }
21
+ else {
22
+ console.log(chalk.yellow('Authentication required.'));
23
+ console.log();
24
+ console.log('This CLI uses the GitHub CLI for authentication.');
25
+ console.log('Run', chalk.cyan('gh auth login'), 'to authenticate.');
26
+ console.log();
27
+ console.log('Alternatively, set the', chalk.cyan('GITHUB_TOKEN'), 'environment variable.');
28
+ process.exit(1);
29
+ }
30
+ }
31
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAMvC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IAClD,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;IAE/C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,IAAI,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7E,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,sBAAsB,CAAC,CAAC;QAChF,CAAC;QACD,OAAO;IACX,CAAC;IAED,IAAI,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,uBAAuB,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface CommentOptions {
2
+ message?: string;
3
+ }
4
+ export declare function commentCommand(issue: string, options: CommentOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/commands/comment.ts"],"names":[],"mappings":"AAQA,UAAU,cAAc;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD1F"}