@nolrm/contextkit 0.13.7 → 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 CHANGED
@@ -165,8 +165,11 @@ ContextKit installs reusable slash commands for supported platforms:
165
165
  | `/squad-review` | Review the full pipeline and give a verdict |
166
166
  | `/squad-doc` | Create companion `.md` files for new/modified code after review passes |
167
167
  | `/squad-auto` | Auto-run the full pipeline after kickoff (recommended, sequential) |
168
- | `/squad-auto-parallel` | Auto-run the pipeline in parallel using Claude Code agents (Claude Code only) |
169
- | `/ck` | Health check — verify setup, standards, and integrations |
168
+ | `/squad-auto-parallel` | Auto-run the pipeline in parallel using Claude Code agents (Claude Code only) |
169
+ | `/ck` | Health check — verify setup, standards, and integrations |
170
+ | `/agent-push-checklist` | Pre-push quality checklist for agents to self-check before `git push` |
171
+ | `/context-budget` | Prioritized guide for which standards files to load for a given task |
172
+ | `/standards-aware` | Decide whether and how to add a newly discovered pattern to the project's standards files |
170
173
 
171
174
  **Claude Code** — available as `/analyze`, `/review`, etc. in `.claude/commands/`
172
175
  **Cursor** — available as slash commands in Chat via `.cursor/prompts/`
@@ -283,6 +286,18 @@ The pre-push hook detects your project type and runs the right quality checks au
283
286
  | **Swift** | SwiftLint, swift test |
284
287
  | **.NET / C#** | dotnet build, dotnet test |
285
288
 
289
+ ### Managing Gates
290
+
291
+ Use `ck gates` to inspect or toggle individual checks without editing config files manually:
292
+
293
+ ```bash
294
+ ck gates # list all gates and their status
295
+ ck gates --disable prettier # disable a specific gate
296
+ ck gates --enable prettier # re-enable it
297
+ ```
298
+
299
+ Gate state is saved to `.contextkit/quality-gates.yml`. Commit this file to share gate preferences with your team.
300
+
286
301
  ### Commit Message Format
287
302
 
288
303
  When the `commit-msg` hook is enabled, all commits must follow this format:
package/bin/contextkit.js CHANGED
@@ -7,6 +7,7 @@ const analyze = require('../lib/commands/analyze');
7
7
  const check = require('../lib/commands/check');
8
8
  const note = require('../lib/commands/note');
9
9
  const run = require('../lib/commands/run');
10
+ const GatesCommand = require('../lib/commands/gates');
10
11
 
11
12
  const packageJson = require('../package.json');
12
13
  const { checkForUpdates } = require('../lib/utils/notifier');
@@ -112,6 +113,23 @@ program
112
113
  }
113
114
  });
114
115
 
116
+ // Gates command
117
+ program
118
+ .command('gates')
119
+ .description('Inspect and manage quality gate configuration')
120
+ .option('--disable <key>', 'Disable a specific gate by key')
121
+ .option('--enable <key>', 'Enable a specific gate by key')
122
+ .option('--list', 'List all gates and their status (default)')
123
+ .action(async (options) => {
124
+ try {
125
+ const cmd = new GatesCommand();
126
+ await cmd.run(options);
127
+ } catch (error) {
128
+ console.error(chalk.red('Gates command failed:'), error.message);
129
+ process.exit(1);
130
+ }
131
+ });
132
+
115
133
  // Run command
116
134
  program
117
135
  .command('run <workflow>')
@@ -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;
@@ -133,6 +133,9 @@ class InstallCommand {
133
133
  await this.installGitHubActionsWorkflow();
134
134
  }
135
135
 
136
+ // Create quality gates config
137
+ await this.createQualityGatesConfig();
138
+
136
139
  // Create configuration
137
140
  await this.createConfiguration(projectType, hookChoices, squadCi);
138
141
 
@@ -496,11 +499,43 @@ Run \`/analyze\` to generate this content.`,
496
499
 
497
500
  'standards/ai-guidelines.md': `# AI Guidelines
498
501
 
499
- <!-- Content will be generated by running: /analyze -->
502
+ > Run \`/analyze\` to add project-specific rules to this file.
500
503
 
501
- Guidelines for AI assistance will be defined based on your project's needs and patterns.
504
+ ## Agentic Workflow
502
505
 
503
- Run \`/analyze\` to generate this content.`,
506
+ When working as an agent in this project:
507
+
508
+ - **Read standards first** — load \`code-style.md\` and \`testing.md\` before writing code
509
+ - **Before pushing** — run through \`.contextkit/commands/agents/agent-push-checklist.md\`
510
+ - **Commit format** — all commits must follow Conventional Commits: \`type(scope): description\`
511
+ - Valid types: \`feat\`, \`fix\`, \`improve\`, \`docs\`, \`chore\`, \`refactor\`, \`test\`
512
+ - **When to proceed** — proceed if the task is clear and standards cover it
513
+ - **When to ask** — ask if the task is ambiguous, contradicts existing standards, or requires an architecture decision
514
+ - **No debug statements** — do not leave \`console.log\`, \`print\`, or equivalent debug output in production code
515
+
516
+ ## Context Budget
517
+
518
+ Load standards files in this priority order to use your context window efficiently:
519
+
520
+ 1. **Always load:** \`code-style.md\`, \`testing.md\` — highest signal, always relevant
521
+ 2. **Load at session start:** \`ai-guidelines.md\` (this file) — behaviour rules
522
+ 3. **Load on demand:** \`architecture.md\` — only when making structural decisions
523
+ 4. **Load on demand:** \`workflows.md\` — only for process questions
524
+ 5. **Load selectively:** \`code-style/typescript-style.md\`, \`code-style/css-style.md\` — only for the file type you are editing
525
+ 6. **Skip unless needed:** \`glossary.md\` — only when the task involves domain-specific terms
526
+
527
+ If a standards file is longer than 200 lines, read the sections relevant to your task — not the whole file.
528
+
529
+ ## Standards Loop
530
+
531
+ This project follows a continuous standards loop:
532
+
533
+ 1. Standards files define what correct looks like
534
+ 2. Quality gates enforce it at every push (human or agent)
535
+ 3. Agents read standards before writing code and write to standards when new patterns emerge
536
+
537
+ When you discover a pattern worth standardising, use \`/standards-aware\` to decide whether and how to add it.
538
+ Without the standards, agents guess. Without the gates, the guesses reach the repo unchecked.`,
504
539
 
505
540
  'standards/workflows.md': `# Workflows
506
541
 
@@ -737,104 +772,118 @@ Any design decisions, trade-offs, or open questions to resolve before coding.
737
772
 
738
773
  // Download commands
739
774
  await this.downloadManager.downloadFile(
740
- `${this.repoUrl}/commands/analyze.md`,
741
- '.contextkit/commands/analyze.md'
775
+ `${this.repoUrl}/commands/dev/analyze.md`,
776
+ '.contextkit/commands/dev/analyze.md'
742
777
  );
743
778
  await this.downloadManager.downloadFile(
744
- `${this.repoUrl}/commands/review.md`,
745
- '.contextkit/commands/review.md'
779
+ `${this.repoUrl}/commands/dev/review.md`,
780
+ '.contextkit/commands/dev/review.md'
746
781
  );
747
782
  await this.downloadManager.downloadFile(
748
- `${this.repoUrl}/commands/fix.md`,
749
- '.contextkit/commands/fix.md'
783
+ `${this.repoUrl}/commands/dev/fix.md`,
784
+ '.contextkit/commands/dev/fix.md'
750
785
  );
751
786
  await this.downloadManager.downloadFile(
752
- `${this.repoUrl}/commands/refactor.md`,
753
- '.contextkit/commands/refactor.md'
787
+ `${this.repoUrl}/commands/dev/refactor.md`,
788
+ '.contextkit/commands/dev/refactor.md'
754
789
  );
755
790
  await this.downloadManager.downloadFile(
756
- `${this.repoUrl}/commands/run-tests.md`,
757
- '.contextkit/commands/run-tests.md'
791
+ `${this.repoUrl}/commands/dev/run-tests.md`,
792
+ '.contextkit/commands/dev/run-tests.md'
758
793
  );
759
794
  await this.downloadManager.downloadFile(
760
- `${this.repoUrl}/commands/add-documentation.md`,
761
- '.contextkit/commands/add-documentation.md'
795
+ `${this.repoUrl}/commands/docs/add-documentation.md`,
796
+ '.contextkit/commands/docs/add-documentation.md'
762
797
  );
763
798
  await this.downloadManager.downloadFile(
764
- `${this.repoUrl}/commands/quality-check.md`,
765
- '.contextkit/commands/quality-check.md'
799
+ `${this.repoUrl}/commands/dev/quality-check.md`,
800
+ '.contextkit/commands/dev/quality-check.md'
766
801
  );
767
802
  await this.downloadManager.downloadFile(
768
- `${this.repoUrl}/commands/create-feature.md`,
769
- '.contextkit/commands/create-feature.md'
803
+ `${this.repoUrl}/commands/dev/create-feature.md`,
804
+ '.contextkit/commands/dev/create-feature.md'
770
805
  );
771
806
  await this.downloadManager.downloadFile(
772
- `${this.repoUrl}/commands/create-component.md`,
773
- '.contextkit/commands/create-component.md'
807
+ `${this.repoUrl}/commands/dev/create-component.md`,
808
+ '.contextkit/commands/dev/create-component.md'
774
809
  );
775
810
  await this.downloadManager.downloadFile(
776
- `${this.repoUrl}/commands/spec.md`,
777
- '.contextkit/commands/spec.md'
811
+ `${this.repoUrl}/commands/dev/spec.md`,
812
+ '.contextkit/commands/dev/spec.md'
778
813
  );
779
814
 
780
815
  // Download squad commands
781
816
  await this.downloadManager.downloadFile(
782
- `${this.repoUrl}/commands/squad.md`,
783
- '.contextkit/commands/squad.md'
817
+ `${this.repoUrl}/commands/squad/squad.md`,
818
+ '.contextkit/commands/squad/squad.md'
784
819
  );
785
820
  await this.downloadManager.downloadFile(
786
- `${this.repoUrl}/commands/squad-architect.md`,
787
- '.contextkit/commands/squad-architect.md'
821
+ `${this.repoUrl}/commands/squad/squad-architect.md`,
822
+ '.contextkit/commands/squad/squad-architect.md'
788
823
  );
789
824
  await this.downloadManager.downloadFile(
790
- `${this.repoUrl}/commands/squad-dev.md`,
791
- '.contextkit/commands/squad-dev.md'
825
+ `${this.repoUrl}/commands/squad/squad-dev.md`,
826
+ '.contextkit/commands/squad/squad-dev.md'
792
827
  );
793
828
  await this.downloadManager.downloadFile(
794
- `${this.repoUrl}/commands/squad-test.md`,
795
- '.contextkit/commands/squad-test.md'
829
+ `${this.repoUrl}/commands/squad/squad-test.md`,
830
+ '.contextkit/commands/squad/squad-test.md'
796
831
  );
797
832
  await this.downloadManager.downloadFile(
798
- `${this.repoUrl}/commands/squad-review.md`,
799
- '.contextkit/commands/squad-review.md'
833
+ `${this.repoUrl}/commands/squad/squad-review.md`,
834
+ '.contextkit/commands/squad/squad-review.md'
800
835
  );
801
836
  await this.downloadManager.downloadFile(
802
- `${this.repoUrl}/commands/squad-auto.md`,
803
- '.contextkit/commands/squad-auto.md'
837
+ `${this.repoUrl}/commands/squad/squad-auto.md`,
838
+ '.contextkit/commands/squad/squad-auto.md'
804
839
  );
805
840
  await this.downloadManager.downloadFile(
806
- `${this.repoUrl}/commands/squad-auto-parallel.md`,
807
- '.contextkit/commands/squad-auto-parallel.md'
841
+ `${this.repoUrl}/commands/squad/squad-auto-parallel.md`,
842
+ '.contextkit/commands/squad/squad-auto-parallel.md'
808
843
  );
809
844
  await this.downloadManager.downloadFile(
810
- `${this.repoUrl}/commands/squad-reset.md`,
811
- '.contextkit/commands/squad-reset.md'
845
+ `${this.repoUrl}/commands/squad/squad-reset.md`,
846
+ '.contextkit/commands/squad/squad-reset.md'
812
847
  );
813
848
  await this.downloadManager.downloadFile(
814
- `${this.repoUrl}/commands/squad-doc.md`,
815
- '.contextkit/commands/squad-doc.md'
849
+ `${this.repoUrl}/commands/squad/squad-doc.md`,
850
+ '.contextkit/commands/squad/squad-doc.md'
816
851
  );
817
852
  await this.downloadManager.downloadFile(
818
- `${this.repoUrl}/commands/squad-ci.md`,
819
- '.contextkit/commands/squad-ci.md'
853
+ `${this.repoUrl}/commands/squad/squad-ci.md`,
854
+ '.contextkit/commands/squad/squad-ci.md'
820
855
  );
821
856
  await this.downloadManager.downloadFile(
822
- `${this.repoUrl}/commands/health-check.md`,
823
- '.contextkit/commands/health-check.md'
857
+ `${this.repoUrl}/commands/dev/health-check.md`,
858
+ '.contextkit/commands/dev/health-check.md'
824
859
  );
825
860
 
826
861
  // Download doc family commands
827
862
  await this.downloadManager.downloadFile(
828
- `${this.repoUrl}/commands/doc-arch.md`,
829
- '.contextkit/commands/doc-arch.md'
863
+ `${this.repoUrl}/commands/docs/doc-arch.md`,
864
+ '.contextkit/commands/docs/doc-arch.md'
830
865
  );
831
866
  await this.downloadManager.downloadFile(
832
- `${this.repoUrl}/commands/doc-feature.md`,
833
- '.contextkit/commands/doc-feature.md'
867
+ `${this.repoUrl}/commands/docs/doc-feature.md`,
868
+ '.contextkit/commands/docs/doc-feature.md'
834
869
  );
835
870
  await this.downloadManager.downloadFile(
836
- `${this.repoUrl}/commands/doc-component.md`,
837
- '.contextkit/commands/doc-component.md'
871
+ `${this.repoUrl}/commands/docs/doc-component.md`,
872
+ '.contextkit/commands/docs/doc-component.md'
873
+ );
874
+
875
+ // Download agentic workflow commands
876
+ await this.downloadManager.downloadFile(
877
+ `${this.repoUrl}/commands/agents/context-budget.md`,
878
+ '.contextkit/commands/agents/context-budget.md'
879
+ );
880
+ await this.downloadManager.downloadFile(
881
+ `${this.repoUrl}/commands/agents/agent-push-checklist.md`,
882
+ '.contextkit/commands/agents/agent-push-checklist.md'
883
+ );
884
+ await this.downloadManager.downloadFile(
885
+ `${this.repoUrl}/commands/agents/standards-aware.md`,
886
+ '.contextkit/commands/agents/standards-aware.md'
838
887
  );
839
888
 
840
889
  // Download hooks (pre-push and commit-msg only, no pre-commit)
@@ -937,15 +986,15 @@ claude "read .contextkit/context.md to see available standards, then create a bu
937
986
  - \`.contextkit/product/context.md\` - Domain-specific context
938
987
 
939
988
  ### Commands
940
- - \`.contextkit/commands/analyze.md\` - Analyze & customize standards
941
- - \`.contextkit/commands/review.md\` - Code review
942
- - \`.contextkit/commands/fix.md\` - Diagnose and fix bugs
943
- - \`.contextkit/commands/refactor.md\` - Refactor code structure
944
- - \`.contextkit/commands/run-tests.md\` - Generate or run tests
945
- - \`.contextkit/commands/add-documentation.md\` - Add documentation
946
- - \`.contextkit/commands/quality-check.md\` - Quality checks
947
- - \`.contextkit/commands/create-component.md\` - Create component
948
- - \`.contextkit/commands/create-feature.md\` - Create feature
989
+ - \`.contextkit/commands/dev/analyze.md\` - Analyze & customize standards
990
+ - \`.contextkit/commands/dev/review.md\` - Code review
991
+ - \`.contextkit/commands/dev/fix.md\` - Diagnose and fix bugs
992
+ - \`.contextkit/commands/dev/refactor.md\` - Refactor code structure
993
+ - \`.contextkit/commands/dev/run-tests.md\` - Generate or run tests
994
+ - \`.contextkit/commands/docs/add-documentation.md\` - Add documentation
995
+ - \`.contextkit/commands/dev/quality-check.md\` - Quality checks
996
+ - \`.contextkit/commands/dev/create-component.md\` - Create component
997
+ - \`.contextkit/commands/dev/create-feature.md\` - Create feature
949
998
 
950
999
  ### Instructions
951
1000
  - \`.contextkit/instructions/meta/pre-flight.md\` - Pre-flight checks
@@ -1066,15 +1115,15 @@ esac
1066
1115
  docs: 'docs',
1067
1116
  },
1068
1117
  commands: {
1069
- analyze: '@.contextkit/commands/analyze.md',
1070
- review: '@.contextkit/commands/review.md',
1071
- fix: '@.contextkit/commands/fix.md',
1072
- refactor: '@.contextkit/commands/refactor.md',
1073
- run_tests: '@.contextkit/commands/run-tests.md',
1074
- add_docs: '@.contextkit/commands/add-documentation.md',
1075
- quality_check: '@.contextkit/commands/quality-check.md',
1076
- create_component: '@.contextkit/commands/create-component.md',
1077
- create_feature: '@.contextkit/commands/create-feature.md',
1118
+ analyze: '@.contextkit/commands/dev/analyze.md',
1119
+ review: '@.contextkit/commands/dev/review.md',
1120
+ fix: '@.contextkit/commands/dev/fix.md',
1121
+ refactor: '@.contextkit/commands/dev/refactor.md',
1122
+ run_tests: '@.contextkit/commands/dev/run-tests.md',
1123
+ add_docs: '@.contextkit/commands/docs/add-documentation.md',
1124
+ quality_check: '@.contextkit/commands/dev/quality-check.md',
1125
+ create_component: '@.contextkit/commands/dev/create-component.md',
1126
+ create_feature: '@.contextkit/commands/dev/create-feature.md',
1078
1127
  },
1079
1128
  };
1080
1129
 
@@ -1740,7 +1789,7 @@ enforcement:
1740
1789
 
1741
1790
  if (platform === 'cursor') {
1742
1791
  console.log(chalk.bold('In Cursor Chat:'));
1743
- console.log(` @.contextkit/commands/analyze.md`);
1792
+ console.log(` @.contextkit/commands/dev/analyze.md`);
1744
1793
  console.log('');
1745
1794
  console.log('Or via CLI:');
1746
1795
  console.log(chalk.yellow('👉'), `/analyze`);
@@ -1766,7 +1815,7 @@ enforcement:
1766
1815
 
1767
1816
  if (platform === 'cursor') {
1768
1817
  console.log(chalk.bold('In Cursor Chat'));
1769
- console.log(`@.contextkit/commands/create-component.md`);
1818
+ console.log(`@.contextkit/commands/dev/create-component.md`);
1770
1819
  console.log(chalk.dim('"Create a Button component for customer checkout"'));
1771
1820
  console.log('');
1772
1821
  }
@@ -1774,7 +1823,7 @@ enforcement:
1774
1823
  console.log(chalk.bold('In CLI'));
1775
1824
  console.log(
1776
1825
  chalk.dim(
1777
- "Use your AI tool's slash command, e.g. /analyze or @.contextkit/commands/create-component.md"
1826
+ "Use your AI tool's slash command, e.g. /analyze or @.contextkit/commands/dev/create-component.md"
1778
1827
  )
1779
1828
  );
1780
1829
  console.log('');
@@ -1782,7 +1831,7 @@ enforcement:
1782
1831
  if (platform === 'claude' || platform === 'gemini') {
1783
1832
  const toolName = platform === 'claude' ? 'Claude' : 'Gemini';
1784
1833
  console.log(chalk.bold(`In ${toolName} CLI`));
1785
- console.log(`read .contextkit/commands/analyze.md and execute`);
1834
+ console.log(`read .contextkit/commands/dev/analyze.md and execute`);
1786
1835
  console.log('');
1787
1836
  }
1788
1837
 
@@ -1973,6 +2022,59 @@ module.exports = [
1973
2022
  }
1974
2023
  return false;
1975
2024
  }
2025
+
2026
+ async createQualityGatesConfig() {
2027
+ const configPath = '.contextkit/quality-gates.yml';
2028
+ if (await fs.pathExists(configPath)) return;
2029
+ const content = `# Quality Gates Configuration
2030
+ # Disable specific gates by uncommenting keys below.
2031
+ # All gates are enabled by default.
2032
+ # Reference: https://contextkit-docs.vercel.app/docs/quality-gates
2033
+
2034
+ disabled:
2035
+ # Node.js gates
2036
+ # - typescript # skip TypeScript type checking
2037
+ # - eslint # skip ESLint (direct, not via script)
2038
+ # - prettier # skip Prettier (direct, not via script)
2039
+ # - format # skip npm run format
2040
+ # - lint # skip npm run lint
2041
+ # - build # skip npm run build
2042
+ # - test # skip npm test
2043
+ # - e2e # skip npm run e2e
2044
+ # Python gates
2045
+ # - ruff-lint # skip ruff/flake8 lint
2046
+ # - typecheck # skip mypy
2047
+ # - ruff-format # skip ruff/black format check
2048
+ # - pytest # skip pytest
2049
+ # Rust gates
2050
+ # - cargo-check # skip cargo check
2051
+ # - clippy # skip cargo clippy
2052
+ # - cargo-test # skip cargo test
2053
+ # Go gates
2054
+ # - go-vet # skip go vet
2055
+ # - golangci-lint # skip golangci-lint
2056
+ # - go-test # skip go test
2057
+ # PHP gates
2058
+ # - phpstan # skip PHPStan
2059
+ # - phpunit # skip PHPUnit
2060
+ # Ruby gates
2061
+ # - rubocop # skip RuboCop
2062
+ # - rspec # skip RSpec / rake test
2063
+ # Java / Kotlin gates
2064
+ # - maven-verify # skip mvn verify
2065
+ # - gradle-check # skip gradle check
2066
+ # - ktlint # skip ktlint
2067
+ # - kotlin-test # skip gradle test
2068
+ # Swift gates
2069
+ # - swiftlint # skip SwiftLint
2070
+ # - swift-test # skip swift test
2071
+ # .NET gates
2072
+ # - dotnet-build # skip dotnet build
2073
+ # - dotnet-test # skip dotnet test
2074
+ `;
2075
+ await fs.writeFile(configPath, content);
2076
+ console.log(chalk.green('✅ Created .contextkit/quality-gates.yml'));
2077
+ }
1976
2078
  }
1977
2079
 
1978
2080
  async function install(options) {
@@ -236,104 +236,116 @@ class UpdateCommand {
236
236
 
237
237
  // Download commands
238
238
  await this.downloadManager.downloadFile(
239
- `${this.repoUrl}/commands/analyze.md`,
240
- '.contextkit/commands/analyze.md'
239
+ `${this.repoUrl}/commands/dev/analyze.md`,
240
+ '.contextkit/commands/dev/analyze.md'
241
241
  );
242
242
  await this.downloadManager.downloadFile(
243
- `${this.repoUrl}/commands/review.md`,
244
- '.contextkit/commands/review.md'
243
+ `${this.repoUrl}/commands/dev/review.md`,
244
+ '.contextkit/commands/dev/review.md'
245
245
  );
246
246
  await this.downloadManager.downloadFile(
247
- `${this.repoUrl}/commands/fix.md`,
248
- '.contextkit/commands/fix.md'
247
+ `${this.repoUrl}/commands/dev/fix.md`,
248
+ '.contextkit/commands/dev/fix.md'
249
249
  );
250
250
  await this.downloadManager.downloadFile(
251
- `${this.repoUrl}/commands/refactor.md`,
252
- '.contextkit/commands/refactor.md'
251
+ `${this.repoUrl}/commands/dev/refactor.md`,
252
+ '.contextkit/commands/dev/refactor.md'
253
253
  );
254
254
  await this.downloadManager.downloadFile(
255
- `${this.repoUrl}/commands/run-tests.md`,
256
- '.contextkit/commands/run-tests.md'
255
+ `${this.repoUrl}/commands/dev/run-tests.md`,
256
+ '.contextkit/commands/dev/run-tests.md'
257
257
  );
258
258
  await this.downloadManager.downloadFile(
259
- `${this.repoUrl}/commands/add-documentation.md`,
260
- '.contextkit/commands/add-documentation.md'
259
+ `${this.repoUrl}/commands/docs/add-documentation.md`,
260
+ '.contextkit/commands/docs/add-documentation.md'
261
261
  );
262
262
  await this.downloadManager.downloadFile(
263
- `${this.repoUrl}/commands/quality-check.md`,
264
- '.contextkit/commands/quality-check.md'
263
+ `${this.repoUrl}/commands/dev/quality-check.md`,
264
+ '.contextkit/commands/dev/quality-check.md'
265
265
  );
266
266
  await this.downloadManager.downloadFile(
267
- `${this.repoUrl}/commands/create-feature.md`,
268
- '.contextkit/commands/create-feature.md'
267
+ `${this.repoUrl}/commands/dev/create-feature.md`,
268
+ '.contextkit/commands/dev/create-feature.md'
269
269
  );
270
270
  await this.downloadManager.downloadFile(
271
- `${this.repoUrl}/commands/create-component.md`,
272
- '.contextkit/commands/create-component.md'
271
+ `${this.repoUrl}/commands/dev/create-component.md`,
272
+ '.contextkit/commands/dev/create-component.md'
273
273
  );
274
274
  await this.downloadManager.downloadFile(
275
- `${this.repoUrl}/commands/spec.md`,
276
- '.contextkit/commands/spec.md'
275
+ `${this.repoUrl}/commands/dev/spec.md`,
276
+ '.contextkit/commands/dev/spec.md'
277
277
  );
278
278
 
279
279
  // Download squad commands
280
280
  await this.downloadManager.downloadFile(
281
- `${this.repoUrl}/commands/squad.md`,
282
- '.contextkit/commands/squad.md'
281
+ `${this.repoUrl}/commands/squad/squad.md`,
282
+ '.contextkit/commands/squad/squad.md'
283
283
  );
284
284
  await this.downloadManager.downloadFile(
285
- `${this.repoUrl}/commands/squad-architect.md`,
286
- '.contextkit/commands/squad-architect.md'
285
+ `${this.repoUrl}/commands/squad/squad-architect.md`,
286
+ '.contextkit/commands/squad/squad-architect.md'
287
287
  );
288
288
  await this.downloadManager.downloadFile(
289
- `${this.repoUrl}/commands/squad-dev.md`,
290
- '.contextkit/commands/squad-dev.md'
289
+ `${this.repoUrl}/commands/squad/squad-dev.md`,
290
+ '.contextkit/commands/squad/squad-dev.md'
291
291
  );
292
292
  await this.downloadManager.downloadFile(
293
- `${this.repoUrl}/commands/squad-test.md`,
294
- '.contextkit/commands/squad-test.md'
293
+ `${this.repoUrl}/commands/squad/squad-test.md`,
294
+ '.contextkit/commands/squad/squad-test.md'
295
295
  );
296
296
  await this.downloadManager.downloadFile(
297
- `${this.repoUrl}/commands/squad-review.md`,
298
- '.contextkit/commands/squad-review.md'
297
+ `${this.repoUrl}/commands/squad/squad-review.md`,
298
+ '.contextkit/commands/squad/squad-review.md'
299
299
  );
300
300
  await this.downloadManager.downloadFile(
301
- `${this.repoUrl}/commands/squad-auto.md`,
302
- '.contextkit/commands/squad-auto.md'
301
+ `${this.repoUrl}/commands/squad/squad-auto.md`,
302
+ '.contextkit/commands/squad/squad-auto.md'
303
303
  );
304
304
  await this.downloadManager.downloadFile(
305
- `${this.repoUrl}/commands/squad-auto-parallel.md`,
306
- '.contextkit/commands/squad-auto-parallel.md'
305
+ `${this.repoUrl}/commands/squad/squad-auto-parallel.md`,
306
+ '.contextkit/commands/squad/squad-auto-parallel.md'
307
307
  );
308
308
  await this.downloadManager.downloadFile(
309
- `${this.repoUrl}/commands/squad-reset.md`,
310
- '.contextkit/commands/squad-reset.md'
309
+ `${this.repoUrl}/commands/squad/squad-reset.md`,
310
+ '.contextkit/commands/squad/squad-reset.md'
311
311
  );
312
312
  await this.downloadManager.downloadFile(
313
- `${this.repoUrl}/commands/squad-doc.md`,
314
- '.contextkit/commands/squad-doc.md'
313
+ `${this.repoUrl}/commands/squad/squad-doc.md`,
314
+ '.contextkit/commands/squad/squad-doc.md'
315
315
  );
316
316
  await this.downloadManager.downloadFile(
317
- `${this.repoUrl}/commands/squad-ci.md`,
318
- '.contextkit/commands/squad-ci.md'
317
+ `${this.repoUrl}/commands/squad/squad-ci.md`,
318
+ '.contextkit/commands/squad/squad-ci.md'
319
319
  );
320
320
  await this.downloadManager.downloadFile(
321
- `${this.repoUrl}/commands/health-check.md`,
322
- '.contextkit/commands/health-check.md'
321
+ `${this.repoUrl}/commands/dev/health-check.md`,
322
+ '.contextkit/commands/dev/health-check.md'
323
323
  );
324
324
 
325
325
  // Download doc family commands
326
326
  await this.downloadManager.downloadFile(
327
- `${this.repoUrl}/commands/doc-arch.md`,
328
- '.contextkit/commands/doc-arch.md'
327
+ `${this.repoUrl}/commands/docs/doc-arch.md`,
328
+ '.contextkit/commands/docs/doc-arch.md'
329
329
  );
330
330
  await this.downloadManager.downloadFile(
331
- `${this.repoUrl}/commands/doc-feature.md`,
332
- '.contextkit/commands/doc-feature.md'
331
+ `${this.repoUrl}/commands/docs/doc-feature.md`,
332
+ '.contextkit/commands/docs/doc-feature.md'
333
333
  );
334
334
  await this.downloadManager.downloadFile(
335
- `${this.repoUrl}/commands/doc-component.md`,
336
- '.contextkit/commands/doc-component.md'
335
+ `${this.repoUrl}/commands/docs/doc-component.md`,
336
+ '.contextkit/commands/docs/doc-component.md'
337
+ );
338
+ await this.downloadManager.downloadFile(
339
+ `${this.repoUrl}/commands/agents/context-budget.md`,
340
+ '.contextkit/commands/agents/context-budget.md'
341
+ );
342
+ await this.downloadManager.downloadFile(
343
+ `${this.repoUrl}/commands/agents/agent-push-checklist.md`,
344
+ '.contextkit/commands/agents/agent-push-checklist.md'
345
+ );
346
+ await this.downloadManager.downloadFile(
347
+ `${this.repoUrl}/commands/agents/standards-aware.md`,
348
+ '.contextkit/commands/agents/standards-aware.md'
337
349
  );
338
350
 
339
351
  // Update CI squad workflow if the user opted in
@@ -426,15 +438,15 @@ paths:
426
438
 
427
439
  # Commands
428
440
  commands:
429
- analyze: "${config.commands?.analyze || '@.contextkit/commands/analyze.md'}"
430
- review: "${config.commands?.review || '@.contextkit/commands/review.md'}"
431
- fix: "${config.commands?.fix || '@.contextkit/commands/fix.md'}"
432
- refactor: "${config.commands?.refactor || '@.contextkit/commands/refactor.md'}"
433
- run_tests: "${config.commands?.run_tests || '@.contextkit/commands/run-tests.md'}"
434
- add_docs: "${config.commands?.add_docs || '@.contextkit/commands/add-documentation.md'}"
435
- quality_check: "${config.commands?.quality_check || '@.contextkit/commands/quality-check.md'}"
436
- create_component: "${config.commands?.create_component || '@.contextkit/commands/create-component.md'}"
437
- create_feature: "${config.commands?.create_feature || '@.contextkit/commands/create-feature.md'}"
441
+ analyze: "${config.commands?.analyze || '@.contextkit/commands/dev/analyze.md'}"
442
+ review: "${config.commands?.review || '@.contextkit/commands/dev/review.md'}"
443
+ fix: "${config.commands?.fix || '@.contextkit/commands/dev/fix.md'}"
444
+ refactor: "${config.commands?.refactor || '@.contextkit/commands/dev/refactor.md'}"
445
+ run_tests: "${config.commands?.run_tests || '@.contextkit/commands/dev/run-tests.md'}"
446
+ add_docs: "${config.commands?.add_docs || '@.contextkit/commands/docs/add-documentation.md'}"
447
+ quality_check: "${config.commands?.quality_check || '@.contextkit/commands/dev/quality-check.md'}"
448
+ create_component: "${config.commands?.create_component || '@.contextkit/commands/dev/create-component.md'}"
449
+ create_feature: "${config.commands?.create_feature || '@.contextkit/commands/dev/create-feature.md'}"
438
450
  `;
439
451
 
440
452
  await fs.writeFile('.contextkit/config.yml', configContent);
@@ -465,7 +477,35 @@ commands:
465
477
  }
466
478
 
467
479
  async removeLegacyFiles() {
468
- const legacyFiles = ['.contextkit/commands/squad-peer-review.md'];
480
+ const legacyFiles = [
481
+ // Removed in 0.14.0 — commands reorganised into dev/ squad/ docs/ agents/ subdirs
482
+ '.contextkit/commands/analyze.md',
483
+ '.contextkit/commands/review.md',
484
+ '.contextkit/commands/fix.md',
485
+ '.contextkit/commands/refactor.md',
486
+ '.contextkit/commands/run-tests.md',
487
+ '.contextkit/commands/add-documentation.md',
488
+ '.contextkit/commands/quality-check.md',
489
+ '.contextkit/commands/create-feature.md',
490
+ '.contextkit/commands/create-component.md',
491
+ '.contextkit/commands/spec.md',
492
+ '.contextkit/commands/health-check.md',
493
+ '.contextkit/commands/squad.md',
494
+ '.contextkit/commands/squad-architect.md',
495
+ '.contextkit/commands/squad-dev.md',
496
+ '.contextkit/commands/squad-test.md',
497
+ '.contextkit/commands/squad-review.md',
498
+ '.contextkit/commands/squad-auto.md',
499
+ '.contextkit/commands/squad-auto-parallel.md',
500
+ '.contextkit/commands/squad-reset.md',
501
+ '.contextkit/commands/squad-doc.md',
502
+ '.contextkit/commands/squad-ci.md',
503
+ '.contextkit/commands/doc-arch.md',
504
+ '.contextkit/commands/doc-feature.md',
505
+ '.contextkit/commands/doc-component.md',
506
+ // Older legacy
507
+ '.contextkit/commands/squad-peer-review.md',
508
+ ];
469
509
  for (const file of legacyFiles) {
470
510
  if (await fs.pathExists(file)) {
471
511
  await fs.remove(file);
package/lib/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  const install = require('./commands/install');
2
2
  const update = require('./commands/update');
3
3
  const status = require('./commands/status');
4
+ const GatesCommand = require('./commands/gates');
4
5
 
5
6
  module.exports = {
6
7
  install,
7
8
  update,
8
9
  status,
10
+ gates: GatesCommand,
9
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolrm/contextkit",
3
- "version": "0.13.7",
3
+ "version": "0.14.0",
4
4
  "description": "ContextKit - Context Engineering for AI Development. Provide rich context to AI through structured MD files with standards, code guides, and documentation. Works with Cursor, Claude, Aider, VS Code Copilot, and more.",
5
5
  "main": "lib/index.js",
6
6
  "bin": {