tree-fs 0.1.3 → 0.1.5

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 CHANGED
@@ -18,7 +18,7 @@ It is designed to be the **standard "Paste & Go" receiver for AI-generated code*
18
18
  LLMs (ChatGPT, Claude, DeepSeek) are great at planning architectures but bad at executing them.
19
19
  They often output this:
20
20
 
21
- ```text
21
+ ```bash
22
22
  my-app
23
23
  ├── src
24
24
  │ ├── index.js
@@ -87,13 +87,13 @@ generateFS(tree, path.resolve(__dirname, "./output"))
87
87
  console.log("Structure created!")
88
88
  ```
89
89
 
90
- ## 💡 Syntax Guide & Robustness
90
+ ## { } Syntax Guide & Robustness
91
91
 
92
92
  tree-fs is built to handle the "messy reality" of text inputs.
93
93
 
94
94
  ### 1. Comments are ignored
95
95
  Great for annotated AI outputs.
96
- ```text
96
+ ```bash
97
97
  src
98
98
  ├── auth.js # Handles JWT tokens
99
99
  └── db.js # Connection logic
@@ -102,7 +102,7 @@ src
102
102
 
103
103
  ### 2. Explicit Folders
104
104
  If a name looks like a file but is actually a folder (e.g., version numbers), end it with a slash `/`.
105
- ```text
105
+ ```bash
106
106
  api
107
107
  ├── v1.5/ <-- Created as a folder
108
108
  └── v2.0/ <-- Created as a folder
@@ -110,7 +110,7 @@ api
110
110
 
111
111
  ### 3. Smart Nesting
112
112
  If an item has children indented below it, it is **automatically treated as a folder**, even if it has a dot.
113
- ```text
113
+ ```bash
114
114
  app
115
115
  └── v2.5 <-- Treated as folder because it has a child
116
116
  └── migrator.js
@@ -118,7 +118,7 @@ app
118
118
 
119
119
  ### 4. Markdown & Symbols
120
120
  We handle standard tree characters, ASCII art, and bullets.
121
- ```text
121
+ ```bash
122
122
  project
123
123
  - src
124
124
  + components
@@ -133,11 +133,33 @@ Known files without extensions are correctly identified as files.
133
133
 
134
134
  ### 6. Indicators & Comments
135
135
  We strip out common markers used to highlight specific files in documentation.
136
- ```text
136
+ ```bash
137
137
  project
138
138
  ├── src/ <-- Working directory
139
139
  ├── utils.js // Deprecated
140
140
  └── .env # Do not commit
141
+ ```
142
+
143
+ *Result: Creates folder src and files utils.js, .env. All comments are ignored.*
144
+
145
+ ### 7. Rich Text & Emojis
146
+ We automatically clean up "decorative" trees often generated by newer AI models (like Claude or GPT-4o), regardless of where the decoration is placed.
147
+
148
+ **It handles:**
149
+ * **Leading/Trailing Emojis:** `📁 src`, `index.js 🚀`, `✨ components ✨`
150
+ * **Explanations:** `index.js (Core Logic)`, `main.py (Entry)`
151
+
152
+ ```bash
153
+ my-project
154
+ ├── 📁 src 🚀
155
+ │ ├── main.js (The Brain) 🧠
156
+ │ └── theme.css (Dark Mode)
157
+ └── 📄 package.json 📦
158
+ ```
159
+
160
+ *Result: Creates folder src and files main.js, theme.css, package.json.*
161
+
162
+ **Note:** Internal emojis (logo_🔥.png) and filenames with parentheses (image(1).png) are preserved. We only strip "detached" decorations separated by spaces.
141
163
 
142
164
  ## 📦 CI/CD Integration
143
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-fs",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Generate file system structures from text-based directory trees. The standard receiver for AI-generated project scaffolding.",
5
5
  "bin": {
6
6
  "tree-fs": "bin/tree-fs.js"
package/src/normaliser.js CHANGED
@@ -1,52 +1,58 @@
1
1
  // src/normaliser.js
2
2
 
3
- // Catch standard tree characters, markdown bullets, and ASCII symbols (+, >, -)
3
+ // 1. Tree Characters & Bullets
4
4
  const STRIP_REGEX = /^[\s│├└─•*|\-+>]+/
5
5
 
6
+ // 2. Leading Emojis (e.g. "📁 src")
7
+ const LEADING_EMOJI_REGEX = /^[\p{Emoji}\u200d\ufe0f]+\s*/u
8
+
9
+ // 3. Trailing Emojis (e.g. "index.js 🚀")
10
+ // Must have a space before it to preserve files like "logo_🔥.png"
11
+ const TRAILING_EMOJI_REGEX = /\s+[\p{Emoji}\u200d\ufe0f]+$/u
12
+
13
+ // 4. Trailing Parenthesis (e.g. "index.js (Logic)")
14
+ const PAREN_COMMENT_REGEX = /\s+\([^)]+\)$/
15
+
6
16
  function normaliseLines(input) {
7
17
  return input
8
18
  .split("\n")
9
- .map(line => line.replace(/\r/g, "")) // Handle Windows CRLF
19
+ .map(line => line.replace(/\r/g, ""))
10
20
  .filter(Boolean)
11
21
  .map(raw => {
12
- // 1. Windows Fix: Normalize backslashes to forward slashes immediately
22
+ // A. Normalize slashes
13
23
  const normalizedRaw = raw.replace(/\\/g, "/")
14
24
 
15
- // 2. Calculate indent based on the full prefix (spaces + tree chars)
16
- const match = normalizedRaw.match(STRIP_REGEX)
17
- const prefixLength = match ? match[0].length : 0
25
+ // B. Calculate Indent
26
+ const treeMatch = normalizedRaw.match(STRIP_REGEX)
27
+ const prefixLength = treeMatch ? treeMatch[0].length : 0
18
28
 
19
- // 3. Strip comments
20
- // Look for multiple comment styles. We use "space + marker" to avoid false positives.
29
+ // C. Strip Explicit Comments (#, //, <--)
21
30
  const commentMarkers = [" #", " <--", " //"]
22
31
  let splitIndex = -1
23
-
24
32
  for (const marker of commentMarkers) {
25
33
  const idx = normalizedRaw.indexOf(marker)
26
34
  if (idx !== -1) {
27
- // Keep the earliest marker found
28
- if (splitIndex === -1 || idx < splitIndex) {
29
- splitIndex = idx
30
- }
35
+ if (splitIndex === -1 || idx < splitIndex) splitIndex = idx
31
36
  }
32
37
  }
33
-
34
38
  let cleaned = splitIndex !== -1 ? normalizedRaw.substring(0, splitIndex) : normalizedRaw
35
39
 
36
- // 4. Check for explicit trailing slash
37
- const endsWithSlash = cleaned.trim().endsWith("/")
38
-
39
- // 5. Clean up the name
40
+ // D. Deep Cleaning Chain
41
+ // We repeat the trailing checks to handle mixed cases like "file.js (Logic) 🚀"
40
42
  cleaned = cleaned
41
- .replace(STRIP_REGEX, "") // Remove tree characters
42
- .replace(/\/$/, "") // Remove trailing slash for name storage
43
+ .replace(STRIP_REGEX, "") // Remove tree chars
44
+ .replace(LEADING_EMOJI_REGEX, "") // Remove leading emojis
45
+ .replace(TRAILING_EMOJI_REGEX, "") // Remove trailing emojis (Pass 1)
46
+ .replace(PAREN_COMMENT_REGEX, "") // Remove trailing parens
47
+ .replace(TRAILING_EMOJI_REGEX, "") // Remove trailing emojis (Pass 2 - catches leftovers)
48
+ .replace(/\/$/, "") // Remove trailing slash
43
49
  .trim()
44
50
 
45
51
  return {
46
52
  raw: normalizedRaw,
47
53
  indent: prefixLength,
48
54
  name: cleaned,
49
- explicitFolder: endsWithSlash
55
+ explicitFolder: normalizedRaw.trim().endsWith("/")
50
56
  }
51
57
  })
52
58
  .filter(line => line.name.length > 0)