ya-git-jira 1.6.0 → 2.0.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 (86) hide show
  1. package/.opencode/skills/architecture/SKILL.md +45 -0
  2. package/.opencode/skills/code-style/SKILL.md +76 -0
  3. package/.opencode/skills/git-confluence/SKILL.md +82 -0
  4. package/.opencode/skills/git-jira/SKILL.md +63 -0
  5. package/.opencode/skills/git-lab/SKILL.md +102 -0
  6. package/AGENTS.md +50 -0
  7. package/README.md +106 -106
  8. package/bin/git-api.ts +70 -0
  9. package/bin/git-confluence-page-search.ts +58 -0
  10. package/bin/git-confluence-page-show.ts +61 -0
  11. package/bin/git-confluence-page-update.ts +77 -0
  12. package/bin/git-confluence-page.ts +28 -0
  13. package/bin/git-confluence-space-list.ts +34 -0
  14. package/bin/git-confluence-space.ts +24 -0
  15. package/bin/git-confluence-whoami.ts +33 -0
  16. package/bin/git-confluence.ts +27 -0
  17. package/bin/git-jira-start.ts +1 -1
  18. package/bin/git-jira-whoami.ts +32 -0
  19. package/bin/git-jira.ts +2 -0
  20. package/bin/git-lab-project-mr-list.ts +57 -0
  21. package/bin/git-lab-project-mr.ts +24 -0
  22. package/bin/git-lab-project-pipeline-jobs.ts +46 -0
  23. package/bin/git-lab-project-pipeline-latest.ts +47 -0
  24. package/bin/git-lab-project-pipeline-log.ts +49 -0
  25. package/bin/git-lab-project-pipeline.ts +6 -0
  26. package/bin/git-lab-project.ts +5 -1
  27. package/bin/gitj-install-skills.ts +126 -0
  28. package/bin/gitj.ts +12 -0
  29. package/dist/bin/git-api.js +2156 -0
  30. package/dist/bin/git-bump.js +132 -121
  31. package/dist/bin/git-confluence-page-search.js +2079 -0
  32. package/dist/bin/git-confluence-page-show.js +2082 -0
  33. package/dist/bin/git-confluence-page-update.js +2093 -0
  34. package/dist/bin/git-confluence-page.js +2186 -0
  35. package/dist/bin/git-confluence-space-list.js +2061 -0
  36. package/dist/bin/git-confluence-space.js +2073 -0
  37. package/dist/bin/git-confluence-whoami.js +2060 -0
  38. package/dist/bin/git-confluence.js +2251 -0
  39. package/dist/bin/git-jira-issue-list.js +136 -125
  40. package/dist/bin/git-jira-issue-show.js +136 -125
  41. package/dist/bin/git-jira-issue.js +140 -129
  42. package/dist/bin/git-jira-start.js +138 -127
  43. package/dist/bin/git-jira-whoami.js +1972 -0
  44. package/dist/bin/git-jira.js +170 -139
  45. package/dist/bin/git-lab-group-list.js +321 -279
  46. package/dist/bin/git-lab-group.js +323 -281
  47. package/dist/bin/git-lab-merge-active.js +321 -279
  48. package/dist/bin/git-lab-merge-todo.js +321 -279
  49. package/dist/bin/git-lab-merge-train-list.js +289 -273
  50. package/dist/bin/git-lab-merge-train.js +291 -275
  51. package/dist/bin/git-lab-merge.js +330 -288
  52. package/dist/bin/git-lab-namespace-list.js +138 -127
  53. package/dist/bin/git-lab-namespace.js +140 -129
  54. package/dist/bin/git-lab-project-list.js +288 -272
  55. package/dist/bin/git-lab-project-mr-list.js +2740 -0
  56. package/dist/bin/git-lab-project-mr.js +2752 -0
  57. package/dist/bin/git-lab-project-pipeline-jobs.js +2734 -0
  58. package/dist/bin/git-lab-project-pipeline-latest.js +2736 -0
  59. package/dist/bin/git-lab-project-pipeline-list.js +323 -281
  60. package/dist/bin/git-lab-project-pipeline-log.js +2739 -0
  61. package/dist/bin/git-lab-project-pipeline.js +437 -292
  62. package/dist/bin/git-lab-project-whereami.js +292 -276
  63. package/dist/bin/git-lab-project.js +563 -288
  64. package/dist/bin/git-lab-whoami.js +142 -131
  65. package/dist/bin/git-lab.js +575 -338
  66. package/dist/bin/gitj-install-skills.js +1954 -0
  67. package/dist/bin/gitj.js +1385 -473
  68. package/dist/index.js +371 -187
  69. package/index.ts +1 -0
  70. package/lib/api.ts +177 -0
  71. package/lib/confluence/api.ts +132 -0
  72. package/lib/confluence/config.ts +25 -0
  73. package/lib/confluence/index.ts +3 -0
  74. package/lib/confluence/types.ts +59 -0
  75. package/lib/gitlab/index.ts +1 -0
  76. package/lib/gitlab/job.ts +31 -0
  77. package/lib/gitlab/merge-request.ts +20 -0
  78. package/lib/gitlab/pipeline.ts +28 -1
  79. package/lib/gitlab/project.ts +14 -5
  80. package/lib/help.ts +40 -0
  81. package/lib/jira.ts +2 -2
  82. package/package.json +18 -2
  83. package/tests/all-help.test.ts +6 -1
  84. package/tests/gitj.test.ts +1 -1
  85. package/tests/help-all.test.ts +29 -0
  86. package/bun.lockb +0 -0
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { isMain } from '../lib/is_main'
6
+ import whoami from './git-confluence-whoami'
7
+ import space from './git-confluence-space'
8
+ import page from './git-confluence-page'
9
+ const version = await getPackageVersion()
10
+
11
+ export function create(): Command {
12
+ const program: Command = new Command()
13
+ program
14
+ .version(version)
15
+ .name('confluence')
16
+ .description('Commands for working with Confluence')
17
+ .addCommand(whoami())
18
+ .addCommand(space())
19
+ .addCommand(page())
20
+ return program
21
+ }
22
+
23
+ export default create
24
+
25
+ if (isMain('git-confluence')) {
26
+ await create().parseAsync(Bun.argv)
27
+ }
@@ -8,7 +8,7 @@ import { isMain } from '../lib/is_main'
8
8
  const version = await getPackageVersion()
9
9
 
10
10
  function toKebab(s: string): string {
11
- return s.replace(/([a-z]+)([A-Z]+)/g, "$1_2").toLowerCase()
11
+ return s.replace(/([a-z]+)([A-Z]+)/g, "$1_$2").toLowerCase()
12
12
  .replace(/(\W+)/g, "-")
13
13
  .replace(/-$/, "")
14
14
  }
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { getMyself } from '../lib/jira'
6
+ import { isMain } from '../lib/is_main'
7
+ const version = await getPackageVersion()
8
+
9
+ export function create(): Command {
10
+ const program: Command = new Command()
11
+ program
12
+ .version(version)
13
+ .name('whoami')
14
+ .description('Show the current Jira user')
15
+ .option('-v, --verbose', 'Verbose output')
16
+ .action(async (options) => {
17
+ const myself = await getMyself()
18
+ if (options.verbose) {
19
+ console.log(myself)
20
+ } else {
21
+ const { displayName, emailAddress, accountId } = myself as any
22
+ console.log({ displayName, emailAddress, accountId })
23
+ }
24
+ })
25
+ return program
26
+ }
27
+
28
+ export default create
29
+
30
+ if (isMain('git-jira-whoami')) {
31
+ await create().parseAsync(Bun.argv)
32
+ }
package/bin/git-jira.ts CHANGED
@@ -6,6 +6,7 @@ import { isMain } from '../lib/is_main'
6
6
  import start from './git-jira-start'
7
7
  import issue from './git-jira-issue'
8
8
  import issues from './git-jira-issue-list'
9
+ import whoami from './git-jira-whoami'
9
10
  const version = await getPackageVersion()
10
11
 
11
12
  export function create(): Command {
@@ -17,6 +18,7 @@ export function create(): Command {
17
18
  .addCommand(start())
18
19
  .addCommand(issue())
19
20
  .addCommand(issues())
21
+ .addCommand(whoami())
20
22
  return program
21
23
  }
22
24
 
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { getMergeRequestsByBranch, type MergeRequest } from "../lib/gitlab"
6
+ import { findProject } from '../lib/gitlab/project'
7
+ import { getRemote, getCurrentBranch } from '../lib/git'
8
+ import { isMain } from '../lib/is_main'
9
+ const version = await getPackageVersion()
10
+
11
+ export function create(): Command {
12
+ const program: Command = new Command()
13
+ program
14
+ .version(version)
15
+ .name('list')
16
+ .description('List open merge requests for a project and branch')
17
+ .option('-v, --verbose', 'Verbose output')
18
+ .option('-p, --project <path>', 'Project path (e.g. etagen-internal/eta-lib/base). Defaults to current directory remote.')
19
+ .option('-b, --branch <branch>', 'Source branch to filter on. Defaults to current branch.')
20
+ .action(async (options) => {
21
+ let projectPath = options.project
22
+ if (!projectPath) {
23
+ const remote = await getRemote()
24
+ const project = await findProject(remote)
25
+ if (!project) {
26
+ console.error(`Could not resolve project from remote: ${remote}`)
27
+ process.exit(1)
28
+ }
29
+ projectPath = project.path_with_namespace
30
+ }
31
+
32
+ const branch = options.branch || await getCurrentBranch()
33
+
34
+ const mrs: Array<MergeRequest> = await getMergeRequestsByBranch(projectPath, branch)
35
+ if (!mrs.length) {
36
+ console.error(`No open MRs for branch '${branch}' in ${projectPath}`)
37
+ process.exit(0)
38
+ }
39
+ if (options.verbose) {
40
+ console.log(mrs)
41
+ }
42
+ else {
43
+ const filtered = mrs.map(m => {
44
+ const { iid, title, web_url, source_branch, target_branch, state, draft } = m
45
+ return { iid, title, web_url, source_branch, target_branch, state, draft }
46
+ })
47
+ console.log(filtered)
48
+ }
49
+ })
50
+ return program
51
+ }
52
+
53
+ export default create
54
+
55
+ if (isMain('git-lab-project-mr-list')) {
56
+ await create().parseAsync(Bun.argv)
57
+ }
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { isMain } from '../lib/is_main'
6
+ import list from './git-lab-project-mr-list'
7
+ const version = await getPackageVersion()
8
+
9
+ export function create(): Command {
10
+ const program: Command = new Command()
11
+ program
12
+ .version(version)
13
+ .name('mr')
14
+ .description('Commands for working with merge requests')
15
+ .addCommand(list())
16
+ .action(() => program.help())
17
+ return program
18
+ }
19
+
20
+ export default create
21
+
22
+ if (isMain('git-lab-project-mr')) {
23
+ await create().parseAsync(Bun.argv)
24
+ }
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { getPipelineJobs, type Job } from '../lib/gitlab'
6
+ import { isMain } from '../lib/is_main'
7
+
8
+ const version = await getPackageVersion()
9
+
10
+ export function create(): Command {
11
+ const program: Command = new Command()
12
+ program
13
+ .version(version)
14
+ .name('jobs')
15
+ .description('List jobs for a pipeline')
16
+ .requiredOption('-p, --pipeline <id>', 'Pipeline ID')
17
+ .option('-v, --verbose', 'Verbose output')
18
+ .action(async (options) => {
19
+ const pipelineId = parseInt(options.pipeline, 10)
20
+ if (isNaN(pipelineId)) {
21
+ console.error(`Invalid pipeline ID: ${options.pipeline}`)
22
+ process.exit(1)
23
+ }
24
+ const jobs: Array<Job> = await getPipelineJobs(pipelineId)
25
+ if (!jobs || jobs.length === 0) {
26
+ console.error(`No jobs found for pipeline ${pipelineId}`)
27
+ process.exit(1)
28
+ }
29
+ if (options.verbose) {
30
+ console.log(JSON.stringify(jobs, null, 2))
31
+ } else {
32
+ const filtered = jobs.map((j: Job) => {
33
+ const { id, name, stage, status, duration, failure_reason } = j
34
+ return { id, name, stage, status, duration, failure_reason }
35
+ })
36
+ console.log(JSON.stringify(filtered, null, 2))
37
+ }
38
+ })
39
+ return program
40
+ }
41
+
42
+ export default create
43
+
44
+ if (isMain('git-lab-project-pipeline-jobs')) {
45
+ await create().parseAsync(Bun.argv)
46
+ }
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { getLatestPipeline, type Pipeline, getPipelineJobs, type Job } from '../lib/gitlab'
6
+ import { isMain } from '../lib/is_main'
7
+
8
+ const version = await getPackageVersion()
9
+
10
+ export function create(): Command {
11
+ const program: Command = new Command()
12
+ program
13
+ .version(version)
14
+ .name('latest')
15
+ .description('Show jobs for the latest pipeline on the current branch')
16
+ .option('-v, --verbose', 'Verbose output')
17
+ .action(async (options) => {
18
+ const pipeline: Pipeline | undefined = await getLatestPipeline()
19
+ if (!pipeline) {
20
+ console.error('No pipeline found for the current branch')
21
+ process.exit(1)
22
+ }
23
+ const { id, status, ref, web_url } = pipeline
24
+ console.log(JSON.stringify({ id, status, ref, web_url }, null, 2))
25
+ const jobs: Array<Job> = await getPipelineJobs(pipeline.id)
26
+ if (!jobs || jobs.length === 0) {
27
+ console.error(`No jobs found for pipeline ${pipeline.id}`)
28
+ process.exit(1)
29
+ }
30
+ if (options.verbose) {
31
+ console.log(JSON.stringify(jobs, null, 2))
32
+ } else {
33
+ const filtered = jobs.map((j: Job) => {
34
+ const { id, name, stage, status, duration, failure_reason } = j
35
+ return { id, name, stage, status, duration, failure_reason }
36
+ })
37
+ console.log(JSON.stringify(filtered, null, 2))
38
+ }
39
+ })
40
+ return program
41
+ }
42
+
43
+ export default create
44
+
45
+ if (isMain('git-lab-project-pipeline-latest')) {
46
+ await create().parseAsync(Bun.argv)
47
+ }
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { getJobLog } from '../lib/gitlab'
6
+ import { isMain } from '../lib/is_main'
7
+
8
+ const version = await getPackageVersion()
9
+
10
+ export function create(): Command {
11
+ const program: Command = new Command()
12
+ program
13
+ .version(version)
14
+ .name('log')
15
+ .description('Download a job log')
16
+ .requiredOption('-j, --job <id>', 'Job ID')
17
+ .option('-t, --tail <lines>', 'Show only the last N lines')
18
+ .action(async (options) => {
19
+ const jobId = parseInt(options.job, 10)
20
+ if (isNaN(jobId)) {
21
+ console.error(`Invalid job ID: ${options.job}`)
22
+ process.exit(1)
23
+ }
24
+ const log = await getJobLog(jobId)
25
+ if (!log) {
26
+ console.error(`No log output for job ${jobId}`)
27
+ process.exit(1)
28
+ }
29
+ if (options.tail) {
30
+ const n = parseInt(options.tail, 10)
31
+ if (isNaN(n)) {
32
+ console.error(`Invalid --tail value: ${options.tail}`)
33
+ process.exit(1)
34
+ }
35
+ const lines = log.split('\n')
36
+ const tail = lines.slice(-n)
37
+ process.stdout.write(tail.join('\n'))
38
+ } else {
39
+ process.stdout.write(log)
40
+ }
41
+ })
42
+ return program
43
+ }
44
+
45
+ export default create
46
+
47
+ if (isMain('git-lab-project-pipeline-log')) {
48
+ await create().parseAsync(Bun.argv)
49
+ }
@@ -3,7 +3,10 @@
3
3
  import { Command } from 'commander'
4
4
  import { getPackageVersion } from '../lib/package'
5
5
  import { isMain } from '../lib/is_main'
6
+ import jobs from './git-lab-project-pipeline-jobs'
7
+ import latest from './git-lab-project-pipeline-latest'
6
8
  import list from './git-lab-project-pipeline-list'
9
+ import log from './git-lab-project-pipeline-log'
7
10
  const version = await getPackageVersion()
8
11
 
9
12
  export function create(): Command {
@@ -12,7 +15,10 @@ export function create(): Command {
12
15
  .version(version)
13
16
  .name('pipeline')
14
17
  .description('Commands for working with GitLab pipelines')
18
+ .addCommand(jobs())
19
+ .addCommand(latest())
15
20
  .addCommand(list())
21
+ .addCommand(log())
16
22
  .action(() => program.help())
17
23
  return program
18
24
  }
@@ -4,6 +4,8 @@ import { Command } from 'commander'
4
4
  import { getPackageVersion } from '../lib/package'
5
5
  import { isMain } from '../lib/is_main'
6
6
  import list from './git-lab-project-list'
7
+ import mr from './git-lab-project-mr'
8
+ import pipeline from './git-lab-project-pipeline'
7
9
  import whereami from './git-lab-project-whereami'
8
10
  const version = await getPackageVersion()
9
11
 
@@ -11,9 +13,11 @@ export function create(): Command {
11
13
  const program: Command = new Command()
12
14
  program
13
15
  .version(version)
14
- .name('projects')
16
+ .name('project')
15
17
  .description('Commands for working with GitLab projects')
16
18
  .addCommand(list())
19
+ .addCommand(mr())
20
+ .addCommand(pipeline())
17
21
  .addCommand(whereami())
18
22
  .action(() => {
19
23
  program.help()
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { getPackageVersion } from '../lib/package'
5
+ import { findPackageJson } from '../lib/package'
6
+ import { isMain } from '../lib/is_main'
7
+ import fs from 'node:fs'
8
+ import path from 'node:path'
9
+ import os from 'node:os'
10
+
11
+ const version = await getPackageVersion()
12
+
13
+ const frameworks = ['opencode', 'copilot', 'claude'] as const
14
+ type Framework = typeof frameworks[number]
15
+
16
+ const skillNames = ['git-jira', 'git-lab', 'git-confluence']
17
+
18
+ function getSkillsSourceDir(): string {
19
+ const packageJsonPath = findPackageJson()
20
+ if (!packageJsonPath) {
21
+ throw new Error('Cannot find package.json for ya-git-jira')
22
+ }
23
+ const packageRoot = path.dirname(packageJsonPath)
24
+ const skillsDir = path.join(packageRoot, '.opencode', 'skills')
25
+ if (!fs.existsSync(skillsDir)) {
26
+ throw new Error(`Skills directory not found: ${skillsDir}`)
27
+ }
28
+ return skillsDir
29
+ }
30
+
31
+ function getTargetDir(framework: Framework): string {
32
+ const home = os.homedir()
33
+ switch (framework) {
34
+ case 'opencode':
35
+ return path.join(home, '.config', 'opencode', 'skills')
36
+ case 'copilot':
37
+ return path.join(home, '.copilot', 'skills')
38
+ case 'claude':
39
+ return path.join(process.cwd(), '.claude', 'skills')
40
+ }
41
+ }
42
+
43
+ function installSkills(framework: Framework, copy: boolean): void {
44
+ const sourceDir = getSkillsSourceDir()
45
+ const targetDir = getTargetDir(framework)
46
+
47
+ fs.mkdirSync(targetDir, { recursive: true })
48
+
49
+ for (const name of skillNames) {
50
+ const source = path.join(sourceDir, name)
51
+ const target = path.join(targetDir, name)
52
+
53
+ if (fs.existsSync(target)) {
54
+ const stat = fs.lstatSync(target)
55
+ if (stat.isSymbolicLink()) {
56
+ fs.unlinkSync(target)
57
+ } else if (stat.isDirectory()) {
58
+ console.error(`${target} already exists as a directory -- skipping (use --force to overwrite)`)
59
+ continue
60
+ }
61
+ }
62
+
63
+ if (copy) {
64
+ fs.cpSync(source, target, { recursive: true })
65
+ console.log(`copied ${name} -> ${target}`)
66
+ } else {
67
+ fs.symlinkSync(source, target)
68
+ console.log(`linked ${name} -> ${target}`)
69
+ }
70
+ }
71
+ }
72
+
73
+ function forceInstallSkills(framework: Framework, copy: boolean): void {
74
+ const sourceDir = getSkillsSourceDir()
75
+ const targetDir = getTargetDir(framework)
76
+
77
+ fs.mkdirSync(targetDir, { recursive: true })
78
+
79
+ for (const name of skillNames) {
80
+ const source = path.join(sourceDir, name)
81
+ const target = path.join(targetDir, name)
82
+
83
+ if (fs.existsSync(target) || fs.lstatSync(target).isSymbolicLink()) {
84
+ fs.rmSync(target, { recursive: true, force: true })
85
+ }
86
+
87
+ if (copy) {
88
+ fs.cpSync(source, target, { recursive: true })
89
+ console.log(`copied ${name} -> ${target}`)
90
+ } else {
91
+ fs.symlinkSync(source, target)
92
+ console.log(`linked ${name} -> ${target}`)
93
+ }
94
+ }
95
+ }
96
+
97
+ export function create(): Command {
98
+ const program: Command = new Command()
99
+ program
100
+ .version(version)
101
+ .name('install-skills')
102
+ .description('Install AI agent skills for a coding framework')
103
+ .argument('<framework>', `framework to install for (${frameworks.join(', ')})`)
104
+ .option('--copy', 'copy files instead of creating symlinks')
105
+ .option('--force', 'overwrite existing skill directories')
106
+ .action(async (framework: string, options: { copy?: boolean; force?: boolean }) => {
107
+ if (!frameworks.includes(framework as Framework)) {
108
+ console.error(`Unknown framework: ${framework}`)
109
+ console.error(`Supported frameworks: ${frameworks.join(', ')}`)
110
+ process.exit(1)
111
+ }
112
+
113
+ if (options.force) {
114
+ forceInstallSkills(framework as Framework, !!options.copy)
115
+ } else {
116
+ installSkills(framework as Framework, !!options.copy)
117
+ }
118
+ })
119
+ return program
120
+ }
121
+
122
+ export default create
123
+
124
+ if (isMain('gitj-install-skills')) {
125
+ await create().parseAsync(Bun.argv)
126
+ }
package/bin/gitj.ts CHANGED
@@ -6,8 +6,12 @@
6
6
  // from the command line and then call the appropriate subcommand.
7
7
 
8
8
  import { Command } from 'commander'
9
+ import { formatCommandTree } from '../lib/help.ts'
9
10
  import { getPackageVersion } from '../lib/package'
11
+ import api from './git-api'
10
12
  import bump from './git-bump'
13
+ import confluence from './git-confluence'
14
+ import installSkills from './gitj-install-skills'
11
15
  import jira from './git-jira'
12
16
  import lab from './git-lab'
13
17
  const version = await getPackageVersion()
@@ -16,10 +20,18 @@ export function create(): Command {
16
20
  const program: Command = new Command()
17
21
  program
18
22
  .version(version)
23
+ .option('--help-all', 'Show full command tree')
24
+ .addCommand(api())
19
25
  .addCommand(bump())
26
+ .addCommand(confluence())
27
+ .addCommand(installSkills())
20
28
  .addCommand(jira())
21
29
  .addCommand(lab())
22
30
  .action(() => {
31
+ if (program.opts().helpAll) {
32
+ console.log(formatCommandTree(program))
33
+ return
34
+ }
23
35
  program.help()
24
36
  })
25
37
  return program