teamspec 4.1.0 → 4.2.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.
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  /**
4
4
  * TeamSpec Init CLI
package/lib/linter.js CHANGED
@@ -472,9 +472,17 @@ function checkStoryDelta(filePath, result) {
472
472
 
473
473
  /**
474
474
  * TS-NAMING-*: Artifact naming conventions
475
+ * Allows README.md and index files in artifact folders
475
476
  */
476
477
  function checkArtifactNaming(filePath, artifactType, result, workspaceDir = null) {
477
478
  const filename = path.basename(filePath);
479
+
480
+ // Skip documentation and index files - these are allowed in any artifact folder
481
+ const allowedFiles = ['README.md', 'readme.md', 'index.md', '.gitkeep'];
482
+ if (allowedFiles.includes(filename)) {
483
+ return;
484
+ }
485
+
478
486
  const patterns = getNamingPatterns(workspaceDir);
479
487
  const pattern = patterns[artifactType];
480
488
 
@@ -672,7 +680,7 @@ function lintProduct(workspaceDir, productId, result, options) {
672
680
  const featuresDir = path.join(productDir, 'features');
673
681
  if (fs.existsSync(featuresDir)) {
674
682
  const features = fs.readdirSync(featuresDir)
675
- .filter(f => f.endsWith('.md') && f !== 'features-index.md' && f !== 'story-ledger.md');
683
+ .filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme') && f !== 'features-index.md' && f !== 'story-ledger.md');
676
684
 
677
685
  for (const feature of features) {
678
686
  checkArtifactNaming(path.join(featuresDir, feature), 'feature', result, workspaceDir);
@@ -682,7 +690,7 @@ function lintProduct(workspaceDir, productId, result, options) {
682
690
  // Lint regression tests naming
683
691
  const rtDir = path.join(productDir, 'qa', 'regression-tests');
684
692
  if (fs.existsSync(rtDir)) {
685
- const rtFiles = fs.readdirSync(rtDir).filter(f => f.endsWith('.md'));
693
+ const rtFiles = fs.readdirSync(rtDir).filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme'));
686
694
  for (const rt of rtFiles) {
687
695
  checkArtifactNaming(path.join(rtDir, rt), 'product-regression-test', result, workspaceDir);
688
696
  }
@@ -718,7 +726,7 @@ function lintProject(workspaceDir, projectId, result, options) {
718
726
  // Lint Feature-Increments
719
727
  const fiDir = path.join(projectDir, 'feature-increments');
720
728
  if (fs.existsSync(fiDir)) {
721
- const fiFiles = fs.readdirSync(fiDir).filter(f => f.endsWith('.md') && f !== 'increments-index.md');
729
+ const fiFiles = fs.readdirSync(fiDir).filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme') && f !== 'increments-index.md');
722
730
 
723
731
  for (const fi of fiFiles) {
724
732
  const fiPath = path.join(fiDir, fi);
@@ -758,7 +766,7 @@ function lintProject(workspaceDir, projectId, result, options) {
758
766
  const epicsDir = path.join(projectDir, 'epics');
759
767
  if (fs.existsSync(epicsDir)) {
760
768
  const epics = fs.readdirSync(epicsDir)
761
- .filter(f => f.endsWith('.md') && f !== 'epics-index.md');
769
+ .filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme') && f !== 'epics-index.md');
762
770
 
763
771
  for (const epic of epics) {
764
772
  const epicPath = path.join(epicsDir, epic);
@@ -828,7 +836,7 @@ function lintProject(workspaceDir, projectId, result, options) {
828
836
  // Lint test cases naming
829
837
  const tcDir = path.join(projectDir, 'qa', 'test-cases');
830
838
  if (fs.existsSync(tcDir)) {
831
- const tcFiles = fs.readdirSync(tcDir).filter(f => f.endsWith('.md'));
839
+ const tcFiles = fs.readdirSync(tcDir).filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme'));
832
840
  for (const tc of tcFiles) {
833
841
  checkArtifactNaming(path.join(tcDir, tc), 'project-test-case', result, workspaceDir);
834
842
  }
@@ -837,7 +845,7 @@ function lintProject(workspaceDir, projectId, result, options) {
837
845
  // Lint bug reports naming
838
846
  const bugDir = path.join(projectDir, 'qa', 'bug-reports');
839
847
  if (fs.existsSync(bugDir)) {
840
- const bugFiles = fs.readdirSync(bugDir).filter(f => f.endsWith('.md'));
848
+ const bugFiles = fs.readdirSync(bugDir).filter(f => f.endsWith('.md') && !f.toLowerCase().startsWith('readme'));
841
849
  for (const bug of bugFiles) {
842
850
  checkArtifactNaming(path.join(bugDir, bug), 'bug-report', result, workspaceDir);
843
851
  }
@@ -142,7 +142,7 @@ function generatePromptFile(command, outputDir, roles) {
142
142
 
143
143
  // Build clean, minimal prompt content
144
144
  const content = `---
145
- name: "ts:${filename.replace('.prompt.md', '').replace(/-/g, ' ')}"
145
+ name: "${commandName}"
146
146
  description: "${command.purpose || `${role.name} command`}"
147
147
  ---
148
148
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teamspec",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "CLI tool to bootstrap TeamSpec 4.0 Product-Canon operating model in any repository",
5
5
  "main": "lib/cli.js",
6
6
  "bin": {