diff --git a/changelog.md b/changelog.md
index d8f6b52..1369934 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,13 @@
 # Changelog
 
+## 2025-05-23 - 1.10.1 - fix(tstest)
+Improve file range filtering and summary logging by skipping test files outside the specified range and reporting them in the final summary.
+
+- Introduce runSingleTestOrSkip to check file index against startFrom/stopAt values.
+- Log skipped files with appropriate messages and add them to the summary.
+- Update the logger to include total skipped files in the test summary.
+- Add permission settings in .claude/settings.local.json to support new operations.
+
 ## 2025-05-23 - 1.10.0 - feat(cli)
 Add --startFrom and --stopAt options to filter test files by range
 
diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts
index d1459a9..faa8bfc 100644
--- a/ts/00_commitinfo_data.ts
+++ b/ts/00_commitinfo_data.ts
@@ -3,6 +3,6 @@
  */
 export const commitinfo = {
   name: '@git.zone/tstest',
-  version: '1.10.0',
+  version: '1.10.1',
   description: 'a test utility to run tests that match test/**/*.ts'
 }
diff --git a/ts/tstest.classes.tap.combinator.ts b/ts/tstest.classes.tap.combinator.ts
index d4514b5..d3d33ca 100644
--- a/ts/tstest.classes.tap.combinator.ts
+++ b/ts/tstest.classes.tap.combinator.ts
@@ -10,6 +10,7 @@ import { TsTestLogger } from './tstest.logging.js';
 
 export class TapCombinator {
   tapParserStore: TapParser[] = [];
+  skippedFiles: string[] = [];
   private logger: TsTestLogger;
   
   constructor(logger: TsTestLogger) {
@@ -19,10 +20,14 @@ export class TapCombinator {
   addTapParser(tapParserArg: TapParser) {
     this.tapParserStore.push(tapParserArg);
   }
+  
+  addSkippedFile(filename: string) {
+    this.skippedFiles.push(filename);
+  }
 
   evaluate() {
-    // Call the logger's summary method
-    this.logger.summary();
+    // Call the logger's summary method with skipped files
+    this.logger.summary(this.skippedFiles);
     
     // Check for failures
     let failGlobal = false;
diff --git a/ts/tstest.classes.tstest.ts b/ts/tstest.classes.tstest.ts
index b0221e6..0628ee0 100644
--- a/ts/tstest.classes.tstest.ts
+++ b/ts/tstest.classes.tstest.ts
@@ -39,26 +39,9 @@ export class TsTest {
 
   async run() {
     const testGroups = await this.testDir.getTestFileGroups();
-    let allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
+    const allFiles = [...testGroups.serial, ...Object.values(testGroups.parallelGroups).flat()];
     
-    // Apply file range filtering if specified
-    if (this.startFromFile !== null || this.stopAtFile !== null) {
-      const startIndex = this.startFromFile ? this.startFromFile - 1 : 0; // Convert to 0-based index
-      const endIndex = this.stopAtFile ? this.stopAtFile : allFiles.length;
-      allFiles = allFiles.slice(startIndex, endIndex);
-      
-      // Filter the serial and parallel groups based on remaining files
-      testGroups.serial = testGroups.serial.filter(file => allFiles.includes(file));
-      Object.keys(testGroups.parallelGroups).forEach(groupName => {
-        testGroups.parallelGroups[groupName] = testGroups.parallelGroups[groupName].filter(file => allFiles.includes(file));
-        // Remove empty groups
-        if (testGroups.parallelGroups[groupName].length === 0) {
-          delete testGroups.parallelGroups[groupName];
-        }
-      });
-    }
-    
-    // Log test discovery
+    // Log test discovery - always show full count
     this.logger.testDiscovery(
       allFiles.length, 
       this.testDir.testPath,
@@ -71,7 +54,7 @@ export class TsTest {
     // Execute serial tests first
     for (const fileNameArg of testGroups.serial) {
       fileIndex++;
-      await this.runSingleTest(fileNameArg, fileIndex, allFiles.length, tapCombinator);
+      await this.runSingleTestOrSkip(fileNameArg, fileIndex, allFiles.length, tapCombinator);
     }
     
     // Execute parallel groups sequentially
@@ -85,7 +68,7 @@ export class TsTest {
         // Run all tests in this group in parallel
         const parallelPromises = groupFiles.map(async (fileNameArg) => {
           fileIndex++;
-          return this.runSingleTest(fileNameArg, fileIndex, allFiles.length, tapCombinator);
+          return this.runSingleTestOrSkip(fileNameArg, fileIndex, allFiles.length, tapCombinator);
         });
         
         await Promise.all(parallelPromises);
@@ -96,6 +79,24 @@ export class TsTest {
     tapCombinator.evaluate();
   }
   
+  private async runSingleTestOrSkip(fileNameArg: string, fileIndex: number, totalFiles: number, tapCombinator: TapCombinator) {
+    // Check if this file should be skipped based on range
+    if (this.startFromFile !== null && fileIndex < this.startFromFile) {
+      this.logger.testFileSkipped(fileNameArg, fileIndex, totalFiles, `before start range (${this.startFromFile})`);
+      tapCombinator.addSkippedFile(fileNameArg);
+      return;
+    }
+    
+    if (this.stopAtFile !== null && fileIndex > this.stopAtFile) {
+      this.logger.testFileSkipped(fileNameArg, fileIndex, totalFiles, `after stop range (${this.stopAtFile})`);
+      tapCombinator.addSkippedFile(fileNameArg);
+      return;
+    }
+    
+    // File is in range, run it
+    await this.runSingleTest(fileNameArg, fileIndex, totalFiles, tapCombinator);
+  }
+  
   private async runSingleTest(fileNameArg: string, fileIndex: number, totalFiles: number, tapCombinator: TapCombinator) {
     switch (true) {
       case process.env.CI && fileNameArg.includes('.nonci.'):
diff --git a/ts/tstest.logging.ts b/ts/tstest.logging.ts
index c0af145..d05a71c 100644
--- a/ts/tstest.logging.ts
+++ b/ts/tstest.logging.ts
@@ -30,8 +30,10 @@ export interface TestSummary {
   totalTests: number;
   totalPassed: number;
   totalFailed: number;
+  totalSkipped: number;
   totalDuration: number;
   fileResults: TestFileResult[];
+  skippedFiles: string[];
 }
 
 export class TsTestLogger {
@@ -282,6 +284,19 @@ export class TsTestLogger {
     }
   }
   
+  // Skipped test file
+  testFileSkipped(filename: string, index: number, total: number, reason: string) {
+    if (this.options.json) {
+      this.logJson({ event: 'fileSkipped', filename, index, total, reason });
+      return;
+    }
+    
+    if (this.options.quiet) return;
+    
+    this.log(this.format(`\n⏭️  ${filename} (${index}/${total})`, 'yellow'));
+    this.log(this.format(`   Skipped: ${reason}`, 'dim'));
+  }
+  
   // Browser console
   browserConsole(message: string, level: string = 'log') {
     if (this.options.json) {
@@ -317,15 +332,17 @@ export class TsTestLogger {
   }
   
   // Final summary
-  summary() {
+  summary(skippedFiles: string[] = []) {
     const totalDuration = Date.now() - this.startTime;
     const summary: TestSummary = {
-      totalFiles: this.fileResults.length,
+      totalFiles: this.fileResults.length + skippedFiles.length,
       totalTests: this.fileResults.reduce((sum, r) => sum + r.total, 0),
       totalPassed: this.fileResults.reduce((sum, r) => sum + r.passed, 0),
       totalFailed: this.fileResults.reduce((sum, r) => sum + r.failed, 0),
+      totalSkipped: skippedFiles.length,
       totalDuration,
-      fileResults: this.fileResults
+      fileResults: this.fileResults,
+      skippedFiles
     };
     
     if (this.options.json) {
@@ -346,6 +363,9 @@ export class TsTestLogger {
     this.log(this.format(`│ Total Tests:    ${summary.totalTests.toString().padStart(14)} │`, 'white'));
     this.log(this.format(`│ Passed:         ${summary.totalPassed.toString().padStart(14)} │`, 'green'));
     this.log(this.format(`│ Failed:         ${summary.totalFailed.toString().padStart(14)} │`, summary.totalFailed > 0 ? 'red' : 'green'));
+    if (summary.totalSkipped > 0) {
+      this.log(this.format(`│ Skipped:        ${summary.totalSkipped.toString().padStart(14)} │`, 'yellow'));
+    }
     this.log(this.format(`│ Duration:       ${totalDuration.toString().padStart(14)}ms │`, 'white'));
     this.log(this.format('└────────────────────────────────┘', 'dim'));