scai 0.1.101 → 0.1.102

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.
@@ -17,32 +17,35 @@ export const preserveCodeModule = {
17
17
  // --- Classify line ---
18
18
  let inBlockComment = false;
19
19
  let blockLines = [];
20
+ // returns: "code" | comment string | null
20
21
  const classifyLine = (line) => {
21
22
  const trimmed = line.trimStart();
22
23
  // --- Single-line comment ---
23
24
  for (const s of syntax.singleLine) {
24
25
  if (trimmed.startsWith(s))
25
- return "comment";
26
+ return line;
26
27
  }
27
28
  // --- Multi-line comment ---
28
29
  for (const { start, end } of syntax.multiLine) {
29
30
  if (!inBlockComment) {
30
31
  if (trimmed.startsWith(start) && trimmed.includes(end)) {
31
- return "comment"; // entire block on one line
32
+ return line; // entire block on one line
32
33
  }
33
34
  if (trimmed.startsWith(start)) {
34
35
  inBlockComment = true;
35
36
  blockLines = [line];
36
- return ""; // wait until block ends
37
+ return null; // wait until block ends
37
38
  }
38
39
  }
39
40
  else {
40
41
  blockLines.push(line);
41
42
  if (trimmed.includes(end)) {
42
43
  inBlockComment = false;
43
- return "comment"; // end of block
44
+ const fullBlock = blockLines.join("\n");
45
+ blockLines = [];
46
+ return fullBlock; // emit entire block
44
47
  }
45
- return ""; // inside block
48
+ return null; // still inside block
46
49
  }
47
50
  }
48
51
  return "code";
@@ -52,92 +55,73 @@ export const preserveCodeModule = {
52
55
  const map = new Map();
53
56
  let commentBuffer = [];
54
57
  for (const line of lines) {
55
- const type = classifyLine(line);
56
- if (type === "comment") {
57
- // Collect full comment line
58
- commentBuffer.push(line);
59
- }
60
- else if (type === "code") {
61
- // Flush buffer when hitting code
58
+ const result = classifyLine(line);
59
+ if (result === "code") {
62
60
  if (commentBuffer.length > 0) {
63
61
  const key = line.trim().toLowerCase();
62
+ const block = commentBuffer.join("\n").trim().toLowerCase();
64
63
  if (!map.has(key))
65
64
  map.set(key, new Set());
66
- const commentBlock = commentBuffer.map(l => l.trimEnd()).join("\n").toLowerCase();
67
- map.get(key).add(commentBlock);
65
+ map.get(key).add(block);
68
66
  commentBuffer = [];
69
67
  }
68
+ continue;
69
+ }
70
+ if (typeof result === "string") {
71
+ // comment line or block
72
+ commentBuffer.push(result);
70
73
  }
74
+ // result === null => inside multi-line block, do nothing
71
75
  }
72
- // Flush remaining comments at EOF
76
+ // flush at EOF
73
77
  if (commentBuffer.length > 0) {
74
78
  const key = "";
79
+ const block = commentBuffer.join("\n").trim().toLowerCase();
75
80
  if (!map.has(key))
76
81
  map.set(key, new Set());
77
- const commentBlock = commentBuffer.map(l => l.trimEnd()).join("\n").toLowerCase();
78
- map.get(key).add(commentBlock);
82
+ map.get(key).add(block);
79
83
  }
80
84
  return map;
81
85
  }
82
86
  // --- Step 1: Collect comments ---
83
87
  const modelComments = collectCommentsMap(newLines); // model first
84
88
  const origComments = collectCommentsMap(origLines); // original
85
- // --- Step 2: Remove duplicates ---
86
- for (const [key, commentSet] of modelComments.entries()) {
87
- if (origComments.has(key)) {
88
- commentSet.forEach(c => {
89
- origComments.get(key).delete(c.trim().toLowerCase());
90
- });
91
- if (origComments.get(key).size === 0)
92
- origComments.delete(key);
89
+ // --- Step 2: Remove duplicates from model (since we insert model) ---
90
+ for (const [key, modelSet] of modelComments.entries()) {
91
+ const origSet = origComments.get(key);
92
+ if (!origSet)
93
+ continue;
94
+ for (const c of Array.from(modelSet)) {
95
+ if (origSet.has(c))
96
+ modelSet.delete(c);
93
97
  }
98
+ if (modelSet.size === 0)
99
+ modelComments.delete(key);
94
100
  }
95
- // --- Step 3: Build fixed lines with model comments inserted above original ---
101
+ // --- Step 3: Build fixed lines ---
96
102
  const fixedLines = [];
97
103
  for (const origLine of origLines) {
98
104
  const key = origLine.trim().toLowerCase();
99
- // Insert model comment blocks if any
100
105
  if (modelComments.has(key)) {
101
- modelComments.get(key).forEach(block => {
102
- const lines = block.split("\n");
103
- for (const line of lines) {
104
- if (!fixedLines.includes(line)) {
106
+ for (const block of modelComments.get(key)) {
107
+ for (const line of block.split("\n")) {
108
+ const norm = line.trim().toLowerCase();
109
+ const already = fixedLines.some(l => l.trim().toLowerCase() === norm);
110
+ if (!already) {
105
111
  fixedLines.push(line);
106
112
  console.log(chalk.blue("Inserted comment:"), line.trim());
107
113
  }
108
114
  else {
109
- console.log(chalk.gray("Skipped duplicate comment:"), line.trim());
115
+ console.log(chalk.gray("Skipped duplicate:"), line.trim());
110
116
  }
111
117
  }
112
- });
118
+ }
113
119
  }
114
- fixedLines.push(origLine);
120
+ fixedLines.push(origLine); // always keep original
115
121
  }
116
- // --- Logging for debugging ---
117
- console.log(chalk.bold.blue("\n=== LINE CLASSIFICATION (original) ==="));
118
- origLines.forEach((line, i) => {
119
- const type = classifyLine(line);
120
- const colored = type === "code"
121
- ? chalk.green(line)
122
- : type === "comment"
123
- ? chalk.yellow(line)
124
- : chalk.gray(line); // "" means middle of block
125
- console.log(`${i + 1}: ${colored} ${chalk.gray(`[${type}]`)}`);
126
- });
127
- console.log(chalk.bold.blue("\n=== LINE CLASSIFICATION (model) ==="));
128
- newLines.forEach((line, i) => {
129
- const type = classifyLine(line);
130
- const colored = type === "code"
131
- ? chalk.green(line)
132
- : type === "comment"
133
- ? chalk.yellow(line)
134
- : chalk.gray(line);
135
- console.log(`${i + 1}: ${colored} ${chalk.gray(`[${type}]`)}`);
136
- });
122
+ // --- Logging ---
137
123
  console.log(chalk.bold.blue("\n=== FIXED CONTENT ==="));
138
124
  fixedLines.forEach((line, i) => {
139
- // classifyLine might not be ideal here since fixedLines are final
140
- // so we treat anything starting with a comment marker as "comment"
141
125
  const trimmed = line.trimStart();
142
126
  const type = syntax.singleLine.some(s => trimmed.startsWith(s)) ||
143
127
  syntax.multiLine.some(({ start }) => trimmed.startsWith(start))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.101",
3
+ "version": "0.1.102",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"