docguard-cli 0.5.1
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/LICENSE +21 -0
- package/PHILOSOPHY.md +150 -0
- package/README.md +309 -0
- package/STANDARD.md +751 -0
- package/cli/commands/agents.mjs +221 -0
- package/cli/commands/audit.mjs +92 -0
- package/cli/commands/badge.mjs +72 -0
- package/cli/commands/ci.mjs +80 -0
- package/cli/commands/diagnose.mjs +273 -0
- package/cli/commands/diff.mjs +360 -0
- package/cli/commands/fix.mjs +610 -0
- package/cli/commands/generate.mjs +842 -0
- package/cli/commands/guard.mjs +158 -0
- package/cli/commands/hooks.mjs +227 -0
- package/cli/commands/init.mjs +249 -0
- package/cli/commands/score.mjs +396 -0
- package/cli/commands/watch.mjs +143 -0
- package/cli/docguard.mjs +458 -0
- package/cli/validators/architecture.mjs +380 -0
- package/cli/validators/changelog.mjs +39 -0
- package/cli/validators/docs-sync.mjs +110 -0
- package/cli/validators/drift.mjs +101 -0
- package/cli/validators/environment.mjs +70 -0
- package/cli/validators/freshness.mjs +224 -0
- package/cli/validators/security.mjs +101 -0
- package/cli/validators/structure.mjs +88 -0
- package/cli/validators/test-spec.mjs +115 -0
- package/docs/ai-integration.md +179 -0
- package/docs/commands.md +239 -0
- package/docs/configuration.md +96 -0
- package/docs/faq.md +155 -0
- package/docs/installation.md +81 -0
- package/docs/profiles.md +103 -0
- package/docs/quickstart.md +79 -0
- package/package.json +57 -0
- package/templates/ADR.md.template +64 -0
- package/templates/AGENTS.md.template +88 -0
- package/templates/ARCHITECTURE.md.template +78 -0
- package/templates/CHANGELOG.md.template +16 -0
- package/templates/CURRENT-STATE.md.template +64 -0
- package/templates/DATA-MODEL.md.template +66 -0
- package/templates/DEPLOYMENT.md.template +66 -0
- package/templates/DRIFT-LOG.md.template +18 -0
- package/templates/ENVIRONMENT.md.template +43 -0
- package/templates/KNOWN-GOTCHAS.md.template +69 -0
- package/templates/ROADMAP.md.template +82 -0
- package/templates/RUNBOOKS.md.template +115 -0
- package/templates/SECURITY.md.template +42 -0
- package/templates/TEST-SPEC.md.template +55 -0
- package/templates/TROUBLESHOOTING.md.template +96 -0
- package/templates/VENDOR-BUGS.md.template +74 -0
- package/templates/ci/github-actions.yml +39 -0
- package/templates/commands/docguard.fix.md +65 -0
- package/templates/commands/docguard.guard.md +40 -0
- package/templates/commands/docguard.init.md +62 -0
- package/templates/commands/docguard.review.md +44 -0
- package/templates/commands/docguard.update.md +44 -0
package/cli/docguard.mjs
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DocGuard CLI — The enforcement tool for Canonical-Driven Development (CDD)
|
|
5
|
+
*
|
|
6
|
+
* Zero dependencies. Pure Node.js.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx docguard audit — Scan project, report what docs exist/missing
|
|
10
|
+
* npx docguard init — Initialize CDD docs from templates
|
|
11
|
+
* npx docguard guard — Validate project against its canonical docs
|
|
12
|
+
* npx docguard --help — Show help
|
|
13
|
+
*
|
|
14
|
+
* @see https://github.com/raccioly/docguard
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
18
|
+
import { resolve, basename } from 'node:path';
|
|
19
|
+
import { runAudit } from './commands/audit.mjs';
|
|
20
|
+
import { runInit } from './commands/init.mjs';
|
|
21
|
+
import { runGuard } from './commands/guard.mjs';
|
|
22
|
+
import { runScore } from './commands/score.mjs';
|
|
23
|
+
import { runDiff } from './commands/diff.mjs';
|
|
24
|
+
import { runAgents } from './commands/agents.mjs';
|
|
25
|
+
import { runGenerate } from './commands/generate.mjs';
|
|
26
|
+
import { runHooks } from './commands/hooks.mjs';
|
|
27
|
+
import { runBadge } from './commands/badge.mjs';
|
|
28
|
+
import { runCI } from './commands/ci.mjs';
|
|
29
|
+
import { runFix } from './commands/fix.mjs';
|
|
30
|
+
import { runWatch } from './commands/watch.mjs';
|
|
31
|
+
import { runDiagnose } from './commands/diagnose.mjs';
|
|
32
|
+
|
|
33
|
+
// ── Colors (ANSI escape codes, zero deps) ──────────────────────────────────
|
|
34
|
+
export const c = {
|
|
35
|
+
reset: '\x1b[0m',
|
|
36
|
+
bold: '\x1b[1m',
|
|
37
|
+
dim: '\x1b[2m',
|
|
38
|
+
red: '\x1b[31m',
|
|
39
|
+
green: '\x1b[32m',
|
|
40
|
+
yellow: '\x1b[33m',
|
|
41
|
+
blue: '\x1b[34m',
|
|
42
|
+
cyan: '\x1b[36m',
|
|
43
|
+
white: '\x1b[37m',
|
|
44
|
+
bgRed: '\x1b[41m',
|
|
45
|
+
bgGreen: '\x1b[42m',
|
|
46
|
+
bgYellow: '\x1b[43m',
|
|
47
|
+
};
|
|
48
|
+
// ── Compliance Profiles ───────────────────────────────────────────────────
|
|
49
|
+
// Profiles layer between defaults and user config — they're preset bundles
|
|
50
|
+
// that adjust what docs are required and which validators run.
|
|
51
|
+
const PROFILES = {
|
|
52
|
+
starter: {
|
|
53
|
+
description: 'Minimal CDD — just architecture + changelog. For side projects and prototypes.',
|
|
54
|
+
requiredFiles: {
|
|
55
|
+
canonical: [
|
|
56
|
+
'docs-canonical/ARCHITECTURE.md',
|
|
57
|
+
],
|
|
58
|
+
agentFile: ['AGENTS.md', 'CLAUDE.md'],
|
|
59
|
+
changelog: 'CHANGELOG.md',
|
|
60
|
+
driftLog: 'DRIFT-LOG.md',
|
|
61
|
+
},
|
|
62
|
+
validators: {
|
|
63
|
+
structure: true,
|
|
64
|
+
docsSync: true,
|
|
65
|
+
drift: false,
|
|
66
|
+
changelog: true,
|
|
67
|
+
architecture: false,
|
|
68
|
+
testSpec: false,
|
|
69
|
+
security: false,
|
|
70
|
+
environment: false,
|
|
71
|
+
freshness: false,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
standard: {
|
|
75
|
+
description: 'Full CDD — all 5 canonical docs. For team projects.',
|
|
76
|
+
// Uses the defaults — no overrides needed
|
|
77
|
+
},
|
|
78
|
+
enterprise: {
|
|
79
|
+
description: 'Strict CDD — all docs, all validators, freshness enforced. For regulated/enterprise projects.',
|
|
80
|
+
validators: {
|
|
81
|
+
structure: true,
|
|
82
|
+
docsSync: true,
|
|
83
|
+
drift: true,
|
|
84
|
+
changelog: true,
|
|
85
|
+
architecture: true,
|
|
86
|
+
testSpec: true,
|
|
87
|
+
security: true,
|
|
88
|
+
environment: true,
|
|
89
|
+
freshness: true,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// ── Config Loading ─────────────────────────────────────────────────────────
|
|
95
|
+
export function loadConfig(projectDir) {
|
|
96
|
+
const configPath = resolve(projectDir, '.docguard.json');
|
|
97
|
+
const defaults = {
|
|
98
|
+
projectName: basename(projectDir),
|
|
99
|
+
version: '0.2',
|
|
100
|
+
profile: 'standard',
|
|
101
|
+
requiredFiles: {
|
|
102
|
+
canonical: [
|
|
103
|
+
'docs-canonical/ARCHITECTURE.md',
|
|
104
|
+
'docs-canonical/DATA-MODEL.md',
|
|
105
|
+
'docs-canonical/SECURITY.md',
|
|
106
|
+
'docs-canonical/TEST-SPEC.md',
|
|
107
|
+
'docs-canonical/ENVIRONMENT.md',
|
|
108
|
+
],
|
|
109
|
+
agentFile: ['AGENTS.md', 'CLAUDE.md'],
|
|
110
|
+
changelog: 'CHANGELOG.md',
|
|
111
|
+
driftLog: 'DRIFT-LOG.md',
|
|
112
|
+
},
|
|
113
|
+
// All CDD document types — required vs optional
|
|
114
|
+
documentTypes: {
|
|
115
|
+
// Canonical (design intent) — required by default
|
|
116
|
+
'docs-canonical/ARCHITECTURE.md': { required: true, category: 'canonical', description: 'System design, components, layer boundaries' },
|
|
117
|
+
'docs-canonical/DATA-MODEL.md': { required: true, category: 'canonical', description: 'Database schemas, entities, relationships' },
|
|
118
|
+
'docs-canonical/SECURITY.md': { required: true, category: 'canonical', description: 'Authentication, authorization, secrets management' },
|
|
119
|
+
'docs-canonical/TEST-SPEC.md': { required: true, category: 'canonical', description: 'Test categories, coverage rules, service-to-test map' },
|
|
120
|
+
'docs-canonical/ENVIRONMENT.md': { required: true, category: 'canonical', description: 'Environment variables, setup steps, prerequisites' },
|
|
121
|
+
'docs-canonical/DEPLOYMENT.md': { required: false, category: 'canonical', description: 'Infrastructure, CI/CD pipeline, DNS, monitoring' },
|
|
122
|
+
'docs-canonical/ADR.md': { required: false, category: 'canonical', description: 'Architecture Decision Records with rationale' },
|
|
123
|
+
// Implementation (current state) — optional by default
|
|
124
|
+
'docs-implementation/KNOWN-GOTCHAS.md': { required: false, category: 'implementation', description: 'Lessons learned — symptom/gotcha/fix format' },
|
|
125
|
+
'docs-implementation/TROUBLESHOOTING.md': { required: false, category: 'implementation', description: 'Error diagnosis guides by category' },
|
|
126
|
+
'docs-implementation/RUNBOOKS.md': { required: false, category: 'implementation', description: 'Operational procedures (deploy, rollback, backup)' },
|
|
127
|
+
'docs-implementation/CURRENT-STATE.md': { required: false, category: 'implementation', description: 'Deployment status, feature completion, tech debt' },
|
|
128
|
+
'docs-implementation/VENDOR-BUGS.md': { required: false, category: 'implementation', description: 'Third-party bug tracker with workarounds' },
|
|
129
|
+
// Root files
|
|
130
|
+
'AGENTS.md': { required: true, category: 'agent', description: 'AI agent behavior rules and project context' },
|
|
131
|
+
'CHANGELOG.md': { required: true, category: 'tracking', description: 'All notable changes per Keep a Changelog format' },
|
|
132
|
+
'DRIFT-LOG.md': { required: true, category: 'tracking', description: 'Documented deviations from canonical docs' },
|
|
133
|
+
'ROADMAP.md': { required: false, category: 'tracking', description: 'Project phases, feature tracking, vision' },
|
|
134
|
+
},
|
|
135
|
+
sourcePatterns: {
|
|
136
|
+
services: 'src/services/**/*.{ts,js,py,java}',
|
|
137
|
+
routes: 'src/routes/**/*.{ts,js,py,java}',
|
|
138
|
+
tests: 'tests/**/*.test.{ts,js,py,java}',
|
|
139
|
+
},
|
|
140
|
+
validators: {
|
|
141
|
+
structure: true,
|
|
142
|
+
docsSync: true,
|
|
143
|
+
drift: true,
|
|
144
|
+
changelog: true,
|
|
145
|
+
architecture: false,
|
|
146
|
+
testSpec: true,
|
|
147
|
+
security: false,
|
|
148
|
+
environment: true,
|
|
149
|
+
freshness: true,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
if (existsSync(configPath)) {
|
|
154
|
+
try {
|
|
155
|
+
const userConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
156
|
+
|
|
157
|
+
// Apply profile presets BEFORE merging user config
|
|
158
|
+
// Profile sets the baseline, user config can override anything
|
|
159
|
+
const profileName = userConfig.profile || defaults.profile;
|
|
160
|
+
const profilePreset = PROFILES[profileName];
|
|
161
|
+
const withProfile = profilePreset
|
|
162
|
+
? deepMerge(defaults, profilePreset)
|
|
163
|
+
: defaults;
|
|
164
|
+
|
|
165
|
+
const merged = deepMerge(withProfile, userConfig);
|
|
166
|
+
merged.profile = profileName;
|
|
167
|
+
|
|
168
|
+
// Auto-detect project type if not set
|
|
169
|
+
if (!merged.projectType) {
|
|
170
|
+
merged.projectType = autoDetectProjectType(projectDir);
|
|
171
|
+
}
|
|
172
|
+
// Ensure projectTypeConfig has sensible defaults based on type
|
|
173
|
+
merged.projectTypeConfig = {
|
|
174
|
+
...getProjectTypeDefaults(merged.projectType),
|
|
175
|
+
...(merged.projectTypeConfig || {}),
|
|
176
|
+
};
|
|
177
|
+
return merged;
|
|
178
|
+
} catch (e) {
|
|
179
|
+
console.error(`${c.red}Error parsing .docguard.json: ${e.message}${c.reset}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// No config file — auto-detect everything
|
|
185
|
+
defaults.projectType = autoDetectProjectType(projectDir);
|
|
186
|
+
defaults.projectTypeConfig = getProjectTypeDefaults(defaults.projectType);
|
|
187
|
+
return defaults;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Export profiles for use by other commands (init --profile)
|
|
191
|
+
export { PROFILES };
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Auto-detect project type from package.json and file structure.
|
|
195
|
+
* Returns: 'cli' | 'library' | 'webapp' | 'api' | 'unknown'
|
|
196
|
+
*/
|
|
197
|
+
function autoDetectProjectType(dir) {
|
|
198
|
+
const pkgPath = resolve(dir, 'package.json');
|
|
199
|
+
if (existsSync(pkgPath)) {
|
|
200
|
+
try {
|
|
201
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
202
|
+
const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
203
|
+
|
|
204
|
+
// CLI tool: has "bin" field
|
|
205
|
+
if (pkg.bin) return 'cli';
|
|
206
|
+
|
|
207
|
+
// Web app: has a frontend framework
|
|
208
|
+
if (allDeps.next || allDeps.react || allDeps.vue || allDeps['@angular/core'] ||
|
|
209
|
+
allDeps.svelte || allDeps.nuxt || allDeps['@sveltejs/kit']) return 'webapp';
|
|
210
|
+
|
|
211
|
+
// API: has a server framework but no frontend
|
|
212
|
+
if (allDeps.express || allDeps.fastify || allDeps.hono || allDeps.koa) return 'api';
|
|
213
|
+
|
|
214
|
+
// Library: has "main" or "exports" and no framework
|
|
215
|
+
if (pkg.main || pkg.exports || pkg.module) return 'library';
|
|
216
|
+
} catch { /* fall through */ }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Python project
|
|
220
|
+
if (existsSync(resolve(dir, 'manage.py'))) return 'webapp';
|
|
221
|
+
if (existsSync(resolve(dir, 'setup.py')) || existsSync(resolve(dir, 'pyproject.toml'))) return 'library';
|
|
222
|
+
|
|
223
|
+
return 'unknown';
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Get default projectTypeConfig for a given project type.
|
|
228
|
+
*/
|
|
229
|
+
function getProjectTypeDefaults(type) {
|
|
230
|
+
const defaults = {
|
|
231
|
+
cli: { needsEnvVars: false, needsEnvExample: false, needsE2E: false, needsDatabase: false, testFramework: 'node:test', runCommand: null },
|
|
232
|
+
library: { needsEnvVars: false, needsEnvExample: false, needsE2E: false, needsDatabase: false, testFramework: 'vitest', runCommand: null },
|
|
233
|
+
webapp: { needsEnvVars: true, needsEnvExample: true, needsE2E: true, needsDatabase: true, testFramework: 'vitest', runCommand: 'npm run dev' },
|
|
234
|
+
api: { needsEnvVars: true, needsEnvExample: true, needsE2E: false, needsDatabase: true, testFramework: 'vitest', runCommand: 'npm run dev' },
|
|
235
|
+
unknown: { needsEnvVars: true, needsEnvExample: true, needsE2E: false, needsDatabase: true, testFramework: null, runCommand: null },
|
|
236
|
+
};
|
|
237
|
+
return defaults[type] || defaults.unknown;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function deepMerge(target, source) {
|
|
241
|
+
const result = { ...target };
|
|
242
|
+
for (const key of Object.keys(source)) {
|
|
243
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
244
|
+
result[key] = deepMerge(target[key] || {}, source[key]);
|
|
245
|
+
} else {
|
|
246
|
+
result[key] = source[key];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ── Banner ─────────────────────────────────────────────────────────────────
|
|
253
|
+
function printBanner() {
|
|
254
|
+
console.log(`
|
|
255
|
+
${c.cyan}${c.bold} ╔═══════════════════════════════════════════╗
|
|
256
|
+
║ DocGuard v0.5.0 ║
|
|
257
|
+
║ Canonical-Driven Development (CDD) ║
|
|
258
|
+
╚═══════════════════════════════════════════╝${c.reset}
|
|
259
|
+
`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ── Help ───────────────────────────────────────────────────────────────────
|
|
263
|
+
function printHelp() {
|
|
264
|
+
printBanner();
|
|
265
|
+
console.log(`${c.bold}Usage:${c.reset}
|
|
266
|
+
docguard <command> [options]
|
|
267
|
+
|
|
268
|
+
${c.bold}Commands:${c.reset}
|
|
269
|
+
${c.green}audit${c.reset} Scan project, report what CDD docs exist or are missing
|
|
270
|
+
${c.green}init${c.reset} Initialize CDD documentation from templates
|
|
271
|
+
${c.green}guard${c.reset} Validate project against its canonical documentation
|
|
272
|
+
${c.green}score${c.reset} Calculate CDD maturity score (0-100)
|
|
273
|
+
${c.green}diagnose${c.reset} AI orchestrator — chains guard→fix in one command
|
|
274
|
+
${c.green}diff${c.reset} Show gaps between canonical docs and code
|
|
275
|
+
${c.green}agents${c.reset} Generate agent-specific config files from AGENTS.md
|
|
276
|
+
${c.green}generate${c.reset} Reverse-engineer canonical docs from existing code
|
|
277
|
+
${c.green}hooks${c.reset} Install git hooks (pre-commit, pre-push, commit-msg)
|
|
278
|
+
${c.green}badge${c.reset} Generate CDD score badges for README
|
|
279
|
+
${c.green}ci${c.reset} Single command for CI/CD pipelines (guard + score)
|
|
280
|
+
${c.green}fix${c.reset} Find issues and generate AI fix instructions
|
|
281
|
+
${c.green}watch${c.reset} Watch for file changes and re-run guard automatically
|
|
282
|
+
|
|
283
|
+
${c.bold}Options:${c.reset}
|
|
284
|
+
--dir <path> Project directory (default: current directory)
|
|
285
|
+
--verbose Show detailed output
|
|
286
|
+
--format json Output results as JSON (for CI)
|
|
287
|
+
--fix Auto-create missing files from templates
|
|
288
|
+
--force Overwrite existing files (for agents/init)
|
|
289
|
+
--agent <name> Target specific agent (for agents command)
|
|
290
|
+
--type <name> Hook type: pre-commit, pre-push, commit-msg
|
|
291
|
+
--list List available hooks and their status
|
|
292
|
+
--remove Remove installed DocGuard hooks
|
|
293
|
+
--threshold <n> Minimum score for CI pass (used with ci command)
|
|
294
|
+
--fail-on-warning Fail CI on warnings (used with ci command)
|
|
295
|
+
--auto Auto-fix what's possible (used with fix command)
|
|
296
|
+
--doc <name> Generate AI prompt for specific doc (architecture, security, etc.)
|
|
297
|
+
--profile <p> Compliance profile: starter, standard, enterprise (init command)
|
|
298
|
+
--tax Show estimated documentation maintenance cost (with score)
|
|
299
|
+
--help Show this help message
|
|
300
|
+
--version Show version
|
|
301
|
+
|
|
302
|
+
${c.bold}Profiles:${c.reset}
|
|
303
|
+
${c.green}starter${c.reset} Minimal CDD — just ARCHITECTURE.md + CHANGELOG (side projects)
|
|
304
|
+
${c.green}standard${c.reset} Full CDD — all 5 canonical docs (default, team projects)
|
|
305
|
+
${c.green}enterprise${c.reset} Strict CDD — all docs + all validators + freshness enforced
|
|
306
|
+
|
|
307
|
+
${c.bold}Examples:${c.reset}
|
|
308
|
+
${c.dim}# AI auto-diagnose and fix${c.reset}
|
|
309
|
+
docguard diagnose
|
|
310
|
+
|
|
311
|
+
${c.dim}# Quick start for a side project${c.reset}
|
|
312
|
+
docguard init --profile starter
|
|
313
|
+
|
|
314
|
+
${c.dim}# Full CDD init (default)${c.reset}
|
|
315
|
+
docguard init
|
|
316
|
+
|
|
317
|
+
${c.dim}# See documentation tax estimate${c.reset}
|
|
318
|
+
docguard score --tax
|
|
319
|
+
|
|
320
|
+
${c.bold}Configuration:${c.reset}
|
|
321
|
+
Create ${c.cyan}.docguard.json${c.reset} in your project root to customize validators.
|
|
322
|
+
See: https://github.com/raccioly/docguard
|
|
323
|
+
|
|
324
|
+
${c.bold}Learn more:${c.reset}
|
|
325
|
+
Canonical-Driven Development: ${c.cyan}PHILOSOPHY.md${c.reset}
|
|
326
|
+
Full standard: ${c.cyan}STANDARD.md${c.reset}
|
|
327
|
+
`);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// ── Main ───────────────────────────────────────────────────────────────────
|
|
331
|
+
function main() {
|
|
332
|
+
const args = process.argv.slice(2);
|
|
333
|
+
const command = args[0];
|
|
334
|
+
|
|
335
|
+
// Parse flags
|
|
336
|
+
const flags = {
|
|
337
|
+
dir: '.',
|
|
338
|
+
verbose: false,
|
|
339
|
+
format: 'text',
|
|
340
|
+
fix: false,
|
|
341
|
+
force: false,
|
|
342
|
+
agent: null,
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
for (let i = 1; i < args.length; i++) {
|
|
346
|
+
if (args[i] === '--dir' && args[i + 1]) {
|
|
347
|
+
flags.dir = args[i + 1];
|
|
348
|
+
i++;
|
|
349
|
+
} else if (args[i] === '--verbose') {
|
|
350
|
+
flags.verbose = true;
|
|
351
|
+
} else if (args[i] === '--format' && args[i + 1]) {
|
|
352
|
+
flags.format = args[i + 1];
|
|
353
|
+
i++;
|
|
354
|
+
} else if (args[i] === '--fix') {
|
|
355
|
+
flags.fix = true;
|
|
356
|
+
} else if (args[i] === '--force') {
|
|
357
|
+
flags.force = true;
|
|
358
|
+
} else if (args[i] === '--agent' && args[i + 1]) {
|
|
359
|
+
flags.agent = args[i + 1];
|
|
360
|
+
i++;
|
|
361
|
+
} else if (args[i] === '--type' && args[i + 1]) {
|
|
362
|
+
flags.type = args[i + 1];
|
|
363
|
+
i++;
|
|
364
|
+
} else if (args[i] === '--list') {
|
|
365
|
+
flags.list = true;
|
|
366
|
+
} else if (args[i] === '--remove') {
|
|
367
|
+
flags.remove = true;
|
|
368
|
+
} else if (args[i] === '--threshold' && args[i + 1]) {
|
|
369
|
+
flags.threshold = args[i + 1];
|
|
370
|
+
i++;
|
|
371
|
+
} else if (args[i] === '--fail-on-warning') {
|
|
372
|
+
flags.failOnWarning = true;
|
|
373
|
+
} else if (args[i] === '--auto') {
|
|
374
|
+
flags.auto = true;
|
|
375
|
+
} else if (args[i] === '--doc' && args[i + 1]) {
|
|
376
|
+
flags.doc = args[i + 1];
|
|
377
|
+
i++;
|
|
378
|
+
} else if (args[i] === '--profile' && args[i + 1]) {
|
|
379
|
+
flags.profile = args[i + 1];
|
|
380
|
+
i++;
|
|
381
|
+
} else if (args[i] === '--tax') {
|
|
382
|
+
flags.tax = true;
|
|
383
|
+
} else if (args[i] === '--auto-fix') {
|
|
384
|
+
flags.autoFix = true;
|
|
385
|
+
} else if (args[i] === '--skip-prompts') {
|
|
386
|
+
flags.skipPrompts = true;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const projectDir = resolve(flags.dir);
|
|
391
|
+
|
|
392
|
+
if (!command || command === '--help' || command === '-h') {
|
|
393
|
+
printHelp();
|
|
394
|
+
process.exit(0);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (command === '--version' || command === '-v') {
|
|
398
|
+
console.log('docguard v0.5.0');
|
|
399
|
+
process.exit(0);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
printBanner();
|
|
403
|
+
|
|
404
|
+
const config = loadConfig(projectDir);
|
|
405
|
+
|
|
406
|
+
switch (command) {
|
|
407
|
+
case 'audit':
|
|
408
|
+
runAudit(projectDir, config, flags);
|
|
409
|
+
break;
|
|
410
|
+
case 'init':
|
|
411
|
+
runInit(projectDir, config, flags);
|
|
412
|
+
break;
|
|
413
|
+
case 'guard':
|
|
414
|
+
runGuard(projectDir, config, flags);
|
|
415
|
+
break;
|
|
416
|
+
case 'score':
|
|
417
|
+
runScore(projectDir, config, flags);
|
|
418
|
+
break;
|
|
419
|
+
case 'diff':
|
|
420
|
+
runDiff(projectDir, config, flags);
|
|
421
|
+
break;
|
|
422
|
+
case 'agents':
|
|
423
|
+
runAgents(projectDir, config, flags);
|
|
424
|
+
break;
|
|
425
|
+
case 'generate':
|
|
426
|
+
case 'gen':
|
|
427
|
+
runGenerate(projectDir, config, flags);
|
|
428
|
+
break;
|
|
429
|
+
case 'hooks':
|
|
430
|
+
runHooks(projectDir, config, flags);
|
|
431
|
+
break;
|
|
432
|
+
case 'badge':
|
|
433
|
+
case 'badges':
|
|
434
|
+
runBadge(projectDir, config, flags);
|
|
435
|
+
break;
|
|
436
|
+
case 'ci':
|
|
437
|
+
case 'pipeline':
|
|
438
|
+
runCI(projectDir, config, flags);
|
|
439
|
+
break;
|
|
440
|
+
case 'fix':
|
|
441
|
+
case 'repair':
|
|
442
|
+
runFix(projectDir, config, flags);
|
|
443
|
+
break;
|
|
444
|
+
case 'diagnose':
|
|
445
|
+
case 'dx':
|
|
446
|
+
runDiagnose(projectDir, config, flags);
|
|
447
|
+
break;
|
|
448
|
+
case 'watch':
|
|
449
|
+
runWatch(projectDir, config, flags);
|
|
450
|
+
break;
|
|
451
|
+
default:
|
|
452
|
+
console.error(`${c.red}Unknown command: ${command}${c.reset}`);
|
|
453
|
+
console.log(`Run ${c.cyan}docguard --help${c.reset} for usage.`);
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
main();
|