a73x

e1d774ff

feat(scanner): tagged marker reporting, size cap, binary sniff

a73x   2026-04-29 05:46


diff --git a/internal/scanner/scanner.go b/internal/scanner/scanner.go
index 5da726c..ade0d97 100644
--- a/internal/scanner/scanner.go
+++ b/internal/scanner/scanner.go
@@ -2,6 +2,7 @@ package scanner

import (
	"bufio"
	"bytes"
	"os"
	"path/filepath"
	"regexp"
@@ -58,6 +59,32 @@ func Scan(path string) ([]Marker, error) {
		return nil, nil
	}

	const maxBytes = 1 << 20 // 1 MB

	st, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	if st.Size() > maxBytes {
		return nil, nil
	}

	// Binary sniff: read first 8 KB, look for null byte.
	sniffN := int64(8192)
	if st.Size() < sniffN {
		sniffN = st.Size()
	}
	sniff := make([]byte, sniffN)
	sf, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	n, _ := sf.Read(sniff)
	sf.Close()
	if bytes.IndexByte(sniff[:n], 0) >= 0 {
		return nil, nil
	}

	f, err := os.Open(path)
	if err != nil {
		return nil, err
diff --git a/internal/scanner/scanner_test.go b/internal/scanner/scanner_test.go
index 1b08be2..3305242 100644
--- a/internal/scanner/scanner_test.go
+++ b/internal/scanner/scanner_test.go
@@ -3,6 +3,7 @@ package scanner
import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

@@ -109,3 +110,46 @@ func TestScanMakefileByName(t *testing.T) {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanTaggedMarkerNotFiredButReported(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "foo.go", "// @claude[fw-a1b2c3d4] write a test\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 {
		t.Fatalf("want 1 marker, got %d", len(markers))
	}
	if !markers[0].Tagged || markers[0].UUID != "fw-a1b2c3d4" {
		t.Errorf("got %#v, want Tagged=true UUID=fw-a1b2c3d4", markers[0])
	}
}

func TestScanLargeFileSkipped(t *testing.T) {
	dir := t.TempDir()
	big := strings.Repeat("// filler line\n", 80_000) // > 1 MB
	path := writeFile(t, dir, "big.go", big+"// @claude do it\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if markers != nil {
		t.Fatalf("expected nil for oversized file, got %#v", markers)
	}
}

func TestScanBinaryFileSkipped(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "blob.go")
	if err := os.WriteFile(path, []byte{0x00, 0x01, 0x02, '/', '/', ' ', '@', 'c', 'l', 'a', 'u', 'd', 'e', ' ', 'x'}, 0o644); err != nil {
		t.Fatal(err)
	}
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if markers != nil {
		t.Fatalf("expected nil for binary file, got %#v", markers)
	}
}