@tanagram/cli 0.1.5 → 0.1.7
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 +1 -1
- package/bin/tanagram +0 -0
- package/checker/llm_integration.go +5 -15
- package/checker/matcher.go +38 -3
- package/commands/run.go +1 -1
- package/commands/sync.go +3 -3
- package/main.go +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ tanagram help
|
|
|
99
99
|
|
|
100
100
|
## How It Works
|
|
101
101
|
|
|
102
|
-
1. **Finds instruction files** - Searches for `AGENTS.md`, `POLICIES.md` in your git repository
|
|
102
|
+
1. **Finds instruction files** - Searches for `AGENTS.md`, `POLICIES.md`, `CLAUDE.md` in your git repository
|
|
103
103
|
2. **Checks cache** - Loads cached policies and MD5 hashes from `.tanagram/`
|
|
104
104
|
3. **Auto-syncs** - Detects file changes via MD5 and automatically resyncs if needed
|
|
105
105
|
4. **LLM extraction** - Uses Claude AI to extract ALL policies from instruction files
|
package/bin/tanagram
CHANGED
|
Binary file
|
|
@@ -81,7 +81,7 @@ func checkFileWithLLM(ctx context.Context, file string, changes []git.ChangedLin
|
|
|
81
81
|
File: file,
|
|
82
82
|
LineNumber: firstLine.LineNumber,
|
|
83
83
|
PolicyName: policy.Name,
|
|
84
|
-
Message:
|
|
84
|
+
Message: check.Reason,
|
|
85
85
|
Code: formatChangesForDisplay(changes),
|
|
86
86
|
})
|
|
87
87
|
}
|
|
@@ -100,20 +100,10 @@ func formatChangesForLLM(changes []git.ChangedLine) string {
|
|
|
100
100
|
|
|
101
101
|
// formatChangesForDisplay creates a compact display of changed lines
|
|
102
102
|
func formatChangesForDisplay(changes []git.ChangedLine) string {
|
|
103
|
-
|
|
103
|
+
// Just return the first line's content, trimmed
|
|
104
|
+
// Line numbers will be shown in the formatted output
|
|
105
|
+
if len(changes) > 0 {
|
|
104
106
|
return strings.TrimSpace(changes[0].Content)
|
|
105
107
|
}
|
|
106
|
-
|
|
107
|
-
var builder strings.Builder
|
|
108
|
-
for i, change := range changes {
|
|
109
|
-
if i > 0 {
|
|
110
|
-
builder.WriteString("\n")
|
|
111
|
-
}
|
|
112
|
-
builder.WriteString(fmt.Sprintf("L%d: %s", change.LineNumber, strings.TrimSpace(change.Content)))
|
|
113
|
-
if i >= 2 { // Limit to first 3 lines
|
|
114
|
-
builder.WriteString("\n...")
|
|
115
|
-
break
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return builder.String()
|
|
108
|
+
return ""
|
|
119
109
|
}
|
package/checker/matcher.go
CHANGED
|
@@ -3,6 +3,7 @@ package checker
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
5
|
"fmt"
|
|
6
|
+
"sort"
|
|
6
7
|
"strings"
|
|
7
8
|
|
|
8
9
|
"github.com/tanagram/cli/git"
|
|
@@ -44,12 +45,46 @@ func FormatViolations(result *CheckResult) string {
|
|
|
44
45
|
return "✓ No policy violations found"
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
// ANSI color codes
|
|
49
|
+
const (
|
|
50
|
+
colorReset = "\033[0m"
|
|
51
|
+
colorGray = "\033[90m"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// Group violations by file
|
|
55
|
+
violationsByFile := make(map[string][]Violation)
|
|
56
|
+
for _, v := range result.Violations {
|
|
57
|
+
violationsByFile[v.File] = append(violationsByFile[v.File], v)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Sort files for consistent output
|
|
61
|
+
files := make([]string, 0, len(violationsByFile))
|
|
62
|
+
for file := range violationsByFile {
|
|
63
|
+
files = append(files, file)
|
|
64
|
+
}
|
|
65
|
+
sort.Strings(files)
|
|
66
|
+
|
|
47
67
|
var output strings.Builder
|
|
48
68
|
output.WriteString(fmt.Sprintf("✗ Found %d policy violation(s):\n\n", len(result.Violations)))
|
|
49
69
|
|
|
50
|
-
for _,
|
|
51
|
-
|
|
52
|
-
|
|
70
|
+
for _, file := range files {
|
|
71
|
+
violations := violationsByFile[file]
|
|
72
|
+
|
|
73
|
+
// Sort violations by line number
|
|
74
|
+
sort.Slice(violations, func(i, j int) bool {
|
|
75
|
+
return violations[i].LineNumber < violations[j].LineNumber
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
output.WriteString(fmt.Sprintf("- %s\n\n", file))
|
|
79
|
+
|
|
80
|
+
for _, v := range violations {
|
|
81
|
+
// Print the code line in gray
|
|
82
|
+
output.WriteString(fmt.Sprintf(" %s%d: %s%s\n", colorGray, v.LineNumber, v.Code, colorReset))
|
|
83
|
+
|
|
84
|
+
// Print the violation message indented with arrow
|
|
85
|
+
output.WriteString(fmt.Sprintf(" ^ %s\n", v.Message))
|
|
86
|
+
}
|
|
87
|
+
output.WriteString("\n")
|
|
53
88
|
}
|
|
54
89
|
|
|
55
90
|
return output.String()
|
package/commands/run.go
CHANGED
|
@@ -47,7 +47,7 @@ func Run() error {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
if len(instructionFiles) == 0 {
|
|
50
|
-
return fmt.Errorf("no instruction files found (looking for AGENTS.md, POLICIES.md,
|
|
50
|
+
return fmt.Errorf("no instruction files found (looking for AGENTS.md, POLICIES.md, CLAUDE.md)")
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Load cache
|
package/commands/sync.go
CHANGED
|
@@ -28,7 +28,7 @@ func Sync() error {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if len(instructionFiles) == 0 {
|
|
31
|
-
return fmt.Errorf("no instruction files found (looking for AGENTS.md, POLICIES.md,
|
|
31
|
+
return fmt.Errorf("no instruction files found (looking for AGENTS.md, POLICIES.md, CLAUDE.md)")
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
fmt.Printf("Found %d instruction file(s)\n", len(instructionFiles))
|
|
@@ -137,12 +137,12 @@ func Sync() error {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
// FindInstructionFiles searches for instruction files in the git repository
|
|
140
|
-
// Looks for: AGENTS.md, POLICIES.md,
|
|
140
|
+
// Looks for: AGENTS.md, POLICIES.md, CLAUDE.md
|
|
141
141
|
func FindInstructionFiles(gitRoot string) ([]string, error) {
|
|
142
142
|
var files []string
|
|
143
143
|
|
|
144
144
|
// Common instruction file names to look for
|
|
145
|
-
commonNames := []string{"AGENTS.md", "POLICIES.md"}
|
|
145
|
+
commonNames := []string{"AGENTS.md", "POLICIES.md", "CLAUDE.md"}
|
|
146
146
|
|
|
147
147
|
// Directories to skip
|
|
148
148
|
skipDirs := map[string]bool{
|
package/main.go
CHANGED
|
@@ -56,7 +56,7 @@ EXAMPLES:
|
|
|
56
56
|
tanagram list # View all cached policies
|
|
57
57
|
|
|
58
58
|
INSTRUCTION FILES:
|
|
59
|
-
Tanagram looks for instruction files like AGENTS.md or
|
|
59
|
+
Tanagram looks for instruction files like AGENTS.md, POLICIES.md, or CLAUDE.md
|
|
60
60
|
in your git repository. Policies are cached and automatically resynced
|
|
61
61
|
when files change.
|
|
62
62
|
`
|