@nolrm/contextkit 0.13.5 → 0.14.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.
- package/README.md +78 -47
- package/bin/contextkit.js +22 -2
- package/lib/commands/analyze.js +131 -91
- package/lib/commands/check.js +24 -18
- package/lib/commands/gates.js +119 -0
- package/lib/commands/install.js +447 -142
- package/lib/commands/note.js +12 -20
- package/lib/commands/run.js +20 -22
- package/lib/commands/status.js +61 -32
- package/lib/commands/update.js +119 -80
- package/lib/index.js +3 -1
- package/lib/integrations/aider-integration.js +1 -1
- package/lib/integrations/base-integration.js +13 -6
- package/lib/integrations/claude-integration.js +103 -41
- package/lib/integrations/continue-integration.js +5 -5
- package/lib/integrations/copilot-integration.js +1 -1
- package/lib/integrations/cursor-integration.js +70 -28
- package/lib/integrations/gemini-integration.js +13 -11
- package/lib/integrations/index.js +11 -1
- package/lib/utils/banner.js +14 -11
- package/lib/utils/download.js +3 -4
- package/lib/utils/git-hooks.js +3 -4
- package/lib/utils/migrations.js +6 -4
- package/lib/utils/migrations.md +4 -3
- package/lib/utils/notifier.js +1 -1
- package/lib/utils/project-detector.js +11 -5
- package/lib/utils/status-manager.js +6 -7
- package/lib/utils/tool-detector.js +19 -21
- package/package.json +8 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const yaml = require('js-yaml');
|
|
4
|
+
|
|
5
|
+
const KNOWN_GATES = {
|
|
6
|
+
'Node.js': ['typescript', 'eslint', 'prettier', 'format', 'lint', 'build', 'test', 'e2e'],
|
|
7
|
+
Python: ['ruff-lint', 'typecheck', 'ruff-format', 'pytest'],
|
|
8
|
+
Rust: ['cargo-check', 'clippy', 'cargo-test'],
|
|
9
|
+
Go: ['go-vet', 'golangci-lint', 'go-test'],
|
|
10
|
+
PHP: ['phpstan', 'phpunit'],
|
|
11
|
+
Ruby: ['rubocop', 'rspec'],
|
|
12
|
+
'Java / Kotlin': ['maven-verify', 'gradle-check', 'ktlint', 'kotlin-test'],
|
|
13
|
+
Swift: ['swiftlint', 'swift-test'],
|
|
14
|
+
'.NET': ['dotnet-build', 'dotnet-test'],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const ALL_GATE_KEYS = Object.values(KNOWN_GATES).flat();
|
|
18
|
+
const GATES_CONFIG_PATH = '.contextkit/quality-gates.yml';
|
|
19
|
+
|
|
20
|
+
class GatesCommand {
|
|
21
|
+
async run(options = {}) {
|
|
22
|
+
if (!(await fs.pathExists('.contextkit/config.yml'))) {
|
|
23
|
+
console.log(chalk.red('ContextKit not installed. Run: ck install'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (options.disable) {
|
|
28
|
+
await this.disable(options.disable);
|
|
29
|
+
} else if (options.enable) {
|
|
30
|
+
await this.enable(options.enable);
|
|
31
|
+
} else {
|
|
32
|
+
await this.list();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async list() {
|
|
37
|
+
const disabled = await this.readDisabled();
|
|
38
|
+
console.log(chalk.bold('\nQuality Gates\n'));
|
|
39
|
+
for (const [stack, keys] of Object.entries(KNOWN_GATES)) {
|
|
40
|
+
console.log(chalk.cyan(` ${stack}`));
|
|
41
|
+
for (const key of keys) {
|
|
42
|
+
const isDisabled = disabled.includes(key);
|
|
43
|
+
const status = isDisabled ? chalk.yellow('[disabled]') : chalk.green('[enabled] ');
|
|
44
|
+
console.log(` ${status} ${key}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
console.log('');
|
|
48
|
+
console.log(chalk.yellow(' To disable a gate: ck gates --disable <key>'));
|
|
49
|
+
console.log(chalk.yellow(' To enable a gate: ck gates --enable <key>'));
|
|
50
|
+
console.log('');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async disable(key) {
|
|
54
|
+
if (!ALL_GATE_KEYS.includes(key)) {
|
|
55
|
+
this.printInvalidKey(key);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const disabled = await this.readDisabled();
|
|
59
|
+
if (disabled.includes(key)) {
|
|
60
|
+
console.log(chalk.yellow(`Gate "${key}" is already disabled.`));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
disabled.push(key);
|
|
64
|
+
await this.writeDisabled(disabled);
|
|
65
|
+
console.log(chalk.green(`✅ Gate "${key}" disabled.`));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async enable(key) {
|
|
69
|
+
if (!ALL_GATE_KEYS.includes(key)) {
|
|
70
|
+
this.printInvalidKey(key);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const disabled = await this.readDisabled();
|
|
74
|
+
const idx = disabled.indexOf(key);
|
|
75
|
+
if (idx === -1) {
|
|
76
|
+
console.log(chalk.yellow(`Gate "${key}" is already enabled.`));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
disabled.splice(idx, 1);
|
|
80
|
+
await this.writeDisabled(disabled);
|
|
81
|
+
console.log(chalk.green(`✅ Gate "${key}" enabled.`));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async readDisabled() {
|
|
85
|
+
if (!(await fs.pathExists(GATES_CONFIG_PATH))) return [];
|
|
86
|
+
try {
|
|
87
|
+
const content = await fs.readFile(GATES_CONFIG_PATH, 'utf-8');
|
|
88
|
+
const parsed = yaml.load(content);
|
|
89
|
+
return Array.isArray(parsed && parsed.disabled) ? parsed.disabled : [];
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error(chalk.red('Error reading quality-gates.yml:'), err.message);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async writeDisabled(disabled) {
|
|
97
|
+
if (!(await fs.pathExists(GATES_CONFIG_PATH))) {
|
|
98
|
+
await fs.writeFile(GATES_CONFIG_PATH, `# Quality Gates Configuration\n\ndisabled:\n`);
|
|
99
|
+
}
|
|
100
|
+
const content = await fs.readFile(GATES_CONFIG_PATH, 'utf-8');
|
|
101
|
+
// Replace or append the disabled block, preserving comments above it
|
|
102
|
+
const withoutDisabled = content.replace(/^disabled:[\s\S]*$/m, '').trimEnd();
|
|
103
|
+
const disabledBlock =
|
|
104
|
+
disabled.length > 0
|
|
105
|
+
? `\ndisabled:\n${disabled.map((k) => ` - ${k}`).join('\n')}\n`
|
|
106
|
+
: `\ndisabled:\n`;
|
|
107
|
+
await fs.writeFile(GATES_CONFIG_PATH, withoutDisabled + disabledBlock);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
printInvalidKey(key) {
|
|
111
|
+
console.error(chalk.red(`Unknown gate key: "${key}"`));
|
|
112
|
+
console.log(chalk.yellow('\nValid gate keys:'));
|
|
113
|
+
for (const [stack, keys] of Object.entries(KNOWN_GATES)) {
|
|
114
|
+
console.log(chalk.cyan(` ${stack}: `) + keys.join(', '));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = GatesCommand;
|