@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
@@ -0,0 +1,201 @@
1
+ name: Security Monitoring
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 6 * * 1' # Every Monday at 6 AM UTC
6
+ workflow_dispatch:
7
+ push:
8
+ branches: [ main ]
9
+ pull_request:
10
+ branches: [ main ]
11
+
12
+ permissions:
13
+ contents: read
14
+ actions: read
15
+
16
+ jobs:
17
+ secret-scan:
18
+ name: Secret Scanning
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 10
21
+ steps:
22
+ - name: Harden Runner
23
+ uses: step-security/harden-runner@v2
24
+ with:
25
+ egress-policy: audit
26
+
27
+ - uses: actions/checkout@v4
28
+ with:
29
+ fetch-depth: 0
30
+
31
+ - name: Run TruffleHog
32
+ uses: trufflesecurity/trufflehog@main
33
+ with:
34
+ path: ./
35
+ # Use the action's event-aware range (push, PR, or full history).
36
+ extra_args: --debug --only-verified
37
+
38
+ license-check:
39
+ name: License Compliance
40
+ runs-on: ubuntu-latest
41
+ if: github.event_name != 'pull_request'
42
+ timeout-minutes: 10
43
+ steps:
44
+ - name: Harden Runner
45
+ uses: step-security/harden-runner@v2
46
+ with:
47
+ egress-policy: audit
48
+
49
+ - uses: actions/checkout@v4
50
+
51
+ - name: Set up Node.js
52
+ uses: actions/setup-node@v4
53
+ with:
54
+ node-version: '20.8.1'
55
+ cache: 'npm'
56
+
57
+ - name: Install dependencies
58
+ run: npm ci --prefer-offline --no-audit
59
+
60
+ - name: Check licenses
61
+ run: |
62
+ npx license-checker --summary --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD;Unlicense' || echo "License check completed with warnings"
63
+ continue-on-error: true
64
+
65
+ supply-chain:
66
+ name: Supply Chain Security
67
+ runs-on: ubuntu-latest
68
+ if: github.event_name != 'pull_request'
69
+ timeout-minutes: 15
70
+ steps:
71
+ - name: Harden Runner
72
+ uses: step-security/harden-runner@v2
73
+ with:
74
+ egress-policy: audit
75
+
76
+ - uses: actions/checkout@v4
77
+
78
+ - name: Set up Node.js
79
+ uses: actions/setup-node@v4
80
+ with:
81
+ node-version: '20.8.1'
82
+ cache: 'npm'
83
+
84
+ - name: Install dependencies
85
+ run: npm ci --prefer-offline --no-audit
86
+
87
+ - name: Run OSV Scanner
88
+ uses: google/osv-scanner-action/osv-scanner-action@v2.6.0
89
+ continue-on-error: true
90
+ with:
91
+ scan-args: |-
92
+ --recursive
93
+ ./
94
+
95
+ - name: Run Snyk Security Scan
96
+ uses: snyk/actions/node@master
97
+ env:
98
+ SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
99
+ with:
100
+ args: --severity-threshold=high
101
+ continue-on-error: true
102
+
103
+ sbom-generation:
104
+ name: Generate SBOM
105
+ runs-on: ubuntu-latest
106
+ if: github.event_name != 'pull_request'
107
+ timeout-minutes: 10
108
+ steps:
109
+ - name: Harden Runner
110
+ uses: step-security/harden-runner@v2
111
+ with:
112
+ egress-policy: audit
113
+
114
+ - uses: actions/checkout@v4
115
+
116
+ - name: Set up Node.js
117
+ uses: actions/setup-node@v4
118
+ with:
119
+ node-version: '20.8.1'
120
+ cache: 'npm'
121
+
122
+ - name: Install dependencies
123
+ run: npm ci --prefer-offline --no-audit
124
+
125
+ - name: Generate SBOM
126
+ run: |
127
+ npx --yes @cyclonedx/cyclonedx-npm --output-file sbom.json
128
+ npx --yes @cyclonedx/cyclonedx-npm --output-file sbom.xml --output-format XML
129
+
130
+ - name: Upload SBOM
131
+ uses: actions/upload-artifact@v4
132
+ with:
133
+ name: sbom-files
134
+ path: |
135
+ sbom.json
136
+ sbom.xml
137
+ retention-days: 90
138
+
139
+ security-scorecard:
140
+ name: OSSF Scorecard
141
+ runs-on: ubuntu-latest
142
+ permissions:
143
+ security-events: write
144
+ actions: read
145
+ contents: read
146
+ id-token: write
147
+ # Scorecard only supports analysis from the repository's default branch.
148
+ if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
149
+ steps:
150
+ - name: Harden Runner
151
+ uses: step-security/harden-runner@v2
152
+ with:
153
+ egress-policy: audit
154
+
155
+ - uses: actions/checkout@v4
156
+ with:
157
+ persist-credentials: false
158
+
159
+ - name: Run analysis
160
+ uses: ossf/scorecard-action@v2.4.4
161
+ with:
162
+ results_file: results.sarif
163
+ results_format: sarif
164
+ publish_results: true
165
+
166
+ - name: Upload SARIF results
167
+ if: always() && hashFiles('results.sarif') != ''
168
+ uses: github/codeql-action/upload-sarif@v3
169
+ with:
170
+ sarif_file: results.sarif
171
+
172
+ container-scan:
173
+ name: Container and Dependency Scan
174
+ runs-on: ubuntu-latest
175
+ timeout-minutes: 15
176
+ if: github.event_name != 'pull_request'
177
+ permissions:
178
+ contents: read
179
+ security-events: write
180
+ steps:
181
+ - name: Harden Runner
182
+ uses: step-security/harden-runner@v2
183
+ with:
184
+ egress-policy: audit
185
+
186
+ - uses: actions/checkout@v4
187
+
188
+ # Scorecard publishing only permits approved actions in its own job.
189
+ - name: Container and dependency scan
190
+ uses: anchore/scan-action@v7.4.2
191
+ id: scan
192
+ with:
193
+ path: "."
194
+ fail-build: false
195
+ output-format: sarif
196
+
197
+ - name: Upload Anchore scan SARIF file
198
+ if: always() && steps.scan.outputs.sarif != ''
199
+ uses: github/codeql-action/upload-sarif@v3
200
+ with:
201
+ sarif_file: ${{ steps.scan.outputs.sarif }}
@@ -0,0 +1,50 @@
1
+ {
2
+ "branches": [
3
+ "main",
4
+ {
5
+ "name": "improvement",
6
+ "prerelease": "beta"
7
+ },
8
+ {
9
+ "name": "development",
10
+ "prerelease": "alpha"
11
+ }
12
+ ],
13
+ "plugins": [
14
+ "@semantic-release/commit-analyzer",
15
+ "@semantic-release/release-notes-generator",
16
+ [
17
+ "@semantic-release/changelog",
18
+ {
19
+ "changelogFile": "CHANGELOG.md"
20
+ }
21
+ ],
22
+ "@semantic-release/npm",
23
+ [
24
+ "@semantic-release/github",
25
+ {
26
+ "assets": [
27
+ {
28
+ "path": "dist/**",
29
+ "label": "Distribution files"
30
+ },
31
+ {
32
+ "path": "docs/**",
33
+ "label": "Documentation"
34
+ }
35
+ ]
36
+ }
37
+ ],
38
+ [
39
+ "@semantic-release/git",
40
+ {
41
+ "assets": [
42
+ "CHANGELOG.md",
43
+ "package.json",
44
+ "package-lock.json"
45
+ ],
46
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
47
+ }
48
+ ]
49
+ ]
50
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,13 @@
1
+ ## Agent skills
2
+
3
+ ### Issue tracker
4
+
5
+ Issues live in GitHub Issues (rahul05ranjan/dhruv-cli), via the `gh` CLI. See `docs/agents/issue-tracker.md`.
6
+
7
+ ### Triage labels
8
+
9
+ Default five-role vocabulary: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`. See `docs/agents/triage-labels.md`.
10
+
11
+ ### Domain docs
12
+
13
+ Single-context: one `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # [1.4.0](https://github.com/rahul05ranjan/dhruv-cli/compare/v1.4.6...v1.4.0) (2026-09-18)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * change moduleResolution from Node to Bundler in tsconfig ([b8339bb](https://github.com/rahul05ranjan/dhruv-cli/commit/b8339bb89781490d5678f43052b606138f375d21))
7
+ * drop unused menu loop flag ([51eeec6](https://github.com/rahul05ranjan/dhruv-cli/commit/51eeec6a607299120ce3e1f15af9f9dc62396ce7))
8
+ * stabilize health and CLI contract tests on CI ([3b3e650](https://github.com/rahul05ranjan/dhruv-cli/commit/3b3e6503591c8c33d36f1887e94358dafe6163ce))
9
+
10
+
11
+ ### Features
12
+
13
+ * improve cli experience across commands ([ce41913](https://github.com/rahul05ranjan/dhruv-cli/commit/ce4191350ca3d1c5f49b371508e66de9421f6d20))
1
14
  # Changelog
2
15
 
3
16
  ## [1.1.1](https://github.com/rahul05ranjan/dhruv-cli/compare/v1.1.0...v1.1.1) (2025-06-29)
package/README.md CHANGED
@@ -1,61 +1,166 @@
1
- # Dhruv CLI
2
-
3
- [📦 View on npm](https://www.npmjs.com/package/@rahul05ranjan/dhruv-cli)
4
- [📖 View Documentation on GitHub Pages](https://rahul05ranjan.github.io/dhruv-cli/)
5
-
6
- AI-powered CLI assistant for developers using Ollama.
7
-
8
- ## 🚀 Features
9
- - Smart command suggestions: `suggest`, `explain`, `fix`
10
- - Project context detection (Node, React, Python, etc.)
11
- - Code review: `review <fileOrDir>`
12
- - Code optimization: `optimize <file>`
13
- - Security analysis: `security-check [fileOrDir]`
14
- - Test/code generation: `generate <type> <target>`
15
- - Interactive setup: `init`
16
- - Streaming AI responses in terminal
17
- - Syntax highlighting for code output
18
- - Progress bars for long operations
19
- - Plugin system: drop ESM modules in `plugins/`
20
- - Autocomplete: `completion [shell]`
21
- - Offline-first with local Ollama models
22
- - Beautiful, modern CLI UX
23
-
24
- ## 🛠️ Installation
1
+ <p align="center">
2
+ <a href="https://github.com/rahul05ranjan/dhruv-cli">
3
+ <strong>⚡ Dhruv CLI</strong>
4
+ </a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ A local-first AI command center for your terminal.
9
+ </p>
10
+
11
+ <p align="center">
12
+ Ask better questions. Understand unfamiliar code. Ship with confidence.
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://rahul05ranjan.github.io/dhruv-cli/">Website</a>
17
+ ·
18
+ <a href="https://www.npmjs.com/package/@rahul05ranjan/dhruv-cli">npm</a>
19
+ ·
20
+ <a href="https://github.com/rahul05ranjan/dhruv-cli/issues">Issues</a>
21
+ ·
22
+ <a href="CONTRIBUTING.md">Contributing</a>
23
+ </p>
24
+
25
+ <p align="center">
26
+ <a href="https://github.com/rahul05ranjan/dhruv-cli/actions/workflows/deploy.yml"><img src="https://github.com/rahul05ranjan/dhruv-cli/actions/workflows/deploy.yml/badge.svg" alt="Deployment status"></a>
27
+ <a href="https://www.npmjs.com/package/@rahul05ranjan/dhruv-cli"><img src="https://img.shields.io/npm/v/%40rahul05ranjan%2Fdhruv-cli?style=flat-square&label=npm" alt="npm version"></a>
28
+ <a href="https://www.npmjs.com/package/@rahul05ranjan/dhruv-cli"><img src="https://img.shields.io/npm/dm/%40rahul05ranjan%2Fdhruv-cli?style=flat-square&label=downloads" alt="npm downloads"></a>
29
+ <img src="https://img.shields.io/github/license/rahul05ranjan/dhruv-cli?style=flat-square" alt="MIT license">
30
+ </p>
31
+
32
+ <p align="center">
33
+ <img src="docs/dhruv-cli-preview.svg" alt="Dhruv CLI terminal preview" width="760">
34
+ </p>
35
+
36
+ ## Why Dhruv?
37
+
38
+ Dhruv brings a focused AI toolkit into the terminal, powered by local Ollama models. It keeps your workflow close to the codebase, works without a hosted AI account, and turns everyday developer questions into fast, actionable output.
39
+
40
+ <table>
41
+ <tr>
42
+ <td width="33%"><strong>✦ Think with you</strong><br>Explain concepts, suggest approaches, and turn errors into clear next steps.</td>
43
+ <td width="33%"><strong>◈ Inspect deeply</strong><br>Review code, optimize files, and scan projects for common security risks.</td>
44
+ <td width="33%"><strong>⌁ Fit your flow</strong><br>Use an interactive menu, shell completion, JSON output, or your own plugins.</td>
45
+ </tr>
46
+ </table>
47
+
48
+ ## Start in 60 seconds
49
+
50
+ ### 1. Install Dhruv
51
+
25
52
  ```bash
26
53
  npm install -g @rahul05ranjan/dhruv-cli
27
54
  ```
28
55
 
29
- Or visit the npm page: https://www.npmjs.com/package/@rahul05ranjan/dhruv-cli
56
+ ### 2. Start a local model
57
+
58
+ Install [Ollama](https://ollama.com/), then run:
59
+
60
+ ```bash
61
+ ollama serve
62
+ ollama pull gemma3:270m
63
+ ```
64
+
65
+ ### 3. Configure once, then go
66
+
67
+ ```bash
68
+ dhruv init
69
+ dhruv suggest "how should I structure this Node.js service?"
70
+ ```
71
+
72
+ Dhruv requires Node.js 18 or newer. The default model is `gemma3:270m`; choose any model available in your Ollama installation during setup.
73
+
74
+ ## A command surface built for shipping
75
+
76
+ | Command | What it does |
77
+ | --- | --- |
78
+ | `dhruv suggest <query>` | Generate practical suggestions for a development task |
79
+ | `dhruv explain <query>` | Explain a concept, command, or unfamiliar error |
80
+ | `dhruv fix <query>` | Analyze a coding issue and propose a fix |
81
+ | `dhruv review <file-or-dir>` | Review up to ten code files for quality and maintainability; add `--diff` for uncommitted changes |
82
+ | `dhruv optimize <file>` | Find actionable improvements for source or configuration files |
83
+ | `dhruv security-check [file-or-dir]` | Run a redacted local security analysis; add `--strict` for CI failure on high-confidence findings |
84
+ | `dhruv generate <type> <target>` | Preview generated tests by default; use `--apply`, `--output`, or `--overwrite` to write safely |
85
+ | `dhruv status` | Check Ollama connectivity and configured models |
86
+ | `dhruv health` | Show a concise health summary; use `--details` for diagnostics |
87
+ | `dhruv metrics` | Inspect local usage and performance metrics; use `--raw` or `--reset` explicitly |
88
+ | `dhruv project-type` | Detect the current project type |
89
+ | `dhruv menu` | Open the interactive command palette |
90
+ | `dhruv completion [shell]` | Generate Bash, Zsh, or Fish completion |
91
+
92
+ ### Common workflows
30
93
 
31
- ## 📝 Usage Examples
32
94
  ```bash
33
- dhruv suggest "deploy react app to vercel"
95
+ # Understand and plan
34
96
  dhruv explain "git rebase vs merge"
35
- dhruv fix "cors error in express"
97
+ dhruv suggest "deploy a React app to Vercel"
98
+
99
+ # Improve an existing project
36
100
  dhruv review src/
101
+ dhruv review --diff .
37
102
  dhruv optimize package.json
38
103
  dhruv security-check src/
39
- dhruv generate tests src/utils/helpers.js
40
- dhruv init
41
- dhruv completion bash > dhruv-complete.sh # Enable tab completion
104
+ dhruv security-check src/ --strict
105
+
106
+ # Generate and automate
107
+ dhruv generate tests src/utils/helpers.js # preview only
108
+ dhruv generate tests src/utils/helpers.js --apply
109
+ dhruv completion zsh > ~/.zsh/completions/_dhruv
110
+ ```
111
+
112
+ ## Configuration that stays out of your way
113
+
114
+ Run `dhruv init` to set the Ollama model, response format, verbosity, terminal theme, and whether settings are project-local or user-global. Local configuration is stored in `.dhruv-config.json`; global settings live under your user config directory.
115
+
116
+ For one-off runs, use global flags:
117
+
118
+ ```bash
119
+ dhruv suggest "summarize this migration" --model llama3.2 --json
120
+ dhruv review src/ --verbose
121
+ dhruv explain "what changed?" --timeout 60000
42
122
  ```
43
123
 
44
- ## 🧩 Plugins
45
- Add new commands by dropping ESM modules in the `plugins/` directory. Example:
124
+ ## Extend it with plugins
125
+
126
+ Drop an ESM module into your project's `plugins/` directory. Dhruv loads `.js` plugins before parsing the command line, so you can add commands without changing the core CLI.
127
+
46
128
  ```js
47
129
  // plugins/hello.js
48
130
  export default (program) => {
49
- program.command('hello-plugin').action(() => console.log('Hello from plugin!'));
131
+ program
132
+ .command('hello-plugin')
133
+ .description('Say hello from a project plugin')
134
+ .action(() => console.log('Hello from Dhruv!'));
50
135
  };
51
136
  ```
52
137
 
53
- ## 📦 Configuration
54
- - Run `dhruv init` to set model, response format, and verbosity.
55
- - Project type auto-detected for context-aware suggestions.
138
+ Then run:
139
+
140
+ ```bash
141
+ dhruv hello-plugin
142
+ ```
143
+
144
+ ## Documentation & project guides
56
145
 
57
- ## 🖥️ Advanced UX
58
- - Streaming output, syntax highlighting, progress bars, colored errors, and interactive menus.
146
+ | Resource | Link |
147
+ | --- | --- |
148
+ | Product site | [rahul05ranjan.github.io/dhruv-cli](https://rahul05ranjan.github.io/dhruv-cli/) |
149
+ | API reference | [Generated TypeDoc](https://rahul05ranjan.github.io/dhruv-cli/api/) |
150
+ | Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) |
151
+ | Security policy | [SECURITY.md](SECURITY.md) |
152
+ | Publishing notes | [docs/publishing-fix.md](docs/publishing-fix.md) |
153
+
154
+ ## Development
155
+
156
+ ```bash
157
+ npm install
158
+ npm run type-check
159
+ npm test
160
+ npm run lint
161
+ npm run build
162
+ ```
59
163
 
60
164
  ## License
61
- MIT
165
+
166
+ MIT © [Rahul Ranjan](https://github.com/rahul05ranjan)
@@ -0,0 +1,104 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ import { resolve } from 'node:path';
5
+
6
+ const execFileAsync = promisify(execFile);
7
+ const repoRoot = resolve(__dirname, '..');
8
+ // Package/relative specifiers so Windows does not pass `D:\...` into the ESM loader.
9
+ const sourceEntry = './src/index.ts';
10
+ const loaderEntry = 'ts-node/esm';
11
+
12
+ describe('CLI output contract', () => {
13
+ it('keeps shell completion stdout free of startup telemetry', async () => {
14
+ const result = await execFileAsync(
15
+ process.execPath,
16
+ ['--loader', loaderEntry, sourceEntry, 'completion', 'bash'],
17
+ {
18
+ cwd: repoRoot,
19
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
20
+ },
21
+ );
22
+
23
+ expect(result.stdout).toMatch(/^#!\/bin\/bash/);
24
+ expect(result.stdout).not.toContain('Dhruv CLI starting');
25
+ expect(result.stdout).not.toContain('\u001b[');
26
+ });
27
+
28
+ it('includes diagnostic commands and shared options in completion scripts', async () => {
29
+ const result = await execFileAsync(
30
+ process.execPath,
31
+ ['--loader', loaderEntry, sourceEntry, 'completion', 'bash'],
32
+ {
33
+ cwd: repoRoot,
34
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
35
+ },
36
+ );
37
+
38
+ expect(result.stdout).toContain('status');
39
+ expect(result.stdout).toContain('--json');
40
+ });
41
+
42
+ it('rejects unsupported completion shells', async () => {
43
+ await expect(execFileAsync(
44
+ process.execPath,
45
+ ['--loader', loaderEntry, sourceEntry, 'completion', 'powershell'],
46
+ { cwd: repoRoot, env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' } },
47
+ )).rejects.toMatchObject({ code: 2 });
48
+ });
49
+
50
+ it('documents strict security checks in command help', async () => {
51
+ const result = await execFileAsync(
52
+ process.execPath,
53
+ ['--loader', loaderEntry, sourceEntry, 'security-check', '--help'],
54
+ {
55
+ cwd: repoRoot,
56
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
57
+ },
58
+ );
59
+
60
+ expect(result.stdout).toContain('--strict');
61
+ });
62
+
63
+ it('documents safe generation controls in command help', async () => {
64
+ const result = await execFileAsync(
65
+ process.execPath,
66
+ ['--loader', loaderEntry, sourceEntry, 'generate', '--help'],
67
+ {
68
+ cwd: repoRoot,
69
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
70
+ },
71
+ );
72
+
73
+ expect(result.stdout).toContain('--apply');
74
+ expect(result.stdout).toContain('--output');
75
+ expect(result.stdout).toContain('--overwrite');
76
+ });
77
+
78
+ it('documents explicit metrics export and reset controls', async () => {
79
+ const result = await execFileAsync(
80
+ process.execPath,
81
+ ['--loader', loaderEntry, sourceEntry, 'metrics', '--help'],
82
+ {
83
+ cwd: repoRoot,
84
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
85
+ },
86
+ );
87
+
88
+ expect(result.stdout).toContain('--raw');
89
+ expect(result.stdout).toContain('--reset');
90
+ });
91
+
92
+ it('documents detailed health diagnostics as an explicit option', async () => {
93
+ const result = await execFileAsync(
94
+ process.execPath,
95
+ ['--loader', loaderEntry, sourceEntry, 'health', '--help'],
96
+ {
97
+ cwd: repoRoot,
98
+ env: { ...process.env, DHRUV_METRICS_ENABLED: 'false' },
99
+ },
100
+ );
101
+
102
+ expect(result.stdout).toContain('--details');
103
+ });
104
+ });