ONNX
security
malware-detection
Vigil / source /pkg /bundle /references.go
turentomer's picture
Make published source self-contained
a2a3348 verified
Raw
History Blame Contribute Delete
11 kB
package bundle
import (
"path/filepath"
"strings"
"huggingface.co/turenlabs/Vigil/source/pkg/types"
)
// resolveReferences marks each File.Referenced by searching the SKILL.md for any
// form of its name. The indirection layer (context-loader / simple-formatter)
// is not defeated by verb omission: we match the basename, the bundle-relative
// path, ./name, markdown-link forms ([x](./payload.sh)), and code-span forms
// (`./payload.sh`), recording which surface named the file in RefSources.
//
// Symlinked siblings are matched on their OWN basename/relpath too, so a
// directive like "run ./helper" where helper -> /bin/sh resolves to the File
// entry for helper.
func resolveReferences(b *Bundle) {
for _, f := range b.Files {
referenced, sources := fileIsReferenced(b.Skill, b.AllowedTools, f)
f.Referenced = referenced
f.RefSources = sources
}
}
// fileIsReferenced reports whether the SKILL.md (body/raw/description/triggers)
// or the allowed-tools frontmatter names f, and via which surfaces. A nil skill
// yields no references (e.g. when SKILL.md failed to parse).
func fileIsReferenced(skill *types.SkillFile, allowedTools []string, f *File) (bool, []string) {
forms := referenceForms(f.RelPath)
if len(forms) == 0 {
return false, nil
}
var sources []string
seen := map[string]bool{}
addSource := func(s string) {
if !seen[s] {
seen[s] = true
sources = append(sources, s)
}
}
// allowed-tools frontmatter list (e.g. Bash(./setup.sh)).
for _, tool := range allowedTools {
if containsAnyForm(tool, forms) {
addSource("allowed-tools")
break
}
}
if skill != nil {
// Body, raw content, and description are scanned for plain, code-span, and
// markdown-link forms. RawContent is a superset of Body+frontmatter, so it
// is the primary surface; Body is checked separately so a body-only mention
// is attributed to "body" rather than the broader "frontmatter".
bodyHit := containsAnyForm(skill.Body, forms)
if bodyHit {
addSource("body")
if hasMarkdownLink(skill.Body, forms) {
addSource("markdown-link")
}
if hasCodeSpan(skill.Body, forms) {
addSource("code-span")
}
}
// Frontmatter-region mention: present in RawContent but not in Body and not
// already attributed to allowed-tools.
if !bodyHit && containsAnyForm(skill.RawContent, forms) {
addSource("frontmatter")
if hasMarkdownLink(skill.RawContent, forms) {
addSource("markdown-link")
}
if hasCodeSpan(skill.RawContent, forms) {
addSource("code-span")
}
}
if containsAnyForm(skill.Description, forms) {
addSource("body")
}
for _, t := range skill.Triggers {
if containsAnyForm(t, forms) {
addSource("frontmatter")
break
}
}
}
return len(sources) > 0, sources
}
// referenceForms returns the distinct textual surfaces under which relPath might
// be named in SKILL.md: the basename, the bundle-relative path (slash form), and
// the ./-prefixed relative path. Empty/degenerate names yield no forms so a
// stray "." cannot match everything.
func referenceForms(relPath string) []string {
rel := filepath.ToSlash(strings.TrimSpace(relPath))
if rel == "" || rel == "." || rel == ".." {
return nil
}
base := pathBase(rel)
forms := []string{}
add := func(s string) {
s = strings.TrimSpace(s)
if s == "" || s == "." {
return
}
for _, existing := range forms {
if existing == s {
return
}
}
forms = append(forms, s)
}
add(base)
add(rel)
add("./" + rel)
if base != rel {
add("./" + base)
}
return forms
}
// pathBase returns the final slash-separated segment of a slash path.
func pathBase(slashPath string) string {
if i := strings.LastIndex(slashPath, "/"); i >= 0 {
return slashPath[i+1:]
}
return slashPath
}
// containsAnyForm reports whether haystack contains any reference form as a
// whole-token match. A bare basename must not match as a substring of an
// unrelated longer word (e.g. "go" inside "category"), so we require the match
// to be bounded by a non-identifier character (or string edge) on each side.
func containsAnyForm(haystack string, forms []string) bool {
if haystack == "" {
return false
}
for _, form := range forms {
if tokenMatch(haystack, form) {
return true
}
}
return false
}
// tokenMatch reports whether needle occurs in haystack bounded by non-filename
// characters. Filename characters are letters, digits, '_', '-', '.', '/'.
// A form that itself starts with "./" or contains "/" is already specific
// enough that a plain substring check is safe and is used directly.
func tokenMatch(haystack, needle string) bool {
if needle == "" {
return false
}
// Path-ish forms are specific; substring is sufficient and avoids missing a
// match adjacent to quotes/parens.
if strings.ContainsAny(needle, "/") || strings.HasPrefix(needle, "./") {
return strings.Contains(haystack, needle)
}
from := 0
for {
idx := strings.Index(haystack[from:], needle)
if idx < 0 {
return false
}
start := from + idx
end := start + len(needle)
leftOK := start == 0 || !isFilenameByte(haystack[start-1])
rightOK := end == len(haystack) || !isFilenameByte(haystack[end])
if leftOK && rightOK {
return true
}
from = start + 1
if from >= len(haystack) {
return false
}
}
}
// isFilenameByte reports whether b can appear inside an unquoted filename token.
func isFilenameByte(b byte) bool {
switch {
case b >= 'a' && b <= 'z':
return true
case b >= 'A' && b <= 'Z':
return true
case b >= '0' && b <= '9':
return true
case b == '_' || b == '-' || b == '.' || b == '/':
return true
}
return false
}
// hasMarkdownLink reports whether any form appears inside a markdown link target
// "](...form...)". This is a heuristic surface attribution, not a strict parse.
func hasMarkdownLink(haystack string, forms []string) bool {
for _, form := range forms {
// Look for the closing "](" of a link whose target contains the form.
from := 0
for {
idx := strings.Index(haystack[from:], "](")
if idx < 0 {
break
}
start := from + idx + 2
closeIdx := strings.Index(haystack[start:], ")")
if closeIdx < 0 {
break
}
target := haystack[start : start+closeIdx]
if strings.Contains(target, form) {
return true
}
from = start + closeIdx + 1
if from >= len(haystack) {
break
}
}
}
return false
}
// hasCodeSpan reports whether any form appears inside a backtick code span.
func hasCodeSpan(haystack string, forms []string) bool {
for _, form := range forms {
from := 0
for {
open := strings.Index(haystack[from:], "`")
if open < 0 {
break
}
openAbs := from + open + 1
close := strings.Index(haystack[openAbs:], "`")
if close < 0 {
break
}
span := haystack[openAbs : openAbs+close]
if strings.Contains(span, form) {
return true
}
from = openAbs + close + 1
if from >= len(haystack) {
break
}
}
}
return false
}
// parseAllowedTools extracts the allowed-tools list from raw frontmatter. The
// existing parser does not capture this field. Supported forms:
//
// allowed-tools: [Bash, Read, Write] # inline flow list
// allowed-tools: Bash, Read # inline comma list
// allowed-tools: # block list
// - Bash(./setup.sh)
// - Read
//
// Only the frontmatter region (the first --- ... --- block) is considered.
func parseAllowedTools(rawContent string) []string {
fm := frontmatterRegion(rawContent)
if fm == "" {
return nil
}
lines := strings.Split(fm, "\n")
var tools []string
inBlock := false
for _, line := range lines {
trimmedRight := strings.TrimRight(line, " \t\r")
trimmed := strings.TrimSpace(trimmedRight)
if inBlock {
if strings.HasPrefix(trimmed, "- ") {
tools = append(tools, splitToolList(trimmed[2:])...)
continue
}
// A new top-level key ends the block.
if isTopLevelKey(trimmedRight) {
inBlock = false
// fall through to key handling below
} else if trimmed == "" {
continue
} else {
inBlock = false
}
}
key, val, ok := splitKey(trimmedRight)
if !ok {
continue
}
if !isAllowedToolsKey(key) {
continue
}
val = strings.TrimSpace(val)
switch {
case val == "":
// Block list follows on subsequent "- " lines.
inBlock = true
case strings.HasPrefix(val, "[") && strings.HasSuffix(val, "]"):
inner := strings.TrimSuffix(strings.TrimPrefix(val, "["), "]")
tools = append(tools, splitToolList(inner)...)
default:
tools = append(tools, splitToolList(val)...)
}
}
return dedupeNonEmpty(tools)
}
// frontmatterRegion returns the inner text of the leading --- ... --- block, or
// "" if there is no frontmatter.
func frontmatterRegion(rawContent string) string {
trimmed := strings.TrimLeft(rawContent, " \t\r\n")
if !strings.HasPrefix(trimmed, "---") {
return ""
}
rest := trimmed[3:]
// Skip to end of the opening delimiter line.
if nl := strings.IndexByte(rest, '\n'); nl >= 0 {
rest = rest[nl+1:]
} else {
return ""
}
idx := strings.Index(rest, "\n---")
if idx < 0 {
// Closing delimiter might be the very first line of rest.
if strings.HasPrefix(rest, "---") {
return ""
}
return ""
}
return rest[:idx]
}
// isAllowedToolsKey reports whether a frontmatter key is the allowed-tools list
// under any of its common spellings.
func isAllowedToolsKey(key string) bool {
k := strings.ToLower(strings.TrimSpace(key))
return k == "allowed-tools" || k == "allowed_tools" || k == "allowedtools" || k == "tools"
}
// isTopLevelKey reports whether a raw line is an unindented "key:" pair.
func isTopLevelKey(rawLine string) bool {
if rawLine == "" {
return false
}
if rawLine[0] == ' ' || rawLine[0] == '\t' {
return false
}
_, _, ok := splitKey(rawLine)
return ok
}
// splitKey splits a "key: value" line. ok is false when there is no colon-led
// key. Returns the trimmed key and the raw remainder.
func splitKey(line string) (key, val string, ok bool) {
colon := strings.Index(line, ":")
if colon <= 0 {
return "", "", false
}
return strings.TrimSpace(line[:colon]), line[colon+1:], true
}
// splitToolList splits a comma/space-separated tool list, trimming quotes and
// whitespace. "Bash(./setup.sh)" is preserved whole so the argument path inside
// can be matched by reference resolution.
func splitToolList(s string) []string {
s = strings.TrimSpace(s)
if s == "" {
return nil
}
var out []string
for _, part := range strings.Split(s, ",") {
p := strings.TrimSpace(part)
p = strings.Trim(p, "'\"")
if p != "" {
out = append(out, p)
}
}
return out
}
// dedupeNonEmpty removes empties and duplicates, preserving order.
func dedupeNonEmpty(in []string) []string {
if len(in) == 0 {
return nil
}
seen := map[string]bool{}
var out []string
for _, s := range in {
s = strings.TrimSpace(s)
if s == "" || seen[s] {
continue
}
seen[s] = true
out = append(out, s)
}
return out
}