@rahul05ranjan/dhruv-cli 1.3.0 → 1.5.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 (121) hide show
  1. package/.github/ENTERPRISE.md +275 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +45 -17
  3. package/.github/ISSUE_TEMPLATE/documentation_issue.md +61 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +61 -9
  5. package/.github/ISSUE_TEMPLATE/security_vulnerability.md +74 -0
  6. package/.github/dependabot.yml +42 -2
  7. package/.github/pull_request_template.md +13 -0
  8. package/.github/workflows/ci.yml +51 -38
  9. package/.github/workflows/contribution.yml +41 -34
  10. package/.github/workflows/dependabot-auto-merge.yml +62 -2
  11. package/.github/workflows/labeler.yml +1 -0
  12. package/.github/workflows/release.yml +229 -0
  13. package/.github/workflows/security.yml +201 -0
  14. package/.releaserc.json +50 -0
  15. package/AGENTS.md +13 -0
  16. package/CHANGELOG.md +13 -0
  17. package/README.md +145 -40
  18. package/__tests__/cli-contract.test.ts +104 -0
  19. package/__tests__/core.test.ts +439 -0
  20. package/__tests__/diagnostics.test.ts +155 -0
  21. package/__tests__/file-workflows.test.ts +195 -0
  22. package/__tests__/interactive.test.ts +119 -0
  23. package/__tests__/setup.ts +62 -0
  24. package/__tests__/workflows.test.ts +118 -0
  25. package/dist/commands/explain.js +13 -44
  26. package/dist/commands/fix.js +13 -38
  27. package/dist/commands/generate.d.ts +6 -1
  28. package/dist/commands/generate.js +60 -55
  29. package/dist/commands/health.d.ts +4 -0
  30. package/dist/commands/health.js +419 -0
  31. package/dist/commands/init.js +56 -42
  32. package/dist/commands/menu.js +137 -24
  33. package/dist/commands/metrics.d.ts +5 -0
  34. package/dist/commands/metrics.js +80 -0
  35. package/dist/commands/optimize.js +42 -34
  36. package/dist/commands/review.d.ts +4 -1
  37. package/dist/commands/review.js +87 -43
  38. package/dist/commands/security-check.d.ts +4 -1
  39. package/dist/commands/security-check.js +109 -38
  40. package/dist/commands/status.d.ts +1 -0
  41. package/dist/commands/status.js +83 -0
  42. package/dist/commands/suggest.js +13 -39
  43. package/dist/config/config.d.ts +5 -1
  44. package/dist/config/config.js +53 -8
  45. package/dist/core/ai.d.ts +88 -2
  46. package/dist/core/ai.js +231 -30
  47. package/dist/core/command-catalog.d.ts +10 -0
  48. package/dist/core/command-catalog.js +27 -0
  49. package/dist/core/command-runner.d.ts +17 -0
  50. package/dist/core/command-runner.js +157 -0
  51. package/dist/core/logger.d.ts +40 -0
  52. package/dist/core/logger.js +139 -0
  53. package/dist/core/metrics.d.ts +62 -0
  54. package/dist/core/metrics.js +284 -0
  55. package/dist/core/prompts.d.ts +1 -0
  56. package/dist/core/prompts.js +121 -0
  57. package/dist/core/security.d.ts +34 -0
  58. package/dist/core/security.js +197 -0
  59. package/dist/index.js +84 -22
  60. package/dist/utils/projectType.d.ts +1 -1
  61. package/dist/utils/projectType.js +26 -7
  62. package/dist/utils/ux.d.ts +3 -0
  63. package/dist/utils/ux.js +15 -0
  64. package/docs/agents/domain.md +51 -0
  65. package/docs/agents/issue-tracker.md +45 -0
  66. package/docs/agents/triage-labels.md +15 -0
  67. package/docs/api/.nojekyll +1 -0
  68. package/docs/api/assets/hierarchy.js +1 -0
  69. package/docs/api/assets/highlight.css +71 -0
  70. package/docs/api/assets/icons.js +18 -0
  71. package/docs/api/assets/icons.svg +1 -0
  72. package/docs/api/assets/main.js +60 -0
  73. package/docs/api/assets/navigation.js +1 -0
  74. package/docs/api/assets/search.js +1 -0
  75. package/docs/api/assets/style.css +1633 -0
  76. package/docs/api/hierarchy.html +1 -0
  77. package/docs/api/index.html +161 -0
  78. package/docs/api/media/CONTRIBUTING.md +60 -0
  79. package/docs/api/media/SECURITY.md +8 -0
  80. package/docs/api/media/dhruv-cli-preview.svg +42 -0
  81. package/docs/api/media/publishing-fix.md +34 -0
  82. package/docs/api/modules.html +1 -0
  83. package/docs/dhruv-cli-preview.svg +42 -0
  84. package/docs/index.html +631 -533
  85. package/docs/publishing-fix.md +34 -0
  86. package/eslint.config.js +170 -0
  87. package/jest.config.json +37 -0
  88. package/lighthouserc.json +22 -0
  89. package/package.json +62 -8
  90. package/src/commands/explain.ts +13 -42
  91. package/src/commands/fix.ts +13 -31
  92. package/src/commands/generate.ts +68 -48
  93. package/src/commands/health.ts +485 -0
  94. package/src/commands/init.ts +57 -42
  95. package/src/commands/menu.ts +132 -24
  96. package/src/commands/metrics.ts +100 -0
  97. package/src/commands/optimize.ts +40 -28
  98. package/src/commands/review.ts +96 -37
  99. package/src/commands/security-check.ts +127 -33
  100. package/src/commands/status.ts +83 -0
  101. package/src/commands/suggest.ts +13 -32
  102. package/src/config/config.ts +60 -8
  103. package/src/core/ai.ts +265 -26
  104. package/src/core/command-catalog.ts +37 -0
  105. package/src/core/command-runner.ts +185 -0
  106. package/src/core/logger.ts +195 -0
  107. package/src/core/metrics.ts +335 -0
  108. package/src/core/prompts.ts +128 -0
  109. package/src/core/security.ts +243 -0
  110. package/src/index.ts +90 -22
  111. package/src/utils/projectType.ts +22 -7
  112. package/src/utils/ux.ts +18 -0
  113. package/test-suite.sh +147 -0
  114. package/tsconfig.json +4 -3
  115. package/typedoc.json +44 -0
  116. package/types/global.d.ts +13 -0
  117. package/validate-workflows.sh +270 -0
  118. package/.eslintignore +0 -1
  119. package/.eslintrc.cjs +0 -43
  120. package/.github/workflows/auto-assign.yml +0 -14
  121. package/src/core/ai.test.js +0 -40
@@ -1,53 +1,66 @@
1
- name: Dhruv CLI CI/CD
1
+ name: Dhruv CLI CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ main ]
5
+ branches: [main]
6
6
  pull_request:
7
- branches: [ main ]
7
+ branches: [main]
8
8
 
9
9
  permissions:
10
- contents: write
10
+ contents: read
11
11
 
12
12
  jobs:
13
- build:
14
- runs-on: ubuntu-latest
13
+ test:
14
+ name: Test (${{ matrix.os }}, Node ${{ matrix.node-version }})
15
+ runs-on: ${{ matrix.os }}
16
+ timeout-minutes: 20
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ include:
21
+ - os: ubuntu-latest
22
+ node-version: 18.x
23
+ - os: ubuntu-latest
24
+ node-version: 20.x
25
+ - os: ubuntu-latest
26
+ node-version: 22.x
27
+ coverage: true
28
+ - os: macos-latest
29
+ node-version: 22.x
30
+ - os: windows-latest
31
+ node-version: 22.x
15
32
  steps:
16
33
  - uses: actions/checkout@v4
17
- - name: Set up Node.js
34
+
35
+ - name: Set up Node.js ${{ matrix.node-version }}
18
36
  uses: actions/setup-node@v4
19
37
  with:
20
- node-version: '20.8.1'
38
+ node-version: ${{ matrix.node-version }}
39
+ cache: npm
40
+
21
41
  - name: Install dependencies
22
- run: npm ci
23
- - name: Lint
24
- run: npx eslint .
25
- - name: Build
42
+ run: npm ci --prefer-offline --no-audit
43
+
44
+ - name: Run linter
45
+ run: npm run lint
46
+
47
+ - name: Type checking
48
+ run: npm run type-check
49
+
50
+ - name: Build project
26
51
  run: npm run build
27
- - name: Test
28
- run: npm test || echo "No tests yet"
29
- - name: Upload docs to GitHub Pages
30
- if: github.ref == 'refs/heads/main'
31
- uses: peaceiris/actions-gh-pages@v4
32
- with:
33
- github_token: ${{ secrets.GITHUB_TOKEN }}
34
- publish_dir: ./docs
35
- publish_branch: gh-pages
36
- - name: Publish to npm
37
- if: github.ref == 'refs/heads/main' && github.event_name == 'push'
38
- run: |
39
- npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
40
- npm publish --access public
41
- - name: Create GitHub Release
42
- if: startsWith(github.ref, 'refs/tags/v')
43
- uses: softprops/action-gh-release@v2
44
- with:
45
- files: |
46
- dist/**
47
- docs/**
48
- - name: Release (semantic-release)
49
- if: github.ref == 'refs/heads/main' && github.event_name == 'push'
52
+
53
+ - name: Run unit tests
54
+ run: npm run test:ci
50
55
  env:
51
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
53
- run: npx semantic-release
56
+ CI: true
57
+
58
+ - name: Upload coverage
59
+ if: matrix.coverage == true
60
+ uses: codecov/codecov-action@v4
61
+ with:
62
+ file: ./coverage/lcov.info
63
+ flags: unittests
64
+ name: codecov-${{ matrix.node-version }}
65
+ fail_ci_if_error: false
66
+ token: ${{ secrets.CODECOV_TOKEN }}
@@ -1,51 +1,58 @@
1
- name: Community Contribution Checks
1
+ name: Pull Request Policy
2
2
 
3
3
  on:
4
4
  pull_request:
5
- types: [opened, synchronize, reopened]
5
+ branches: [main]
6
+ types: [opened, synchronize, reopened, ready_for_review]
6
7
 
7
- jobs:
8
- lint:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v4
12
- - name: Set up Node.js
13
- uses: actions/setup-node@v4
14
- with:
15
- node-version: '18.x'
16
- - name: Install dependencies
17
- run: npm ci
18
- - name: Lint
19
- run: npx eslint .
8
+ permissions:
9
+ contents: read
10
+ pull-requests: write
20
11
 
21
- test:
22
- runs-on: ubuntu-latest
23
- steps:
24
- - uses: actions/checkout@v4
25
- - name: Set up Node.js
26
- uses: actions/setup-node@v4
27
- with:
28
- node-version: '18.x'
29
- - name: Install dependencies
30
- run: npm ci
31
- - name: Run tests
32
- run: npm test || echo "No tests yet"
33
-
34
- pr-title:
35
- if: github.event.pull_request.head.repo.full_name == github.repository
12
+ jobs:
13
+ validate-pr:
14
+ name: PR Metadata
36
15
  runs-on: ubuntu-latest
16
+ timeout-minutes: 10
17
+ if: github.event.pull_request.draft == false
37
18
  steps:
38
- - uses: amannn/action-semantic-pull-request@v5
19
+ - name: Validate PR title
20
+ uses: amannn/action-semantic-pull-request@v5
39
21
  with:
40
22
  types: |
41
23
  feat
42
24
  fix
43
- chore
44
25
  docs
45
- refactor
46
26
  style
27
+ refactor
28
+ perf
47
29
  test
30
+ build
48
31
  ci
49
- githubBaseUrl: https://api.github.com
32
+ chore
33
+ revert
34
+ requireScope: false
35
+ disallowScopes: |
36
+ release
37
+ subjectPattern: ^(?![A-Z]).+
38
+ subjectPatternError: |
39
+ The subject "{subject}" found in the pull request title "{title}"
40
+ didn't match the configured pattern. Please ensure that the subject
41
+ doesn't start with an uppercase character.
50
42
  env:
51
43
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44
+
45
+ - name: Apply PR size label
46
+ uses: pascalgn/size-label-action@v0.5.0
47
+ env:
48
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49
+ with:
50
+ sizes: >
51
+ {
52
+ "0": "XS",
53
+ "20": "S",
54
+ "50": "M",
55
+ "200": "L",
56
+ "800": "XL",
57
+ "2000": "XXL"
58
+ }
@@ -2,18 +2,78 @@ name: Dependabot Auto Merge
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ branches: [main]
5
6
  types:
6
7
  - opened
7
8
  - synchronize
8
9
  - reopened
10
+ - ready_for_review
11
+
12
+ permissions:
13
+ contents: write
14
+ pull-requests: write
15
+ checks: read
9
16
 
10
17
  jobs:
18
+ auto-approve:
19
+ name: Auto Approve Dependabot PRs
20
+ if: github.actor == 'dependabot[bot]' && github.event.pull_request.draft == false
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 5
23
+ steps:
24
+ - name: Harden Runner
25
+ uses: step-security/harden-runner@v2
26
+ with:
27
+ egress-policy: audit
28
+
29
+ - name: Approve Dependabot PRs
30
+ uses: hmarr/auto-approve-action@v4
31
+ with:
32
+ github-token: ${{ secrets.GITHUB_TOKEN }}
33
+
11
34
  auto-merge:
12
- if: github.actor == 'dependabot[bot]'
35
+ name: Auto Merge Dependabot PRs
36
+ needs: auto-approve
37
+ if: github.actor == 'dependabot[bot]' && github.event.pull_request.draft == false
13
38
  runs-on: ubuntu-latest
39
+ timeout-minutes: 10
14
40
  steps:
15
- - name: Enable auto-merge for Dependabot PRs
41
+ - name: Harden Runner
42
+ uses: step-security/harden-runner@v2
43
+ with:
44
+ egress-policy: audit
45
+
46
+ - name: Get Dependabot metadata
47
+ id: metadata
48
+ uses: dependabot/fetch-metadata@v1
49
+ with:
50
+ github-token: ${{ secrets.GITHUB_TOKEN }}
51
+
52
+ - name: Enable auto-merge for patch updates
53
+ if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
16
54
  uses: peter-evans/enable-pull-request-automerge@v3
17
55
  with:
18
56
  token: ${{ secrets.GITHUB_TOKEN }}
19
57
  merge-method: squash
58
+
59
+ - name: Enable auto-merge for minor updates
60
+ if: steps.metadata.outputs.update-type == 'version-update:semver-minor' && contains(steps.metadata.outputs.dependency-names, '@types/')
61
+ uses: peter-evans/enable-pull-request-automerge@v3
62
+ with:
63
+ token: ${{ secrets.GITHUB_TOKEN }}
64
+ merge-method: squash
65
+
66
+ - name: Comment on major updates
67
+ if: steps.metadata.outputs.update-type == 'version-update:semver-major'
68
+ uses: peter-evans/create-or-update-comment@v4
69
+ with:
70
+ issue-number: ${{ github.event.pull_request.number }}
71
+ body: |
72
+ 🚨 **Major Version Update Detected**
73
+
74
+ This PR updates a dependency to a new major version. Please review the changelog and test thoroughly before merging.
75
+
76
+ **Dependency:** ${{ steps.metadata.outputs.dependency-names }}
77
+ **Update Type:** ${{ steps.metadata.outputs.update-type }}
78
+
79
+ This PR will not be auto-merged and requires manual review.
@@ -2,6 +2,7 @@ name: Pull Request Labeler
2
2
 
3
3
  on:
4
4
  pull_request:
5
+ branches: [main]
5
6
  types: [opened, synchronize, reopened]
6
7
 
7
8
  jobs:
@@ -0,0 +1,229 @@
1
+ name: Release Management
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+ workflow_dispatch:
8
+ inputs:
9
+ release_type:
10
+ description: 'Release type (patch, minor, major, prerelease)'
11
+ required: true
12
+ default: 'patch'
13
+ type: choice
14
+ options:
15
+ - patch
16
+ - minor
17
+ - major
18
+ - prerelease
19
+
20
+ permissions:
21
+ contents: write
22
+ packages: write
23
+ pull-requests: write
24
+ issues: write
25
+ id-token: write
26
+
27
+ jobs:
28
+ pre-release-validation:
29
+ name: Pre-Release Validation
30
+ runs-on: ubuntu-latest
31
+ timeout-minutes: 20
32
+ steps:
33
+ - name: Harden Runner
34
+ uses: step-security/harden-runner@v2
35
+ with:
36
+ egress-policy: audit
37
+
38
+ - uses: actions/checkout@v4
39
+ with:
40
+ fetch-depth: 0
41
+ token: ${{ secrets.GITHUB_TOKEN }}
42
+
43
+ - name: Set up Node.js
44
+ uses: actions/setup-node@v4
45
+ with:
46
+ node-version: '22.14.0'
47
+ cache: 'npm'
48
+ registry-url: 'https://registry.npmjs.org'
49
+
50
+ - name: Install dependencies
51
+ run: npm ci --prefer-offline --no-audit
52
+
53
+ - name: Run full test suite
54
+ run: npm run test:ci
55
+
56
+ - name: Build project
57
+ run: npm run build
58
+
59
+ - name: Generate documentation
60
+ run: npm run docs
61
+
62
+ - name: Run security audit
63
+ run: npm audit --omit=dev --audit-level=high
64
+
65
+ - name: Package size check
66
+ run: |
67
+ npm pack --dry-run
68
+ du -sh *.tgz || echo "No package found"
69
+
70
+ - name: Validate package contents
71
+ run: |
72
+ npm pack
73
+ tar -tzf *.tgz | head -20
74
+
75
+ release:
76
+ name: Create Release
77
+ runs-on: ubuntu-latest
78
+ needs: pre-release-validation
79
+ timeout-minutes: 15
80
+ environment: production
81
+ env:
82
+ # Authentication uses OIDC with npm 11.5.1+; provenance is an attestation.
83
+ NPM_CONFIG_PROVENANCE: 'true'
84
+ steps:
85
+ - name: Harden Runner
86
+ uses: step-security/harden-runner@v2
87
+ with:
88
+ egress-policy: audit
89
+
90
+ - uses: actions/checkout@v4
91
+ with:
92
+ fetch-depth: 0
93
+ token: ${{ secrets.GITHUB_TOKEN }}
94
+
95
+ - name: Set up Node.js
96
+ uses: actions/setup-node@v4
97
+ with:
98
+ node-version: '22.14.0'
99
+ cache: 'npm'
100
+ registry-url: 'https://registry.npmjs.org'
101
+
102
+ - name: Install dependencies
103
+ run: npm ci --prefer-offline --no-audit
104
+
105
+ - name: Build project
106
+ run: npm run build
107
+
108
+ - name: Generate documentation
109
+ run: npm run docs
110
+
111
+ - name: Install npm with trusted publishing support
112
+ run: npm install --global npm@11.17.0
113
+
114
+ - name: Generate changelog
115
+ run: |
116
+ npx conventional-changelog-cli -p angular -i CHANGELOG.md -s
117
+ git add CHANGELOG.md || echo "No changelog changes"
118
+
119
+ - name: Create Release PR
120
+ if: github.event_name == 'workflow_dispatch'
121
+ uses: peter-evans/create-pull-request@v7
122
+ with:
123
+ token: ${{ secrets.GITHUB_TOKEN }}
124
+ commit-message: 'chore(release): prepare release ${{ github.event.inputs.release_type }}'
125
+ title: 'chore(release): prepare ${{ github.event.inputs.release_type }} release'
126
+ body: |
127
+ ## Release Preparation
128
+
129
+ This PR prepares a ${{ github.event.inputs.release_type }} release.
130
+
131
+ ### Changes included:
132
+ - Updated version in package.json
133
+ - Generated changelog
134
+ - Updated documentation
135
+
136
+ ### Pre-release checklist:
137
+ - [ ] All tests passing
138
+ - [ ] Documentation updated
139
+ - [ ] Security audit clean
140
+ - [ ] Breaking changes documented
141
+
142
+ **Auto-generated by Release Management workflow**
143
+ branch: release/prepare-${{ github.event.inputs.release_type }}
144
+ delete-branch: true
145
+
146
+ - name: Release with semantic-release
147
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
148
+ env:
149
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
150
+ run: npx semantic-release
151
+
152
+ - name: Manual publish for workflow dispatch
153
+ if: github.event_name == 'workflow_dispatch'
154
+ run: |
155
+ # For manual releases, update version first
156
+ npm version ${{ github.event.inputs.release_type }} --no-git-tag-version
157
+ npm publish --access public --provenance
158
+
159
+ - name: Update GitHub Pages
160
+ if: startsWith(github.ref, 'refs/tags/v')
161
+ uses: peaceiris/actions-gh-pages@v4
162
+ with:
163
+ github_token: ${{ secrets.GITHUB_TOKEN }}
164
+ publish_dir: ./docs
165
+ publish_branch: gh-pages
166
+ enable_jekyll: false
167
+
168
+ - name: Create GitHub Release
169
+ if: startsWith(github.ref, 'refs/tags/v')
170
+ uses: softprops/action-gh-release@v2
171
+ with:
172
+ files: |
173
+ dist/**
174
+ docs/**
175
+ *.tgz
176
+ generate_release_notes: true
177
+ draft: false
178
+ prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
179
+
180
+ post-release:
181
+ name: Post Release Tasks
182
+ runs-on: ubuntu-latest
183
+ needs: release
184
+ if: always() && (needs.release.result == 'success')
185
+ timeout-minutes: 10
186
+ steps:
187
+ - name: Harden Runner
188
+ uses: step-security/harden-runner@v2
189
+ with:
190
+ egress-policy: audit
191
+
192
+ - uses: actions/checkout@v4
193
+
194
+ - name: Update repository topics
195
+ # Best-effort: GITHUB_TOKEN cannot replaceAllTopics without admin.
196
+ continue-on-error: true
197
+ uses: actions/github-script@v7
198
+ with:
199
+ script: |
200
+ const packageJson = require('./package.json');
201
+ const topics = [
202
+ 'cli',
203
+ 'ai',
204
+ 'developer-tools',
205
+ 'ollama',
206
+ 'typescript',
207
+ `version-${packageJson.version.replace(/\./g, '-')}`
208
+ ];
209
+
210
+ await github.rest.repos.replaceAllTopics({
211
+ owner: context.repo.owner,
212
+ repo: context.repo.repo,
213
+ names: topics
214
+ });
215
+
216
+ - name: Notify stakeholders
217
+ uses: 8398a7/action-slack@v3
218
+ continue-on-error: true
219
+ with:
220
+ status: 'success'
221
+ channel: '#releases'
222
+ text: |
223
+ 🎉 New release published!
224
+
225
+ **Repository:** ${{ github.repository }}
226
+ **Version:** ${{ github.ref_name }}
227
+ **Release Notes:** ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}
228
+ env:
229
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}