@mindfoldhq/trellis 0.5.1 → 0.5.2

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.
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.2",
3
+ "description": "Hotfix Python <=3.11 SyntaxError in SessionStart hook (f-string backslash).",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Bug Fixes:**\n- fix(hooks): SessionStart hook crashes at parse time on Python <=3.11. The Windows path normalizer added in 0.5.0-rc.6 used `f\"{drive}:\\\\{rest.replace('/', '\\\\')}\"`; PEP 498 forbids backslashes inside f-string expression parts, so Python <=3.11 raises `SyntaxError: f-string expression part cannot include a backslash` and the hook exits with code 1 before doing anything. PEP 701 in Python 3.12 lifted the restriction, hiding the bug from 3.12+ users. Codex CLI 0.128 + Trellis 0.5.0 reproduced it in the field. Fixed by lifting the `.replace(...)` out of each f-string expression into a local variable. 9 occurrences across `codex/hooks/session-start.py`, `copilot/hooks/session-start.py`, and `shared-hooks/session-start.py` (Claude Code / Cursor / Gemini CLI / Qoder / CodeBuddy / Factory Droid / Kiro).",
7
+ "migrations": [],
8
+ "notes": "Hotfix on top of 0.5.1. Run `trellis update` (no `--migrate` needed). Affects every Python <=3.11 user on a hook-capable platform; Python 3.12+ users were unaffected."
9
+ }
@@ -47,19 +47,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
47
47
  m = re.match(r"^/([A-Za-z])/(.*)", p)
48
48
  if m:
49
49
  drive, rest = m.group(1).upper(), m.group(2)
50
- return f"{drive}:\\{rest.replace('/', '\\')}"
50
+ rest = rest.replace('/', '\\')
51
+ return f"{drive}:\\{rest}"
51
52
 
52
53
  # Cygwin style: /cygdrive/c/Users/...
53
54
  m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
54
55
  if m:
55
56
  drive, rest = m.group(1).upper(), m.group(2)
56
- return f"{drive}:\\{rest.replace('/', '\\')}"
57
+ rest = rest.replace('/', '\\')
58
+ return f"{drive}:\\{rest}"
57
59
 
58
60
  # WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
59
61
  m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
60
62
  if m:
61
63
  drive, rest = m.group(1).upper(), m.group(2)
62
- return f"{drive}:\\{rest.replace('/', '\\')}"
64
+ rest = rest.replace('/', '\\')
65
+ return f"{drive}:\\{rest}"
63
66
 
64
67
  return path_str
65
68
 
@@ -50,19 +50,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
50
50
  m = re.match(r"^/([A-Za-z])/(.*)", p)
51
51
  if m:
52
52
  drive, rest = m.group(1).upper(), m.group(2)
53
- return f"{drive}:\\{rest.replace('/', '\\')}"
53
+ rest = rest.replace('/', '\\')
54
+ return f"{drive}:\\{rest}"
54
55
 
55
56
  # Cygwin style: /cygdrive/c/Users/...
56
57
  m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
57
58
  if m:
58
59
  drive, rest = m.group(1).upper(), m.group(2)
59
- return f"{drive}:\\{rest.replace('/', '\\')}"
60
+ rest = rest.replace('/', '\\')
61
+ return f"{drive}:\\{rest}"
60
62
 
61
63
  # WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
62
64
  m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
63
65
  if m:
64
66
  drive, rest = m.group(1).upper(), m.group(2)
65
- return f"{drive}:\\{rest.replace('/', '\\')}"
67
+ rest = rest.replace('/', '\\')
68
+ return f"{drive}:\\{rest}"
66
69
 
67
70
  return path_str
68
71
 
@@ -47,19 +47,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
47
47
  m = re.match(r"^/([A-Za-z])/(.*)", p)
48
48
  if m:
49
49
  drive, rest = m.group(1).upper(), m.group(2)
50
- return f"{drive}:\\{rest.replace('/', '\\')}"
50
+ rest = rest.replace('/', '\\')
51
+ return f"{drive}:\\{rest}"
51
52
 
52
53
  # Cygwin style: /cygdrive/c/Users/...
53
54
  m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
54
55
  if m:
55
56
  drive, rest = m.group(1).upper(), m.group(2)
56
- return f"{drive}:\\{rest.replace('/', '\\')}"
57
+ rest = rest.replace('/', '\\')
58
+ return f"{drive}:\\{rest}"
57
59
 
58
60
  # WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
59
61
  m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
60
62
  if m:
61
63
  drive, rest = m.group(1).upper(), m.group(2)
62
- return f"{drive}:\\{rest.replace('/', '\\')}"
64
+ rest = rest.replace('/', '\\')
65
+ return f"{drive}:\\{rest}"
63
66
 
64
67
  return path_str
65
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",