omgkit 2.25.0 → 2.26.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
@@ -278,13 +278,21 @@ Commands are slash-prefixed actions organized by namespace.
278
278
  ```bash
279
279
  /dev:feature <desc> # Full feature development
280
280
  /dev:fix <error> # Debug and fix bugs
281
- /dev:fix-fast <error> # Quick bug fix
281
+ /dev:fix-fast <error> # Quick bug fix (tests optional)
282
282
  /dev:fix-hard <error> # Complex bug (deep analysis)
283
283
  /dev:test <scope> # Generate tests
284
284
  /dev:tdd <feature> # Test-driven development
285
285
  /dev:review [file] # Code review
286
286
  ```
287
287
 
288
+ **Testing Options** (available on most dev commands):
289
+ ```bash
290
+ /dev:feature "login" --no-test # Skip test enforcement
291
+ /dev:fix "bug" --test-level strict # Override enforcement level
292
+ /dev:feature-tested "auth" --coverage 90 # Custom coverage target
293
+ /dev:fix-fast "typo" --with-test # Opt-in to testing
294
+ ```
295
+
288
296
  ### Planning (`/planning:*`)
289
297
 
290
298
  ```bash
@@ -794,6 +802,38 @@ OMGKIT's upgrade system is designed with safety first:
794
802
  | **settings.json** | Version updated, structure preserved |
795
803
  | **Your files** | NEVER touched (config.yaml, sprints, artifacts, devlogs) |
796
804
 
805
+ ### Config Commands (New)
806
+
807
+ Configure workflow settings via CLI:
808
+
809
+ ```bash
810
+ # Get a config value
811
+ omgkit config get testing.enforcement.level
812
+ omgkit config get testing.coverage_gates.unit
813
+
814
+ # Set a config value
815
+ omgkit config set testing.enforcement.level strict
816
+ omgkit config set testing.auto_generate_tasks true
817
+ omgkit config set testing.coverage_gates.unit.minimum 90
818
+
819
+ # List all config or specific section
820
+ omgkit config list
821
+ omgkit config list testing
822
+
823
+ # Reset to default value
824
+ omgkit config reset testing.enforcement.level
825
+ ```
826
+
827
+ #### Supported Value Types
828
+
829
+ | Type | Example |
830
+ |------|---------|
831
+ | **String** | `omgkit config set git.main_branch develop` |
832
+ | **Boolean** | `omgkit config set testing.auto_generate_tasks true` |
833
+ | **Number** | `omgkit config set testing.coverage_gates.unit.minimum 90` |
834
+
835
+ **Note**: For arrays, edit `.omgkit/workflow.yaml` directly.
836
+
797
837
  ---
798
838
 
799
839
  ## Documentation Sync Automation
package/bin/omgkit.js CHANGED
@@ -25,6 +25,10 @@ import {
25
25
  rollbackProject,
26
26
  listProjectBackups,
27
27
  getProjectVersion,
28
+ getConfig,
29
+ setConfig,
30
+ listConfig,
31
+ resetConfig,
28
32
  COLORS,
29
33
  BANNER,
30
34
  log
@@ -57,6 +61,12 @@ ${COLORS.bright}PROJECT COMMANDS${COLORS.reset}
57
61
  ${COLORS.cyan}project:backups${COLORS.reset} List available project backups
58
62
  ${COLORS.cyan}project:version${COLORS.reset} Show project's OMGKIT version
59
63
 
64
+ ${COLORS.bright}CONFIG COMMANDS${COLORS.reset}
65
+ ${COLORS.cyan}config get <key>${COLORS.reset} Get config value (e.g., testing.enforcement.level)
66
+ ${COLORS.cyan}config set <key> <val>${COLORS.reset} Set config value
67
+ ${COLORS.cyan}config list [section]${COLORS.reset} List all config or specific section
68
+ ${COLORS.cyan}config reset <key>${COLORS.reset} Reset config key to default
69
+
60
70
  ${COLORS.bright}UPGRADE OPTIONS${COLORS.reset}
61
71
  --dry Show what would change without applying
62
72
  --force Skip confirmation prompts
@@ -69,6 +79,14 @@ ${COLORS.bright}EXAMPLES${COLORS.reset}
69
79
  omgkit project:rollback # Rollback to last backup
70
80
  omgkit doctor # Check status
71
81
 
82
+ ${COLORS.bright}CONFIG EXAMPLES${COLORS.reset}
83
+ omgkit config set testing.enforcement.level strict
84
+ omgkit config set testing.auto_generate_tasks true
85
+ omgkit config set testing.coverage_gates.unit.minimum 90
86
+ omgkit config get testing
87
+ omgkit config list testing
88
+ omgkit config reset testing.enforcement.level
89
+
72
90
  ${COLORS.bright}AFTER INSTALLATION${COLORS.reset}
73
91
  In Claude Code, type / to see all OMGKIT commands:
74
92
 
@@ -156,6 +174,70 @@ switch (command) {
156
174
  }
157
175
  break;
158
176
  }
177
+ case 'config': {
178
+ const subCommand = args[0];
179
+ switch (subCommand) {
180
+ case 'get': {
181
+ const key = args[1];
182
+ if (!key) {
183
+ log.error('Usage: omgkit config get <key>');
184
+ log.info('Example: omgkit config get testing.enforcement.level');
185
+ process.exit(1);
186
+ }
187
+ const result = getConfig(key);
188
+ if (!result.success) process.exit(1);
189
+ break;
190
+ }
191
+ case 'set': {
192
+ const key = args[1];
193
+ const value = args[2];
194
+ if (!key || value === undefined) {
195
+ log.error('Usage: omgkit config set <key> <value>');
196
+ log.info('Example: omgkit config set testing.enforcement.level strict');
197
+ process.exit(1);
198
+ }
199
+ const result = setConfig(key, value);
200
+ if (!result.success) process.exit(1);
201
+ break;
202
+ }
203
+ case 'list': {
204
+ const section = args[1];
205
+ const result = listConfig({ section });
206
+ if (!result.success) process.exit(1);
207
+ break;
208
+ }
209
+ case 'reset': {
210
+ const key = args[1];
211
+ if (!key) {
212
+ log.error('Usage: omgkit config reset <key>');
213
+ log.info('Example: omgkit config reset testing.enforcement.level');
214
+ process.exit(1);
215
+ }
216
+ const result = resetConfig(key);
217
+ if (!result.success) process.exit(1);
218
+ break;
219
+ }
220
+ default: {
221
+ log.error(`Unknown config subcommand: ${subCommand || '(none)'}`);
222
+ console.log(`
223
+ ${COLORS.bright}Config Commands:${COLORS.reset}
224
+ omgkit config get <key> Get config value
225
+ omgkit config set <key> <val> Set config value
226
+ omgkit config list [section] List all config
227
+ omgkit config reset <key> Reset to default
228
+
229
+ ${COLORS.bright}Examples:${COLORS.reset}
230
+ omgkit config get testing.enforcement.level
231
+ omgkit config set testing.enforcement.level strict
232
+ omgkit config set testing.auto_generate_tasks true
233
+ omgkit config list testing
234
+ omgkit config reset testing.enforcement.level
235
+ `);
236
+ process.exit(1);
237
+ }
238
+ }
239
+ break;
240
+ }
159
241
  case 'version':
160
242
  case '-v':
161
243
  case '--version': {
package/lib/cli.js CHANGED
@@ -1633,3 +1633,253 @@ ${COLORS.magenta}🔮 Think Omega. Build Omega. Be Omega.${COLORS.reset}
1633
1633
  backupPath: backup.path
1634
1634
  };
1635
1635
  }
1636
+
1637
+ // =============================================================================
1638
+ // WORKFLOW CONFIG MANAGEMENT
1639
+ // =============================================================================
1640
+
1641
+ /**
1642
+ * Get nested value from object using dot notation
1643
+ * @param {Object} obj - Object to get value from
1644
+ * @param {string} path - Dot-separated path (e.g., 'testing.enforcement.level')
1645
+ * @returns {*} Value at path or undefined
1646
+ */
1647
+ function getNestedValue(obj, path) {
1648
+ return path.split('.').reduce((current, key) => current?.[key], obj);
1649
+ }
1650
+
1651
+ /**
1652
+ * Set nested value in object using dot notation
1653
+ * @param {Object} obj - Object to set value in
1654
+ * @param {string} path - Dot-separated path
1655
+ * @param {*} value - Value to set
1656
+ */
1657
+ function setNestedValue(obj, path, value) {
1658
+ const keys = path.split('.');
1659
+ const lastKey = keys.pop();
1660
+ const target = keys.reduce((current, key) => {
1661
+ if (!(key in current)) current[key] = {};
1662
+ return current[key];
1663
+ }, obj);
1664
+ target[lastKey] = value;
1665
+ }
1666
+
1667
+ /**
1668
+ * Delete nested key from object using dot notation
1669
+ * @param {Object} obj - Object to delete from
1670
+ * @param {string} path - Dot-separated path
1671
+ */
1672
+ function deleteNestedValue(obj, path) {
1673
+ const keys = path.split('.');
1674
+ const lastKey = keys.pop();
1675
+ const target = keys.reduce((current, key) => current?.[key], obj);
1676
+ if (target && lastKey in target) {
1677
+ delete target[lastKey];
1678
+ }
1679
+ }
1680
+
1681
+ /**
1682
+ * Parse value string to appropriate type
1683
+ * @param {string} value - Value string
1684
+ * @returns {*} Parsed value
1685
+ */
1686
+ function parseConfigValue(value) {
1687
+ // Boolean
1688
+ if (value === 'true') return true;
1689
+ if (value === 'false') return false;
1690
+
1691
+ // Number
1692
+ if (/^\d+$/.test(value)) return parseInt(value, 10);
1693
+ if (/^\d+\.\d+$/.test(value)) return parseFloat(value);
1694
+
1695
+ // String (arrays should be edited directly in workflow.yaml)
1696
+ return value;
1697
+ }
1698
+
1699
+ /**
1700
+ * Read workflow.yaml config
1701
+ * @param {string} cwd - Project directory
1702
+ * @returns {Object|null} Config object or null
1703
+ */
1704
+ export function readWorkflowConfig(cwd = process.cwd()) {
1705
+ const workflowPath = join(cwd, '.omgkit', 'workflow.yaml');
1706
+ if (!existsSync(workflowPath)) return null;
1707
+
1708
+ try {
1709
+ const content = readFileSync(workflowPath, 'utf8');
1710
+ return parseSimpleYaml(content);
1711
+ } catch (e) {
1712
+ return null;
1713
+ }
1714
+ }
1715
+
1716
+ /**
1717
+ * Write workflow.yaml config
1718
+ * @param {Object} config - Config object
1719
+ * @param {string} cwd - Project directory
1720
+ */
1721
+ function writeWorkflowConfig(config, cwd = process.cwd()) {
1722
+ const workflowPath = join(cwd, '.omgkit', 'workflow.yaml');
1723
+ const yaml = toSimpleYaml(config);
1724
+ writeFileSync(workflowPath, yaml);
1725
+ }
1726
+
1727
+ /**
1728
+ * Get a config value from workflow.yaml
1729
+ * @param {string} key - Dot-separated key (e.g., 'testing.enforcement.level')
1730
+ * @param {Object} options - Options
1731
+ * @returns {Object} Result with success and value
1732
+ */
1733
+ export function getConfig(key, options = {}) {
1734
+ const { cwd = process.cwd(), silent = false } = options;
1735
+
1736
+ const omgkitDir = join(cwd, '.omgkit');
1737
+ if (!existsSync(omgkitDir)) {
1738
+ if (!silent) log.error('Not an OMGKIT project. Run: omgkit init');
1739
+ return { success: false, error: 'NOT_INITIALIZED' };
1740
+ }
1741
+
1742
+ const config = readWorkflowConfig(cwd);
1743
+ if (!config) {
1744
+ if (!silent) log.error('workflow.yaml not found');
1745
+ return { success: false, error: 'NO_WORKFLOW' };
1746
+ }
1747
+
1748
+ const value = getNestedValue(config, key);
1749
+
1750
+ if (value === undefined) {
1751
+ if (!silent) log.warn(`Key '${key}' not found`);
1752
+ return { success: false, error: 'KEY_NOT_FOUND' };
1753
+ }
1754
+
1755
+ if (!silent) {
1756
+ if (typeof value === 'object') {
1757
+ console.log(`${COLORS.cyan}${key}:${COLORS.reset}`);
1758
+ console.log(toSimpleYaml(value).split('\n').map(l => ' ' + l).join('\n'));
1759
+ } else {
1760
+ console.log(`${COLORS.cyan}${key}${COLORS.reset} = ${COLORS.green}${value}${COLORS.reset}`);
1761
+ }
1762
+ }
1763
+
1764
+ return { success: true, value };
1765
+ }
1766
+
1767
+ /**
1768
+ * Set a config value in workflow.yaml
1769
+ * @param {string} key - Dot-separated key
1770
+ * @param {string} value - Value to set
1771
+ * @param {Object} options - Options
1772
+ * @returns {Object} Result
1773
+ */
1774
+ export function setConfig(key, value, options = {}) {
1775
+ const { cwd = process.cwd(), silent = false } = options;
1776
+
1777
+ const omgkitDir = join(cwd, '.omgkit');
1778
+ if (!existsSync(omgkitDir)) {
1779
+ if (!silent) log.error('Not an OMGKIT project. Run: omgkit init');
1780
+ return { success: false, error: 'NOT_INITIALIZED' };
1781
+ }
1782
+
1783
+ let config = readWorkflowConfig(cwd);
1784
+ if (!config) {
1785
+ if (!silent) log.error('workflow.yaml not found. Run: omgkit project:upgrade');
1786
+ return { success: false, error: 'NO_WORKFLOW' };
1787
+ }
1788
+
1789
+ const parsedValue = parseConfigValue(value);
1790
+ const oldValue = getNestedValue(config, key);
1791
+
1792
+ setNestedValue(config, key, parsedValue);
1793
+ writeWorkflowConfig(config, cwd);
1794
+
1795
+ if (!silent) {
1796
+ if (oldValue !== undefined) {
1797
+ log.success(`Updated: ${key}`);
1798
+ console.log(` ${COLORS.red}${oldValue}${COLORS.reset} → ${COLORS.green}${parsedValue}${COLORS.reset}`);
1799
+ } else {
1800
+ log.success(`Set: ${key} = ${parsedValue}`);
1801
+ }
1802
+ }
1803
+
1804
+ return { success: true, key, value: parsedValue, oldValue };
1805
+ }
1806
+
1807
+ /**
1808
+ * List all config from workflow.yaml
1809
+ * @param {Object} options - Options
1810
+ * @returns {Object} Result with config
1811
+ */
1812
+ export function listConfig(options = {}) {
1813
+ const { cwd = process.cwd(), silent = false, section = null } = options;
1814
+
1815
+ const omgkitDir = join(cwd, '.omgkit');
1816
+ if (!existsSync(omgkitDir)) {
1817
+ if (!silent) log.error('Not an OMGKIT project. Run: omgkit init');
1818
+ return { success: false, error: 'NOT_INITIALIZED' };
1819
+ }
1820
+
1821
+ const config = readWorkflowConfig(cwd);
1822
+ if (!config) {
1823
+ if (!silent) log.error('workflow.yaml not found');
1824
+ return { success: false, error: 'NO_WORKFLOW' };
1825
+ }
1826
+
1827
+ const displayConfig = section ? { [section]: getNestedValue(config, section) } : config;
1828
+
1829
+ if (!silent) {
1830
+ console.log(BANNER);
1831
+ console.log(`${COLORS.bright}Workflow Configuration${COLORS.reset}\n`);
1832
+ console.log(toSimpleYaml(displayConfig));
1833
+ }
1834
+
1835
+ return { success: true, config: displayConfig };
1836
+ }
1837
+
1838
+ /**
1839
+ * Reset a config key to default value
1840
+ * @param {string} key - Dot-separated key to reset
1841
+ * @param {Object} options - Options
1842
+ * @returns {Object} Result
1843
+ */
1844
+ export function resetConfig(key, options = {}) {
1845
+ const { cwd = process.cwd(), silent = false } = options;
1846
+
1847
+ const omgkitDir = join(cwd, '.omgkit');
1848
+ if (!existsSync(omgkitDir)) {
1849
+ if (!silent) log.error('Not an OMGKIT project. Run: omgkit init');
1850
+ return { success: false, error: 'NOT_INITIALIZED' };
1851
+ }
1852
+
1853
+ // Load default template
1854
+ const templatePath = join(getPackageRoot(), 'templates', 'omgkit', 'workflow.yaml');
1855
+ if (!existsSync(templatePath)) {
1856
+ if (!silent) log.error('Default template not found');
1857
+ return { success: false, error: 'NO_TEMPLATE' };
1858
+ }
1859
+
1860
+ const templateContent = readFileSync(templatePath, 'utf8');
1861
+ const templateConfig = parseSimpleYaml(templateContent);
1862
+ const defaultValue = getNestedValue(templateConfig, key);
1863
+
1864
+ if (defaultValue === undefined) {
1865
+ if (!silent) log.error(`Key '${key}' not found in default config`);
1866
+ return { success: false, error: 'KEY_NOT_IN_DEFAULT' };
1867
+ }
1868
+
1869
+ let config = readWorkflowConfig(cwd);
1870
+ if (!config) {
1871
+ if (!silent) log.error('workflow.yaml not found');
1872
+ return { success: false, error: 'NO_WORKFLOW' };
1873
+ }
1874
+
1875
+ const oldValue = getNestedValue(config, key);
1876
+ setNestedValue(config, key, defaultValue);
1877
+ writeWorkflowConfig(config, cwd);
1878
+
1879
+ if (!silent) {
1880
+ log.success(`Reset: ${key}`);
1881
+ console.log(` ${COLORS.red}${JSON.stringify(oldValue)}${COLORS.reset} → ${COLORS.green}${JSON.stringify(defaultValue)}${COLORS.reset}`);
1882
+ }
1883
+
1884
+ return { success: true, key, value: defaultValue, oldValue };
1885
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omgkit",
3
- "version": "2.25.0",
3
+ "version": "2.26.0",
4
4
  "description": "Omega-Level Development Kit - AI Team System for Claude Code. 41 agents, 160 commands, 161 skills, 69 workflows.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -7,14 +7,18 @@ skills:
7
7
  - methodology/executing-plans
8
8
  - methodology/verification-before-completion
9
9
  - methodology/test-driven-development
10
+ - methodology/test-enforcement
10
11
  - languages/typescript
11
12
  - languages/javascript
12
13
  commands:
13
14
  - /dev:feature
15
+ - /dev:feature-tested
14
16
  - /dev:fix
15
17
  - /dev:fix-fast
16
18
  - /dev:fix-hard
17
19
  - /dev:tdd
20
+ - /quality:refactor
21
+ - /quality:optimize
18
22
  ---
19
23
 
20
24
  # ⚡ Fullstack Developer Agent
@@ -432,9 +436,45 @@ Before marking task complete:
432
436
 
433
437
  ---
434
438
 
439
+ ## Test Enforcement
440
+
441
+ ### Configuration
442
+
443
+ Testing is enforced based on `.omgkit/workflow.yaml`:
444
+
445
+ ```yaml
446
+ testing:
447
+ enabled: true
448
+ enforcement:
449
+ level: standard # soft | standard | strict
450
+ ```
451
+
452
+ ### Command Options
453
+
454
+ | Option | Description | Example |
455
+ |--------|-------------|---------|
456
+ | `--no-test` | Skip test enforcement | `/dev:fix "typo" --no-test` |
457
+ | `--test-level <level>` | Override enforcement level | `/dev:feature "auth" --test-level strict` |
458
+ | `--coverage <percent>` | Override coverage minimum | `/dev:feature "api" --coverage 95` |
459
+
460
+ ### Behavior by Command
461
+
462
+ | Command | Default | Testing Behavior |
463
+ |---------|---------|------------------|
464
+ | `/dev:feature` | Tests enabled | Regression + unit tests |
465
+ | `/dev:feature-tested` | Tests enforced | Full test suite auto-generated |
466
+ | `/dev:fix` | Tests enabled | Regression test required |
467
+ | `/dev:fix-fast` | Tests disabled | Optional with `--with-test` |
468
+ | `/dev:fix-hard` | Tests enabled | Comprehensive testing |
469
+ | `/dev:tdd` | Tests enforced | Test-first development |
470
+
435
471
  ## Commands
436
472
 
437
- - `/feature [description]` - Implement a feature from plan
438
- - `/fix [issue]` - Fix a bug
439
- - `/refactor [target]` - Refactor code
440
- - `/test [file]` - Add tests to file
473
+ - `/dev:feature [description]` - Implement a feature
474
+ - `/dev:feature-tested [desc]` - Feature with auto-generated tests
475
+ - `/dev:fix [issue]` - Fix a bug with regression test
476
+ - `/dev:fix-fast [issue]` - Quick fix (tests optional)
477
+ - `/dev:fix-hard [issue]` - Deep investigation with tests
478
+ - `/dev:tdd [feature]` - Test-driven development
479
+ - `/quality:refactor [target]` - Refactor with test verification
480
+ - `/quality:optimize [target]` - Optimize with test verification
@@ -259,11 +259,14 @@ Generates:
259
259
 
260
260
  ### Configuration Loading
261
261
 
262
- At sprint start, read `.omgkit/workflow.yaml` for testing configuration:
262
+ At sprint start, read `.omgkit/workflow.yaml` for testing configuration.
263
+
264
+ **Via workflow.yaml:**
263
265
 
264
266
  ```yaml
265
267
  # .omgkit/workflow.yaml
266
268
  testing:
269
+ enabled: true
267
270
  enforcement:
268
271
  level: standard # soft | standard | strict
269
272
  auto_generate_tasks: true
@@ -282,6 +285,27 @@ testing:
282
285
  on_coverage_below_minimum: true
283
286
  ```
284
287
 
288
+ **Via CLI:**
289
+
290
+ ```bash
291
+ # Set enforcement level
292
+ omgkit config set testing.enforcement.level strict
293
+
294
+ # Enable/disable auto-generation
295
+ omgkit config set testing.auto_generate_tasks true
296
+
297
+ # View testing config
298
+ omgkit config list testing
299
+ ```
300
+
301
+ **Via Command Options:**
302
+
303
+ | Option | Description | Example |
304
+ |--------|-------------|---------|
305
+ | `--no-test` | Skip test enforcement | `/sprint:team-run --no-test` |
306
+ | `--test-level <level>` | Override enforcement level | `/sprint:team-run --test-level strict` |
307
+ | `--mode <mode>` | Autonomy mode | `/sprint:team-run --mode full-auto` |
308
+
285
309
  ### Auto Test Task Generation
286
310
 
287
311
  When `auto_generate_tasks: true`, automatically create test tasks:
@@ -5,14 +5,20 @@ tools: Read, Write, Bash, Glob, Grep, Task
5
5
  model: inherit
6
6
  skills:
7
7
  - methodology/test-driven-development
8
+ - methodology/test-enforcement
9
+ - methodology/test-task-generation
8
10
  - methodology/testing-anti-patterns
9
11
  - testing/vitest
10
12
  - testing/playwright
11
13
  - testing/pytest
12
14
  commands:
13
15
  - /dev:test
16
+ - /dev:test-write
14
17
  - /dev:tdd
15
18
  - /dev:fix-test
19
+ - /dev:feature-tested
20
+ - /quality:verify-done
21
+ - /quality:coverage-check
16
22
  ---
17
23
 
18
24
  # 🧪 Tester Agent
@@ -577,9 +583,44 @@ Before marking testing complete:
577
583
 
578
584
  ---
579
585
 
586
+ ## Test Enforcement Integration
587
+
588
+ ### Configuration
589
+
590
+ Read testing configuration from `.omgkit/workflow.yaml`:
591
+
592
+ ```yaml
593
+ testing:
594
+ enabled: true
595
+ enforcement:
596
+ level: standard # soft | standard | strict
597
+ coverage_gates:
598
+ unit:
599
+ minimum: 80
600
+ target: 90
601
+ ```
602
+
603
+ ### Command Options
604
+
605
+ | Option | Description | Example |
606
+ |--------|-------------|---------|
607
+ | `--coverage <percent>` | Override coverage minimum | `/dev:test "src/" --coverage 90` |
608
+ | `--test-types <types>` | Specify test types | `/dev:test "api/" --test-types unit,integration` |
609
+ | `--watch` | Run in watch mode | `/dev:test "src/" --watch` |
610
+ | `--fail-under <percent>` | Fail if coverage below | `/dev:test "lib/" --fail-under 80` |
611
+
612
+ ### Enforcement Behavior
613
+
614
+ When enforcement is enabled:
615
+ - Block task completion if tests fail
616
+ - Block if coverage below minimum
617
+ - Warn about missing test types
618
+
580
619
  ## Commands
581
620
 
582
- - `/test [target]` - Run tests for target
583
- - `/test:coverage` - Run with coverage report
584
- - `/test:watch` - Run in watch mode
585
- - `/tdd [feature]` - Test-driven development workflow
621
+ - `/dev:test [target]` - Run tests for target
622
+ - `/dev:test-write [file]` - Write comprehensive tests
623
+ - `/dev:tdd [feature]` - Test-driven development workflow
624
+ - `/dev:feature-tested [desc]` - Feature with auto-generated tests
625
+ - `/quality:verify-done` - Verify test requirements
626
+ - `/quality:coverage-check` - Check coverage gates
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Feature Tested
3
- description: Create a feature with automatically generated test tasks. Ensures every implementation task has corresponding test coverage before the feature can be marked complete.
3
+ description: Create a feature with automatically generated test tasks and strict test enforcement
4
4
  category: dev
5
5
  related_skills:
6
6
  - methodology/test-task-generation
@@ -12,6 +12,10 @@ related_commands:
12
12
  - /dev:feature
13
13
  - /dev:test
14
14
  allowed-tools: Task, Read, Write, Bash, Grep, Glob
15
+ argument-hint: <feature-description> [--coverage PERCENT] [--test-types TYPES] [--tdd] [--strict]
16
+ testing:
17
+ default: true
18
+ configurable: false
15
19
  ---
16
20
 
17
21
  # /dev:feature-tested
@@ -26,7 +30,11 @@ Build a feature with automatically generated test tasks. This command ensures co
26
30
  /dev:feature-tested "Payment processing" --test-types unit,integration,e2e
27
31
  ```
28
32
 
29
- ## Options
33
+ ## Testing Options
34
+
35
+ This command **always enforces testing** (testing cannot be disabled). This is a strict version of `/dev:feature`.
36
+
37
+ ### Options
30
38
 
31
39
  | Option | Description | Default |
32
40
  |--------|-------------|---------|
@@ -35,6 +43,29 @@ Build a feature with automatically generated test tasks. This command ensures co
35
43
  | `--tdd` | Use TDD approach (tests first) | false |
36
44
  | `--strict` | Strict enforcement (no overrides) | false |
37
45
 
46
+ ### Enforcement Behavior
47
+
48
+ Unlike `/dev:feature`, this command:
49
+ - **Cannot skip tests** (no `--no-test` option)
50
+ - **Blocks completion** until all test tasks pass
51
+ - **Auto-generates test tasks** for every implementation task
52
+
53
+ ### Configuration
54
+
55
+ Configure via `.omgkit/workflow.yaml`:
56
+
57
+ ```yaml
58
+ testing:
59
+ enabled: true
60
+ enforcement:
61
+ level: strict # Recommended for feature-tested
62
+ auto_generate_tasks: true
63
+ coverage_gates:
64
+ unit:
65
+ minimum: 80
66
+ target: 90
67
+ ```
68
+
38
69
  ## How It Works
39
70
 
40
71
  ### 1. Feature Analysis