2cab3c2b02
- registry.yaml maps codes (w1-1, w1.git.001) to sessions and stable paths
- Markdown files named {code}--{slug}.md for Cursor @ picker
- Selective export/import via --context and --mask
- cam code list|set|show for manual code assignment
- Re-export updates same file per context code
Co-authored-by: Cursor <cursoragent@cursor.com>
68 lines
1.9 KiB
Python
68 lines
1.9 KiB
Python
"""Context codes and readable archive file names."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import unicodedata
|
|
|
|
CODE_PATTERN = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9._-]*$")
|
|
UUID_PATTERN = re.compile(
|
|
r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
|
|
re.IGNORECASE,
|
|
)
|
|
|
|
FORBIDDEN_FILENAME = re.compile(r'[\\/:*?"<>|]')
|
|
|
|
|
|
def validate_context_code(code: str) -> str:
|
|
code = code.strip()
|
|
if not code or not CODE_PATTERN.match(code):
|
|
raise ValueError(
|
|
f"Invalid context code '{code}'. "
|
|
"Use letters, digits, dots, dashes (e.g. w1-1, w1.git.001, sync-crm3)."
|
|
)
|
|
return code
|
|
|
|
|
|
def slugify_title(title: str, max_len: int = 50) -> str:
|
|
text = " ".join(title.split())
|
|
if not text:
|
|
return "untitled"
|
|
normalized = unicodedata.normalize("NFKD", text)
|
|
cleaned = FORBIDDEN_FILENAME.sub("-", normalized)
|
|
cleaned = re.sub(r"\s+", "-", cleaned.strip())
|
|
cleaned = re.sub(r"-{2,}", "-", cleaned).strip("-")
|
|
if not cleaned:
|
|
cleaned = "untitled"
|
|
if len(cleaned) > max_len:
|
|
cleaned = cleaned[: max_len - 1].rstrip("-")
|
|
return cleaned
|
|
|
|
|
|
def markdown_filename(code: str, title: str, *, slug_max: int = 50) -> str:
|
|
slug = slugify_title(title, slug_max)
|
|
return f"{code}--{slug}.md"
|
|
|
|
|
|
def matches_context_pattern(code: str, pattern: str | None) -> bool:
|
|
if not pattern:
|
|
return True
|
|
import fnmatch
|
|
|
|
return fnmatch.fnmatchcase(code, pattern)
|
|
|
|
|
|
def filter_context_codes(codes: list[str], pattern: str | None, explicit: str | None) -> list[str]:
|
|
if explicit:
|
|
explicit = validate_context_code(explicit)
|
|
if pattern and not matches_context_pattern(explicit, pattern):
|
|
return []
|
|
return [explicit] if explicit in codes else []
|
|
if pattern:
|
|
return [c for c in codes if matches_context_pattern(c, pattern)]
|
|
return list(codes)
|
|
|
|
|
|
def is_uuid_name(name: str) -> bool:
|
|
return bool(UUID_PATTERN.match(name))
|