@proletariat/cli 0.3.16 → 0.3.18
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/commands/action/create.d.ts +1 -0
- package/dist/commands/action/create.js +74 -38
- package/dist/commands/action/delete.d.ts +1 -0
- package/dist/commands/action/delete.js +23 -24
- package/dist/commands/action/index.d.ts +1 -0
- package/dist/commands/action/index.js +5 -10
- package/dist/commands/action/list.d.ts +1 -0
- package/dist/commands/action/list.js +3 -1
- package/dist/commands/action/run.d.ts +1 -0
- package/dist/commands/action/run.js +44 -32
- package/dist/commands/action/show.d.ts +2 -0
- package/dist/commands/action/update.d.ts +1 -0
- package/dist/commands/action/update.js +80 -39
- package/dist/commands/agent/auth.d.ts +2 -0
- package/dist/commands/agent/auth.js +44 -3
- package/dist/commands/agent/discover.d.ts +2 -0
- package/dist/commands/agent/discover.js +35 -3
- package/dist/commands/agent/index.d.ts +1 -0
- package/dist/commands/agent/index.js +25 -45
- package/dist/commands/agent/list.d.ts +8 -3
- package/dist/commands/agent/list.js +16 -29
- package/dist/commands/agent/login.d.ts +1 -0
- package/dist/commands/agent/login.js +14 -32
- package/dist/commands/agent/rebuild.d.ts +1 -0
- package/dist/commands/agent/rebuild.js +2 -2
- package/dist/commands/agent/remove.d.ts +17 -0
- package/dist/commands/agent/remove.js +144 -0
- package/dist/commands/agent/restart.d.ts +1 -0
- package/dist/commands/agent/restart.js +2 -2
- package/dist/commands/agent/shell.d.ts +1 -0
- package/dist/commands/agent/shell.js +63 -76
- package/dist/commands/agent/staff/add.d.ts +1 -0
- package/dist/commands/agent/staff/add.js +7 -1
- package/dist/commands/agent/staff/index.d.ts +1 -0
- package/dist/commands/agent/staff/index.js +5 -4
- package/dist/commands/agent/staff/remove.d.ts +1 -0
- package/dist/commands/agent/status.d.ts +1 -0
- package/dist/commands/agent/status.js +11 -23
- package/dist/commands/agent/temp/cleanup.d.ts +1 -0
- package/dist/commands/agent/temp/index.d.ts +1 -0
- package/dist/commands/agent/temp/index.js +4 -3
- package/dist/commands/agent/themes/index.d.ts +1 -0
- package/dist/commands/agent/themes/index.js +9 -3
- package/dist/commands/agent/themes/set.d.ts +1 -0
- package/dist/commands/agent/themes/set.js +7 -1
- package/dist/commands/agent/visit.d.ts +1 -0
- package/dist/commands/agent/visit.js +11 -23
- package/dist/commands/autocomplete/setup.d.ts +11 -0
- package/dist/commands/autocomplete/setup.js +113 -8
- package/dist/commands/board/index.d.ts +4 -0
- package/dist/commands/board/index.js +32 -30
- package/dist/commands/board/watch.d.ts +2 -0
- package/dist/commands/branch/create.d.ts +1 -0
- package/dist/commands/branch/create.js +33 -41
- package/dist/commands/branch/index.d.ts +1 -0
- package/dist/commands/branch/list.d.ts +2 -0
- package/dist/commands/branch/validate.d.ts +2 -0
- package/dist/commands/branch/where.d.ts +1 -0
- package/dist/commands/claude.d.ts +6 -0
- package/dist/commands/claude.js +166 -116
- package/dist/commands/commit.d.ts +6 -0
- package/dist/commands/commit.js +68 -73
- package/dist/commands/config/index.d.ts +13 -0
- package/dist/commands/config/index.js +142 -98
- package/dist/commands/docker/clean.d.ts +2 -1
- package/dist/commands/docker/clean.js +20 -29
- package/dist/commands/docker/index.d.ts +1 -0
- package/dist/commands/docker/index.js +37 -41
- package/dist/commands/docker/prune.d.ts +2 -1
- package/dist/commands/docker/prune.js +20 -27
- package/dist/commands/docker/restart.d.ts +2 -1
- package/dist/commands/docker/restart.js +20 -29
- package/dist/commands/docker/stop.d.ts +2 -1
- package/dist/commands/docker/stop.js +20 -29
- package/dist/commands/epic/activate.d.ts +1 -0
- package/dist/commands/epic/archive.d.ts +1 -0
- package/dist/commands/epic/create.d.ts +1 -0
- package/dist/commands/epic/index.d.ts +1 -0
- package/dist/commands/epic/link/block.d.ts +1 -0
- package/dist/commands/epic/link/duplicates.d.ts +1 -0
- package/dist/commands/epic/link/index.d.ts +1 -0
- package/dist/commands/epic/link/relates.d.ts +1 -0
- package/dist/commands/epic/link/remove.d.ts +1 -0
- package/dist/commands/epic/list.d.ts +2 -0
- package/dist/commands/epic/move.d.ts +1 -0
- package/dist/commands/epic/progress.d.ts +1 -0
- package/dist/commands/epic/project.d.ts +1 -0
- package/dist/commands/epic/reorder.d.ts +1 -0
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/ticket.d.ts +1 -0
- package/dist/commands/epic/view.d.ts +1 -0
- package/dist/commands/execution/index.d.ts +1 -0
- package/dist/commands/execution/index.js +9 -25
- package/dist/commands/execution/list.d.ts +2 -0
- package/dist/commands/execution/logs.d.ts +1 -0
- package/dist/commands/execution/logs.js +6 -16
- package/dist/commands/execution/stop.d.ts +1 -0
- package/dist/commands/execution/stop.js +4 -15
- package/dist/commands/gh/index.d.ts +1 -0
- package/dist/commands/gh/index.js +27 -27
- package/dist/commands/gh/login.d.ts +4 -0
- package/dist/commands/gh/login.js +31 -0
- package/dist/commands/gh/status.d.ts +4 -0
- package/dist/commands/gh/status.js +27 -4
- package/dist/commands/gh/token.d.ts +4 -0
- package/dist/commands/gh/token.js +49 -5
- package/dist/commands/phase/create.d.ts +1 -1
- package/dist/commands/phase/create.js +116 -74
- package/dist/commands/phase/delete.d.ts +1 -0
- package/dist/commands/phase/delete.js +23 -22
- package/dist/commands/phase/list.d.ts +1 -0
- package/dist/commands/phase/list.js +3 -5
- package/dist/commands/phase/move.d.ts +1 -0
- package/dist/commands/phase/move.js +39 -39
- package/dist/commands/phase/template/apply.d.ts +1 -0
- package/dist/commands/phase/template/create.d.ts +2 -0
- package/dist/commands/phase/template/delete.d.ts +1 -0
- package/dist/commands/phase/template/index.d.ts +1 -0
- package/dist/commands/phase/template/list.d.ts +1 -0
- package/dist/commands/phase/template/update.d.ts +2 -0
- package/dist/commands/phase/update.d.ts +1 -1
- package/dist/commands/phase/update.js +89 -55
- package/dist/commands/pmo/init.d.ts +2 -0
- package/dist/commands/pmo/init.js +84 -22
- package/dist/commands/pr/create.d.ts +12 -3
- package/dist/commands/pr/create.js +130 -147
- package/dist/commands/pr/index.d.ts +6 -3
- package/dist/commands/pr/index.js +41 -39
- package/dist/commands/pr/link.d.ts +7 -3
- package/dist/commands/pr/link.js +126 -150
- package/dist/commands/pr/status.d.ts +6 -3
- package/dist/commands/pr/status.js +101 -126
- package/dist/commands/project/archive.d.ts +1 -0
- package/dist/commands/project/archive.js +15 -20
- package/dist/commands/project/create.d.ts +1 -0
- package/dist/commands/project/create.js +13 -5
- package/dist/commands/project/delete.d.ts +1 -0
- package/dist/commands/project/delete.js +14 -28
- package/dist/commands/project/index.d.ts +1 -0
- package/dist/commands/project/index.js +0 -5
- package/dist/commands/project/list.d.ts +2 -0
- package/dist/commands/project/list.js +21 -3
- package/dist/commands/project/spec.d.ts +1 -0
- package/dist/commands/project/spec.js +17 -23
- package/dist/commands/project/unarchive.d.ts +2 -0
- package/dist/commands/project/unarchive.js +21 -2
- package/dist/commands/project/view.d.ts +1 -0
- package/dist/commands/project/view.js +34 -22
- package/dist/commands/repo/add.d.ts +2 -0
- package/dist/commands/repo/add.js +44 -1
- package/dist/commands/repo/index.d.ts +1 -0
- package/dist/commands/repo/index.js +20 -38
- package/dist/commands/repo/list.d.ts +2 -0
- package/dist/commands/repo/remove.d.ts +1 -0
- package/dist/commands/repo/remove.js +45 -63
- package/dist/commands/repo/view.d.ts +2 -0
- package/dist/commands/repo/view.js +30 -5
- package/dist/commands/roadmap/add-project.d.ts +1 -0
- package/dist/commands/roadmap/create.d.ts +1 -0
- package/dist/commands/roadmap/delete.d.ts +1 -0
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/index.d.ts +1 -0
- package/dist/commands/roadmap/list.d.ts +2 -0
- package/dist/commands/roadmap/remove-project.d.ts +1 -0
- package/dist/commands/roadmap/reorder.d.ts +1 -0
- package/dist/commands/roadmap/update.d.ts +1 -0
- package/dist/commands/roadmap/view.d.ts +1 -0
- package/dist/commands/session/attach.d.ts +1 -0
- package/dist/commands/session/index.d.ts +1 -0
- package/dist/commands/session/index.js +8 -25
- package/dist/commands/session/list.d.ts +2 -0
- package/dist/commands/spec/create.d.ts +1 -1
- package/dist/commands/spec/create.js +64 -65
- package/dist/commands/spec/index.d.ts +1 -0
- package/dist/commands/spec/index.js +36 -22
- package/dist/commands/spec/link/depends.d.ts +1 -0
- package/dist/commands/spec/link/depends.js +6 -6
- package/dist/commands/spec/link/duplicates.d.ts +1 -0
- package/dist/commands/spec/link/duplicates.js +6 -6
- package/dist/commands/spec/link/index.d.ts +2 -1
- package/dist/commands/spec/link/index.js +0 -4
- package/dist/commands/spec/link/relates.d.ts +1 -0
- package/dist/commands/spec/link/relates.js +6 -6
- package/dist/commands/spec/link/remove.d.ts +2 -1
- package/dist/commands/spec/link/remove.js +6 -6
- package/dist/commands/spec/list.d.ts +2 -0
- package/dist/commands/spec/list.js +25 -0
- package/dist/commands/spec/plan.d.ts +2 -1
- package/dist/commands/spec/plan.js +19 -26
- package/dist/commands/spec/ticket.d.ts +2 -1
- package/dist/commands/spec/ticket.js +48 -34
- package/dist/commands/spec/view.d.ts +2 -1
- package/dist/commands/spec/view.js +25 -16
- package/dist/commands/status/create.d.ts +1 -1
- package/dist/commands/status/create.js +80 -64
- package/dist/commands/status/delete.d.ts +2 -1
- package/dist/commands/status/delete.js +26 -22
- package/dist/commands/status/index.d.ts +1 -0
- package/dist/commands/status/index.js +26 -19
- package/dist/commands/status/list.d.ts +1 -0
- package/dist/commands/status/list.js +12 -7
- package/dist/commands/status/move.d.ts +2 -1
- package/dist/commands/status/move.js +62 -61
- package/dist/commands/status/update.d.ts +2 -2
- package/dist/commands/status/update.js +110 -77
- package/dist/commands/template/delete.d.ts +1 -0
- package/dist/commands/template/delete.js +47 -48
- package/dist/commands/template/index.d.ts +1 -0
- package/dist/commands/template/index.js +26 -33
- package/dist/commands/template/list.d.ts +1 -0
- package/dist/commands/template/phase/create.d.ts +1 -0
- package/dist/commands/template/phase/create.js +6 -0
- package/dist/commands/template/phase/index.d.ts +1 -0
- package/dist/commands/template/phase/index.js +27 -26
- package/dist/commands/template/phase/update.d.ts +1 -0
- package/dist/commands/template/phase/update.js +6 -0
- package/dist/commands/template/ticket/index.d.ts +1 -0
- package/dist/commands/template/ticket/index.js +27 -26
- package/dist/commands/template/ticket/save.d.ts +1 -0
- package/dist/commands/template/ticket/save.js +6 -0
- package/dist/commands/terminal/title.d.ts +26 -0
- package/dist/commands/terminal/title.js +37 -3
- package/dist/commands/ticket/bulk.d.ts +1 -0
- package/dist/commands/ticket/complete.d.ts +1 -0
- package/dist/commands/ticket/complete.js +18 -14
- package/dist/commands/ticket/create.d.ts +1 -0
- package/dist/commands/ticket/create.js +45 -41
- package/dist/commands/ticket/delete.d.ts +1 -0
- package/dist/commands/ticket/delete.js +1 -1
- package/dist/commands/ticket/edit.d.ts +1 -0
- package/dist/commands/ticket/edit.js +1 -1
- package/dist/commands/ticket/epic.d.ts +1 -0
- package/dist/commands/ticket/epic.js +2 -2
- package/dist/commands/ticket/index.d.ts +1 -0
- package/dist/commands/ticket/link/block.d.ts +1 -0
- package/dist/commands/ticket/link/block.js +1 -1
- package/dist/commands/ticket/link/duplicates.d.ts +1 -0
- package/dist/commands/ticket/link/duplicates.js +1 -1
- package/dist/commands/ticket/link/index.d.ts +1 -0
- package/dist/commands/ticket/link/index.js +9 -8
- package/dist/commands/ticket/link/relates.d.ts +1 -0
- package/dist/commands/ticket/link/relates.js +1 -1
- package/dist/commands/ticket/link/remove.d.ts +1 -0
- package/dist/commands/ticket/link/remove.js +1 -1
- package/dist/commands/ticket/list.d.ts +2 -0
- package/dist/commands/ticket/move.d.ts +1 -0
- package/dist/commands/ticket/move.js +27 -19
- package/dist/commands/ticket/project.d.ts +1 -0
- package/dist/commands/ticket/project.js +3 -3
- package/dist/commands/ticket/reassign.d.ts +1 -0
- package/dist/commands/ticket/reassign.js +1 -1
- package/dist/commands/ticket/spec.d.ts +1 -0
- package/dist/commands/ticket/spec.js +3 -3
- package/dist/commands/ticket/status.d.ts +1 -0
- package/dist/commands/ticket/status.js +1 -1
- package/dist/commands/ticket/template/apply.d.ts +1 -0
- package/dist/commands/ticket/template/create.d.ts +2 -0
- package/dist/commands/ticket/template/delete.d.ts +1 -0
- package/dist/commands/ticket/template/index.d.ts +1 -0
- package/dist/commands/ticket/template/list.d.ts +1 -0
- package/dist/commands/ticket/template/save.d.ts +2 -0
- package/dist/commands/ticket/update.d.ts +1 -0
- package/dist/commands/ticket/update.js +1 -1
- package/dist/commands/ticket/view.d.ts +1 -0
- package/dist/commands/ticket/view.js +1 -1
- package/dist/commands/work/complete.d.ts +1 -0
- package/dist/commands/work/index.d.ts +1 -0
- package/dist/commands/work/ready.d.ts +1 -0
- package/dist/commands/work/revise.d.ts +1 -0
- package/dist/commands/work/spawn-all.d.ts +2 -0
- package/dist/commands/work/spawn-all.js +11 -4
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +261 -166
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +270 -189
- package/dist/commands/work/watch.d.ts +1 -0
- package/dist/commands/work/watch.js +63 -58
- package/dist/commands/workflow/create.d.ts +1 -0
- package/dist/commands/workflow/create.js +2 -4
- package/dist/commands/workflow/delete.d.ts +1 -0
- package/dist/commands/workflow/delete.js +21 -33
- package/dist/commands/workflow/index.d.ts +1 -0
- package/dist/commands/workflow/list.d.ts +1 -0
- package/dist/commands/workflow/list.js +3 -6
- package/dist/commands/workflow/switch.d.ts +2 -0
- package/dist/commands/workflow/switch.js +46 -21
- package/dist/commands/workflow/view.d.ts +1 -0
- package/dist/commands/workflow/view.js +18 -27
- package/dist/commands/workspace/remove.d.ts +2 -2
- package/dist/commands/workspace/remove.js +16 -21
- package/dist/commands/workspace/use.d.ts +2 -2
- package/dist/commands/workspace/use.js +12 -18
- package/dist/lib/agents/commands.d.ts +1 -1
- package/dist/lib/agents/commands.js +4 -4
- package/dist/lib/database/drizzle-schema.d.ts +5009 -0
- package/dist/lib/database/drizzle-schema.js +699 -0
- package/dist/lib/database/drizzle.d.ts +29 -0
- package/dist/lib/database/drizzle.js +37 -0
- package/dist/lib/database/index.d.ts +1 -0
- package/dist/lib/database/index.js +1 -1
- package/dist/lib/execution/config.d.ts +6 -0
- package/dist/lib/execution/config.js +31 -13
- package/dist/lib/execution/devcontainer.js +13 -7
- package/dist/lib/execution/runners.js +24 -7
- package/dist/lib/execution/spawner.js +19 -0
- package/dist/lib/flags/index.d.ts +4 -0
- package/dist/lib/flags/index.js +4 -0
- package/dist/lib/flags/resolver.d.ts +224 -0
- package/dist/lib/flags/resolver.js +313 -0
- package/dist/lib/pmo/base-command.d.ts +53 -3
- package/dist/lib/pmo/base-command.js +92 -13
- package/dist/lib/pmo/find-pmo.d.ts +1 -1
- package/dist/lib/pmo/find-pmo.js +4 -4
- package/dist/lib/pmo/index.d.ts +1 -1
- package/dist/lib/pmo/index.js +1 -1
- package/dist/lib/pmo/storage/helpers.js +2 -1
- package/dist/lib/pmo/storage/index.d.ts +9 -0
- package/dist/lib/pmo/storage/index.js +14 -0
- package/dist/lib/pmo/storage/projects.d.ts +28 -13
- package/dist/lib/pmo/storage/projects.js +110 -34
- package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
- package/dist/lib/pmo/storage/roadmaps.js +182 -111
- package/dist/lib/pmo/storage/specs.js +13 -16
- package/dist/lib/pmo/storage/subtasks.js +17 -2
- package/dist/lib/pmo/storage/tickets.d.ts +12 -2
- package/dist/lib/pmo/storage/tickets.js +63 -5
- package/dist/lib/pmo/storage/types.d.ts +7 -3
- package/dist/lib/pmo/storage/views.d.ts +12 -1
- package/dist/lib/pmo/storage/views.js +61 -6
- package/dist/lib/prompt-command.d.ts +90 -0
- package/dist/lib/prompt-command.js +102 -0
- package/dist/lib/prompt-json.d.ts +34 -4
- package/dist/lib/prompt-json.js +35 -3
- package/dist/lib/repos/index.js +15 -15
- package/dist/lib/workspace.d.ts +4 -3
- package/dist/lib/workspace.js +3 -3
- package/oclif.manifest.json +4610 -2997
- package/package.json +13 -5
package/dist/commands/pr/link.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import Database from 'better-sqlite3';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { getPMOContext } from '../../lib/pmo/index.js';
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags, } from '../../lib/pmo/index.js';
|
|
6
3
|
import { styles } from '../../lib/styles.js';
|
|
7
|
-
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
8
4
|
import { isGHInstalled, isGHAuthenticated, getPRByNumber, listOpenPRs, } from '../../lib/pr/index.js';
|
|
9
|
-
import { shouldOutputJson,
|
|
10
|
-
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
6
|
+
import { FlagResolver } from '../../lib/flags/index.js';
|
|
7
|
+
export default class PRLink extends PMOCommand {
|
|
11
8
|
static description = 'Link an existing GitHub pull request to a ticket';
|
|
12
9
|
static examples = [
|
|
13
10
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -22,6 +19,7 @@ export default class PRLink extends Command {
|
|
|
22
19
|
}),
|
|
23
20
|
};
|
|
24
21
|
static flags = {
|
|
22
|
+
...pmoBaseFlags,
|
|
25
23
|
pr: Flags.integer({
|
|
26
24
|
char: 'p',
|
|
27
25
|
description: 'PR number to link',
|
|
@@ -30,12 +28,15 @@ export default class PRLink extends Command {
|
|
|
30
28
|
char: 'u',
|
|
31
29
|
description: 'PR URL to link',
|
|
32
30
|
}),
|
|
33
|
-
|
|
34
|
-
description: '
|
|
31
|
+
ticket: Flags.string({
|
|
32
|
+
description: 'Ticket ID to link (alternative to positional arg)',
|
|
33
|
+
}),
|
|
34
|
+
confirm: Flags.boolean({
|
|
35
|
+
description: 'Confirm overwriting existing PR link',
|
|
35
36
|
default: false,
|
|
36
37
|
}),
|
|
37
38
|
};
|
|
38
|
-
async
|
|
39
|
+
async execute() {
|
|
39
40
|
const { args, flags } = await this.parse(PRLink);
|
|
40
41
|
// Check if JSON output mode is active
|
|
41
42
|
const jsonMode = shouldOutputJson(flags);
|
|
@@ -54,159 +55,134 @@ export default class PRLink extends Command {
|
|
|
54
55
|
if (!isGHAuthenticated()) {
|
|
55
56
|
return handleError('GH_NOT_AUTHENTICATED', 'GitHub CLI is not authenticated. Run "gh auth login" first.');
|
|
56
57
|
}
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
workspaceInfo = getWorkspaceInfo();
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
58
|
+
// PMOCommand ensures we have storage access
|
|
59
|
+
if (!this.storage) {
|
|
63
60
|
return handleError('NOT_IN_WORKSPACE', 'Not in a workspace. Run "prlt init" first.');
|
|
64
61
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const allTickets = await storage.listTickets(projectId);
|
|
76
|
-
const activeTickets = allTickets.filter(t => t.statusName && !t.statusName.toLowerCase().includes('done') && !t.statusName.toLowerCase().includes('archive'));
|
|
77
|
-
if (activeTickets.length === 0) {
|
|
78
|
-
await storage.close();
|
|
79
|
-
db.close();
|
|
80
|
-
if (jsonMode) {
|
|
81
|
-
outputErrorAsJson('NO_ACTIVE_TICKETS', 'No active tickets found.', createMetadata('pr link', flags));
|
|
82
|
-
this.exit(1);
|
|
83
|
-
}
|
|
84
|
-
this.log(styles.info('No active tickets found.'));
|
|
85
|
-
return;
|
|
62
|
+
// Get ticket ID from args or flags
|
|
63
|
+
let ticketId = args.ticketId || flags.ticket;
|
|
64
|
+
if (!ticketId) {
|
|
65
|
+
const projectId = flags.project;
|
|
66
|
+
const allTickets = await this.storage.listTickets(projectId);
|
|
67
|
+
const activeTickets = allTickets.filter(t => t.statusName && !t.statusName.toLowerCase().includes('done') && !t.statusName.toLowerCase().includes('archive'));
|
|
68
|
+
if (activeTickets.length === 0) {
|
|
69
|
+
if (jsonMode) {
|
|
70
|
+
outputErrorAsJson('NO_ACTIVE_TICKETS', 'No active tickets found.', createMetadata('pr link', flags));
|
|
71
|
+
this.exit(1);
|
|
86
72
|
}
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
this.log(styles.info('No active tickets found.'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Use FlagResolver for ticket selection
|
|
77
|
+
const resolver = new FlagResolver({
|
|
78
|
+
commandName: 'pr link',
|
|
79
|
+
baseCommand: 'prlt pr link',
|
|
80
|
+
jsonMode,
|
|
81
|
+
flags: { ticket: ticketId },
|
|
82
|
+
});
|
|
83
|
+
resolver.addPrompt({
|
|
84
|
+
flagName: 'ticket',
|
|
85
|
+
type: 'list',
|
|
86
|
+
message: 'Select ticket to link PR to:',
|
|
87
|
+
choices: () => activeTickets.map(t => ({
|
|
89
88
|
name: `${t.id} - ${t.title} (${t.statusName})`,
|
|
90
89
|
value: t.id,
|
|
91
|
-
}))
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
})),
|
|
91
|
+
when: (ctx) => !ctx.flags.ticket,
|
|
92
|
+
});
|
|
93
|
+
const resolved = await resolver.resolve();
|
|
94
|
+
ticketId = resolved.ticket;
|
|
95
|
+
}
|
|
96
|
+
// Get ticket
|
|
97
|
+
const ticket = await this.storage.getTicket(ticketId);
|
|
98
|
+
if (!ticket) {
|
|
99
|
+
this.error(`Ticket "${ticketId}" not found.`);
|
|
100
|
+
}
|
|
101
|
+
// Check if ticket already has a PR linked
|
|
102
|
+
if (ticket.metadata?.pr_url && !flags.confirm) {
|
|
103
|
+
this.log(styles.info(`Ticket ${ticketId} already has a linked PR:`));
|
|
104
|
+
this.log(styles.muted(` URL: ${ticket.metadata.pr_url}`));
|
|
105
|
+
// Use FlagResolver for confirmation
|
|
106
|
+
const confirmResolver = new FlagResolver({
|
|
107
|
+
commandName: 'pr link',
|
|
108
|
+
baseCommand: `prlt pr link ${ticketId}`,
|
|
109
|
+
jsonMode,
|
|
110
|
+
flags: {},
|
|
111
|
+
});
|
|
112
|
+
confirmResolver.addPrompt({
|
|
113
|
+
flagName: 'confirm',
|
|
114
|
+
type: 'list',
|
|
115
|
+
message: 'Replace with a different PR?',
|
|
116
|
+
choices: () => [
|
|
117
|
+
{ name: 'No', value: 'no' },
|
|
118
|
+
{ name: 'Yes', value: 'yes' },
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
const confirmResolved = await confirmResolver.resolve();
|
|
122
|
+
if (confirmResolved.confirm !== 'yes') {
|
|
123
|
+
return;
|
|
104
124
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
125
|
+
}
|
|
126
|
+
// Get PR number
|
|
127
|
+
let prNumber = flags.pr;
|
|
128
|
+
const prUrl = flags.url;
|
|
129
|
+
if (prUrl) {
|
|
130
|
+
// Extract PR number from URL
|
|
131
|
+
const urlMatch = prUrl.match(/\/pull\/(\d+)/);
|
|
132
|
+
if (urlMatch) {
|
|
133
|
+
prNumber = parseInt(urlMatch[1], 10);
|
|
111
134
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// Build choices once, use for both JSON and interactive modes
|
|
115
|
-
const confirmChoices = [
|
|
116
|
-
{ name: 'No', value: 'false' },
|
|
117
|
-
{ name: 'Yes', value: 'true' },
|
|
118
|
-
];
|
|
119
|
-
const confirmMessage = `Ticket ${ticketId} already has a linked PR (${ticket.metadata.pr_url}). Replace with a different PR?`;
|
|
120
|
-
// In JSON mode, output overwrite confirmation prompt and exit
|
|
121
|
-
if (jsonMode) {
|
|
122
|
-
outputPromptAsJson(buildPromptConfig('list', 'overwrite', confirmMessage, confirmChoices), createMetadata('pr link', flags));
|
|
123
|
-
}
|
|
124
|
-
this.log(styles.info(`Ticket ${ticketId} already has a linked PR:`));
|
|
125
|
-
this.log(styles.muted(` URL: ${ticket.metadata.pr_url}`));
|
|
126
|
-
const { overwrite } = await inquirer.prompt([{
|
|
127
|
-
type: 'list',
|
|
128
|
-
name: 'overwrite',
|
|
129
|
-
message: 'Replace with a different PR?',
|
|
130
|
-
choices: confirmChoices.map(c => ({ name: c.name, value: c.value === 'true' })),
|
|
131
|
-
default: false,
|
|
132
|
-
}]);
|
|
133
|
-
if (!overwrite) {
|
|
134
|
-
await storage.close();
|
|
135
|
-
db.close();
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
135
|
+
else {
|
|
136
|
+
this.error('Invalid PR URL format. Expected: https://github.com/owner/repo/pull/123');
|
|
138
137
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
this.error('Invalid PR URL format. Expected: https://github.com/owner/repo/pull/123');
|
|
138
|
+
}
|
|
139
|
+
if (!prNumber) {
|
|
140
|
+
// List open PRs for selection
|
|
141
|
+
const openPRs = listOpenPRs();
|
|
142
|
+
if (openPRs.length === 0) {
|
|
143
|
+
if (jsonMode) {
|
|
144
|
+
outputErrorAsJson('NO_OPEN_PRS', 'No open PRs found. Create one first with "prlt pr create".', createMetadata('pr link', flags));
|
|
145
|
+
this.exit(1);
|
|
150
146
|
}
|
|
147
|
+
this.error('No open PRs found. Create one first with "prlt pr create".');
|
|
151
148
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// Build choices once, use for both JSON and interactive modes
|
|
165
|
-
const prChoices = openPRs.map(pr => ({
|
|
149
|
+
// Use FlagResolver for PR selection
|
|
150
|
+
const prResolver = new FlagResolver({
|
|
151
|
+
commandName: 'pr link',
|
|
152
|
+
baseCommand: `prlt pr link ${ticketId}`,
|
|
153
|
+
jsonMode,
|
|
154
|
+
flags: {},
|
|
155
|
+
});
|
|
156
|
+
prResolver.addPrompt({
|
|
157
|
+
flagName: 'pr',
|
|
158
|
+
type: 'list',
|
|
159
|
+
message: 'Select PR to link:',
|
|
160
|
+
choices: () => openPRs.map(pr => ({
|
|
166
161
|
name: `#${pr.number} - ${pr.title} (${pr.headBranch})`,
|
|
167
162
|
value: String(pr.number),
|
|
168
|
-
}))
|
|
169
|
-
const prMessage = 'Select PR to link:';
|
|
170
|
-
// In JSON mode, output PR selection prompt and exit
|
|
171
|
-
if (jsonMode) {
|
|
172
|
-
outputPromptAsJson(buildPromptConfig('list', 'prNumber', prMessage, prChoices), createMetadata('pr link', flags));
|
|
173
|
-
}
|
|
174
|
-
const { selectedPR } = await inquirer.prompt([{
|
|
175
|
-
type: 'list',
|
|
176
|
-
name: 'selectedPR',
|
|
177
|
-
message: prMessage,
|
|
178
|
-
choices: prChoices.map(c => ({ name: c.name, value: parseInt(c.value, 10) })),
|
|
179
|
-
}]);
|
|
180
|
-
prNumber = selectedPR;
|
|
181
|
-
}
|
|
182
|
-
// Get PR info
|
|
183
|
-
const prInfo = getPRByNumber(prNumber);
|
|
184
|
-
if (!prInfo) {
|
|
185
|
-
await storage.close();
|
|
186
|
-
db.close();
|
|
187
|
-
this.error(`PR #${prNumber} not found.`);
|
|
188
|
-
}
|
|
189
|
-
// Link PR to ticket
|
|
190
|
-
await storage.updateTicket(ticketId, {
|
|
191
|
-
metadata: {
|
|
192
|
-
...ticket.metadata,
|
|
193
|
-
pr_url: prInfo.url,
|
|
194
|
-
pr_number: String(prInfo.number),
|
|
195
|
-
pr_branch: prInfo.headBranch,
|
|
196
|
-
},
|
|
163
|
+
})),
|
|
197
164
|
});
|
|
198
|
-
await
|
|
199
|
-
|
|
200
|
-
this.log('');
|
|
201
|
-
this.log(styles.success(`PR linked to ticket!`));
|
|
202
|
-
this.log(styles.muted(` Ticket: ${ticketId}`));
|
|
203
|
-
this.log(styles.muted(` PR: #${prInfo.number} - ${prInfo.title}`));
|
|
204
|
-
this.log(styles.muted(` URL: ${prInfo.url}`));
|
|
165
|
+
const prResolved = await prResolver.resolve();
|
|
166
|
+
prNumber = parseInt(prResolved.pr, 10);
|
|
205
167
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
168
|
+
// Get PR info
|
|
169
|
+
const prInfo = getPRByNumber(prNumber);
|
|
170
|
+
if (!prInfo) {
|
|
171
|
+
this.error(`PR #${prNumber} not found.`);
|
|
210
172
|
}
|
|
173
|
+
// Link PR to ticket
|
|
174
|
+
await this.storage.updateTicket(ticketId, {
|
|
175
|
+
metadata: {
|
|
176
|
+
...ticket.metadata,
|
|
177
|
+
pr_url: prInfo.url,
|
|
178
|
+
pr_number: String(prInfo.number),
|
|
179
|
+
pr_branch: prInfo.headBranch,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
this.log('');
|
|
183
|
+
this.log(styles.success(`PR linked to ticket!`));
|
|
184
|
+
this.log(styles.muted(` Ticket: ${ticketId}`));
|
|
185
|
+
this.log(styles.muted(` PR: #${prInfo.number} - ${prInfo.title}`));
|
|
186
|
+
this.log(styles.muted(` URL: ${prInfo.url}`));
|
|
211
187
|
}
|
|
212
188
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class PRStatus extends
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class PRStatus extends PMOCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
6
6
|
ticketId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
7
|
};
|
|
8
8
|
static flags: {
|
|
9
|
+
ticket: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
11
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
13
|
};
|
|
11
|
-
|
|
14
|
+
execute(): Promise<void>;
|
|
12
15
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import Database from 'better-sqlite3';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { getPMOContext } from '../../lib/pmo/index.js';
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags, } from '../../lib/pmo/index.js';
|
|
6
3
|
import { styles } from '../../lib/styles.js';
|
|
7
|
-
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
8
4
|
import { isGHInstalled, isGHAuthenticated, getPRByNumber, } from '../../lib/pr/index.js';
|
|
9
|
-
import { shouldOutputJson,
|
|
10
|
-
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
6
|
+
import { FlagResolver } from '../../lib/flags/index.js';
|
|
7
|
+
export default class PRStatus extends PMOCommand {
|
|
11
8
|
static description = 'View PR status for a ticket';
|
|
12
9
|
static examples = [
|
|
13
10
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -20,12 +17,12 @@ export default class PRStatus extends Command {
|
|
|
20
17
|
}),
|
|
21
18
|
};
|
|
22
19
|
static flags = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
...pmoBaseFlags,
|
|
21
|
+
ticket: Flags.string({
|
|
22
|
+
description: 'Ticket ID to check (alternative to positional arg)',
|
|
26
23
|
}),
|
|
27
24
|
};
|
|
28
|
-
async
|
|
25
|
+
async execute() {
|
|
29
26
|
const { args, flags } = await this.parse(PRStatus);
|
|
30
27
|
// Check if JSON output mode is active
|
|
31
28
|
const jsonMode = shouldOutputJson(flags);
|
|
@@ -37,125 +34,103 @@ export default class PRStatus extends Command {
|
|
|
37
34
|
}
|
|
38
35
|
this.error(message);
|
|
39
36
|
};
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
workspaceInfo = getWorkspaceInfo();
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
37
|
+
// PMOCommand ensures we have storage access
|
|
38
|
+
if (!this.storage) {
|
|
46
39
|
return handleError('NOT_IN_WORKSPACE', 'Not in a workspace. Run "prlt init" first.');
|
|
47
40
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
const allTickets = await storage.listTickets(projectId);
|
|
59
|
-
// Filter to tickets that have a PR linked
|
|
60
|
-
const ticketsWithPR = allTickets.filter(t => t.metadata?.pr_url);
|
|
61
|
-
const ticketsWithoutPR = allTickets.filter(t => !t.metadata?.pr_url && t.statusName && !t.statusName.toLowerCase().includes('done'));
|
|
62
|
-
if (ticketsWithPR.length === 0 && ticketsWithoutPR.length === 0) {
|
|
63
|
-
await storage.close();
|
|
64
|
-
db.close();
|
|
65
|
-
this.log(styles.info('No tickets found.'));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
// Build choices once, use for both JSON and interactive modes
|
|
69
|
-
const ticketsWithPRChoices = ticketsWithPR.map(t => ({
|
|
70
|
-
name: `${t.id} - ${t.title} [PR linked]`,
|
|
71
|
-
value: t.id,
|
|
72
|
-
}));
|
|
73
|
-
const ticketsWithoutPRChoices = ticketsWithoutPR.slice(0, 10).map(t => ({
|
|
74
|
-
name: `${t.id} - ${t.title} (${t.statusName})`,
|
|
75
|
-
value: t.id,
|
|
76
|
-
}));
|
|
77
|
-
const ticketChoices = [...ticketsWithPRChoices, ...ticketsWithoutPRChoices];
|
|
78
|
-
const message = 'Select ticket to check PR status:';
|
|
79
|
-
// In JSON mode, output ticket selection prompt and exit
|
|
80
|
-
if (jsonMode) {
|
|
81
|
-
outputPromptAsJson(buildPromptConfig('list', 'ticketId', message, ticketChoices), createMetadata('pr status', flags));
|
|
82
|
-
}
|
|
83
|
-
// Build interactive choices with separator
|
|
84
|
-
const interactiveChoices = [...ticketsWithPRChoices];
|
|
85
|
-
if (ticketsWithoutPRChoices.length > 0) {
|
|
86
|
-
interactiveChoices.push(new inquirer.Separator('── No PR Linked ──'));
|
|
87
|
-
interactiveChoices.push(...ticketsWithoutPRChoices);
|
|
88
|
-
}
|
|
89
|
-
const { selectedTicketId } = await inquirer.prompt([{
|
|
90
|
-
type: 'list',
|
|
91
|
-
name: 'selectedTicketId',
|
|
92
|
-
message,
|
|
93
|
-
choices: interactiveChoices,
|
|
94
|
-
}]);
|
|
95
|
-
ticketId = selectedTicketId;
|
|
96
|
-
}
|
|
97
|
-
// Get ticket
|
|
98
|
-
const ticket = await storage.getTicket(ticketId);
|
|
99
|
-
if (!ticket) {
|
|
100
|
-
await storage.close();
|
|
101
|
-
db.close();
|
|
102
|
-
this.error(`Ticket "${ticketId}" not found.`);
|
|
103
|
-
}
|
|
104
|
-
this.log('');
|
|
105
|
-
this.log(styles.header(`PR Status: ${ticket.id}`));
|
|
106
|
-
this.log(styles.muted(` Title: ${ticket.title}`));
|
|
107
|
-
this.log(styles.muted(` Status: ${ticket.statusName}`));
|
|
108
|
-
this.log('');
|
|
109
|
-
if (!ticket.metadata?.pr_url) {
|
|
110
|
-
this.log(styles.info('No PR linked to this ticket.'));
|
|
111
|
-
this.log(styles.muted(' Use "prlt pr create" or "prlt pr link" to link a PR.'));
|
|
112
|
-
await storage.close();
|
|
113
|
-
db.close();
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
// Check gh CLI for live status
|
|
117
|
-
if (!isGHInstalled() || !isGHAuthenticated()) {
|
|
118
|
-
this.log(styles.muted(' PR URL:'), ticket.metadata.pr_url);
|
|
119
|
-
this.log(styles.muted(' (Install and authenticate `gh` CLI for live status)'));
|
|
120
|
-
await storage.close();
|
|
121
|
-
db.close();
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const prNumber = parseInt(ticket.metadata.pr_number || '0', 10);
|
|
125
|
-
if (!prNumber) {
|
|
126
|
-
this.log(styles.muted(' PR URL:'), ticket.metadata.pr_url);
|
|
127
|
-
await storage.close();
|
|
128
|
-
db.close();
|
|
41
|
+
// Get ticket ID from args or flags
|
|
42
|
+
let ticketId = args.ticketId || flags.ticket;
|
|
43
|
+
if (!ticketId) {
|
|
44
|
+
const projectId = flags.project;
|
|
45
|
+
const allTickets = await this.storage.listTickets(projectId);
|
|
46
|
+
// Filter to tickets that have a PR linked
|
|
47
|
+
const ticketsWithPR = allTickets.filter(t => t.metadata?.pr_url);
|
|
48
|
+
const ticketsWithoutPR = allTickets.filter(t => !t.metadata?.pr_url && t.statusName && !t.statusName.toLowerCase().includes('done'));
|
|
49
|
+
if (ticketsWithPR.length === 0 && ticketsWithoutPR.length === 0) {
|
|
50
|
+
this.log(styles.info('No tickets found.'));
|
|
129
51
|
return;
|
|
130
52
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
53
|
+
// Combine tickets for selection - prioritize those with PRs
|
|
54
|
+
const allSelectableTickets = [
|
|
55
|
+
...ticketsWithPR.map(t => ({
|
|
56
|
+
id: t.id,
|
|
57
|
+
title: t.title,
|
|
58
|
+
hasPR: true,
|
|
59
|
+
statusName: t.statusName,
|
|
60
|
+
})),
|
|
61
|
+
...ticketsWithoutPR.slice(0, 10).map(t => ({
|
|
62
|
+
id: t.id,
|
|
63
|
+
title: t.title,
|
|
64
|
+
hasPR: false,
|
|
65
|
+
statusName: t.statusName,
|
|
66
|
+
})),
|
|
67
|
+
];
|
|
68
|
+
// Use FlagResolver for ticket selection
|
|
69
|
+
const resolver = new FlagResolver({
|
|
70
|
+
commandName: 'pr status',
|
|
71
|
+
baseCommand: 'prlt pr status',
|
|
72
|
+
jsonMode,
|
|
73
|
+
flags: { ticket: ticketId },
|
|
74
|
+
});
|
|
75
|
+
resolver.addPrompt({
|
|
76
|
+
flagName: 'ticket',
|
|
77
|
+
type: 'list',
|
|
78
|
+
message: 'Select ticket to check PR status:',
|
|
79
|
+
choices: () => allSelectableTickets.map(item => ({
|
|
80
|
+
name: item.hasPR
|
|
81
|
+
? `${item.id} - ${item.title} [PR linked]`
|
|
82
|
+
: `${item.id} - ${item.title} (${item.statusName})`,
|
|
83
|
+
value: item.id,
|
|
84
|
+
})),
|
|
85
|
+
when: (ctx) => !ctx.flags.ticket,
|
|
86
|
+
});
|
|
87
|
+
const resolved = await resolver.resolve();
|
|
88
|
+
ticketId = resolved.ticket;
|
|
89
|
+
}
|
|
90
|
+
// Get ticket
|
|
91
|
+
const ticket = await this.storage.getTicket(ticketId);
|
|
92
|
+
if (!ticket) {
|
|
93
|
+
this.error(`Ticket "${ticketId}" not found.`);
|
|
94
|
+
}
|
|
95
|
+
this.log('');
|
|
96
|
+
this.log(styles.header(`PR Status: ${ticket.id}`));
|
|
97
|
+
this.log(styles.muted(` Title: ${ticket.title}`));
|
|
98
|
+
this.log(styles.muted(` Status: ${ticket.statusName}`));
|
|
99
|
+
this.log('');
|
|
100
|
+
if (!ticket.metadata?.pr_url) {
|
|
101
|
+
this.log(styles.info('No PR linked to this ticket.'));
|
|
102
|
+
this.log(styles.muted(' Use "prlt pr create" or "prlt pr link" to link a PR.'));
|
|
103
|
+
return;
|
|
154
104
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
105
|
+
// Check gh CLI for live status
|
|
106
|
+
if (!isGHInstalled() || !isGHAuthenticated()) {
|
|
107
|
+
this.log(styles.muted(' PR URL:'), ticket.metadata.pr_url);
|
|
108
|
+
this.log(styles.muted(' (Install and authenticate `gh` CLI for live status)'));
|
|
109
|
+
return;
|
|
159
110
|
}
|
|
111
|
+
const prNumber = parseInt(ticket.metadata.pr_number || '0', 10);
|
|
112
|
+
if (!prNumber) {
|
|
113
|
+
this.log(styles.muted(' PR URL:'), ticket.metadata.pr_url);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const prInfo = getPRByNumber(prNumber);
|
|
117
|
+
if (!prInfo) {
|
|
118
|
+
this.log(styles.warning('Unable to fetch PR status (PR may have been deleted).'));
|
|
119
|
+
this.log(styles.muted(' Stored URL:'), ticket.metadata.pr_url);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// Display PR status
|
|
123
|
+
const stateEmoji = {
|
|
124
|
+
OPEN: '🟢',
|
|
125
|
+
CLOSED: '🔴',
|
|
126
|
+
MERGED: '🟣',
|
|
127
|
+
};
|
|
128
|
+
this.log(styles.success(`${stateEmoji[prInfo.state]} PR #${prInfo.number}: ${prInfo.title}`));
|
|
129
|
+
this.log('');
|
|
130
|
+
this.log(styles.muted(` State: ${prInfo.state}${prInfo.isDraft ? ' (Draft)' : ''}`));
|
|
131
|
+
this.log(styles.muted(` Branch: ${prInfo.headBranch} → ${prInfo.baseBranch}`));
|
|
132
|
+
this.log(styles.muted(` URL: ${prInfo.url}`));
|
|
133
|
+
this.log(styles.muted(` Created: ${new Date(prInfo.createdAt).toLocaleDateString()}`));
|
|
134
|
+
this.log(styles.muted(` Updated: ${new Date(prInfo.updatedAt).toLocaleDateString()}`));
|
|
160
135
|
}
|
|
161
136
|
}
|
|
@@ -7,6 +7,7 @@ export default class ProjectArchive extends PMOCommand {
|
|
|
7
7
|
};
|
|
8
8
|
static flags: {
|
|
9
9
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|