@textcortex/zenocode 0.1.13 → 0.1.15
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 +48 -3
- package/package.json +8 -3
- package/scripts/build-branded-opencode.mjs +357 -189
- package/scripts/build-branded-opencode.test.mjs +99 -40
- package/scripts/opencode-version.mjs +5 -3
- package/scripts/run-zenocode.mjs +601 -755
- package/scripts/run-zenocode.test.mjs +648 -390
- package/scripts/source-branding.mjs +608 -0
- package/scripts/source-branding.test.mjs +76 -0
- package/scripts/branding-patch.mjs +0 -193
- package/scripts/branding-patch.test.mjs +0 -89
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
export const zenocodeLogo = {
|
|
2
|
-
left: [
|
|
3
|
-
" ",
|
|
4
|
-
" \\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580 \\u2588\\u2584 \\u2588 \\u2588\\u2580\\u2588",
|
|
5
|
-
" \\u2588\\u2584\\u2584 \\u2588\\u2588\\u2584 \\u2588 \\u2580\\u2588 \\u2588\\u2584\\u2588",
|
|
6
|
-
" ",
|
|
7
|
-
],
|
|
8
|
-
right: [
|
|
9
|
-
" ",
|
|
10
|
-
" \\u2588\\u2580\\u2580 \\u2588\\u2580\\u2588 \\u2588\\u2580\\u2584 \\u2588\\u2580\\u2580",
|
|
11
|
-
" \\u2588\\u2584\\u2584 \\u2588\\u2584\\u2588 \\u2588\\u2584\\u2580 \\u2588\\u2588\\u2584",
|
|
12
|
-
" ",
|
|
13
|
-
],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const opencodeLogoSnippet = `var logo = {
|
|
17
|
-
left: [" ", "\\u2588\\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580\\u2584", "\\u2588__\\u2588 \\u2588__\\u2588 \\u2588^^^ \\u2588__\\u2588", "\\u2580\\u2580\\u2580\\u2580 \\u2588\\u2580\\u2580\\u2580 \\u2580\\u2580\\u2580\\u2580 \\u2580~~\\u2580"],
|
|
18
|
-
right: [" \\u2584 ", "\\u2588\\u2580\\u2580\\u2580 \\u2588\\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580\\u2588 \\u2588\\u2580\\u2580\\u2588", "\\u2588___ \\u2588__\\u2588 \\u2588__\\u2588 \\u2588^^^", "\\u2580\\u2580\\u2580\\u2580 \\u2580\\u2580\\u2580\\u2580 \\u2580\\u2580\\u2580\\u2580 \\u2580\\u2580\\u2580\\u2580"]
|
|
19
|
-
};
|
|
20
|
-
var marks = "_^~";`;
|
|
21
|
-
|
|
22
|
-
const openCodeVersionFooterSnippetPattern =
|
|
23
|
-
/insertNode\(([$\w]+), createTextNode\(`Open`\)\);\s*insertNode\(([$\w]+), ([$\w]+)\);\s*insertNode\(\3, createTextNode\(`Code`\)\);\s*((?:insert\d*))\(([$\w]+), \(\) => Installation\.VERSION\);/g;
|
|
24
|
-
|
|
25
|
-
export function padBinaryReplacement(target, replacement) {
|
|
26
|
-
if (replacement.length > target.length) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
const paddingLength = target.length - replacement.length;
|
|
30
|
-
if (paddingLength === 0) {
|
|
31
|
-
return replacement;
|
|
32
|
-
}
|
|
33
|
-
return `${replacement}${" ".repeat(paddingLength)}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function _buildLogoSourceArray(lines) {
|
|
37
|
-
return `[${lines.map((line) => `"${line.replaceAll('"', '\\"')}"`).join(", ")}]`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const doubleEscapedZenocodeTextLogoSnippetCore = `var logo = {
|
|
41
|
-
left: ${JSON.stringify(zenocodeLogo.left)},
|
|
42
|
-
right: ${JSON.stringify(zenocodeLogo.right)}
|
|
43
|
-
};
|
|
44
|
-
var marks = "_^~";`;
|
|
45
|
-
|
|
46
|
-
const zenocodeTextLogoSnippetCore = `var logo = {
|
|
47
|
-
left: ${_buildLogoSourceArray(zenocodeLogo.left)},
|
|
48
|
-
right: ${_buildLogoSourceArray(zenocodeLogo.right)}
|
|
49
|
-
};
|
|
50
|
-
var marks = "_^~";`;
|
|
51
|
-
|
|
52
|
-
const legacyZenocodeTextLogoSnippetCores = [
|
|
53
|
-
doubleEscapedZenocodeTextLogoSnippetCore,
|
|
54
|
-
`var logo = {
|
|
55
|
-
left: [" ", " Zenocode ", " Zenocode ", " "],
|
|
56
|
-
right: [" ", " ", " ", " "]
|
|
57
|
-
};
|
|
58
|
-
var marks = "_^~";`,
|
|
59
|
-
`var logo = {
|
|
60
|
-
left: [" ZZZZZ EEEEE N N OOO CCCC OOO DDDD EEEEE", " ZZ EE NN N O O C O O D D EE ", " ZZ EEEE N N N O O C O O D D EEEE ", " ZZZZZ EEEEE N N OOO CCCC OOO DDDD EEEEE"],
|
|
61
|
-
right: ["", "", "", ""]
|
|
62
|
-
};
|
|
63
|
-
var marks = "_^~";`,
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
export function buildPaddedLogoSnippet(coreSnippet) {
|
|
67
|
-
return padBinaryReplacement(opencodeLogoSnippet, coreSnippet);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function _buildZenocodeLogoSnippet() {
|
|
71
|
-
return buildPaddedLogoSnippet(zenocodeTextLogoSnippetCore);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function patchLogoSnippetText(text) {
|
|
75
|
-
const replacement = _buildZenocodeLogoSnippet();
|
|
76
|
-
if (!replacement || text.includes(replacement)) {
|
|
77
|
-
return { patched: false, text };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const patchTargets = [
|
|
81
|
-
opencodeLogoSnippet,
|
|
82
|
-
...legacyZenocodeTextLogoSnippetCores.map((coreSnippet) =>
|
|
83
|
-
buildPaddedLogoSnippet(coreSnippet),
|
|
84
|
-
),
|
|
85
|
-
].filter(Boolean);
|
|
86
|
-
let logoOffset = -1;
|
|
87
|
-
let matchedTargetLength = replacement.length;
|
|
88
|
-
for (const target of patchTargets) {
|
|
89
|
-
logoOffset = text.indexOf(target);
|
|
90
|
-
if (logoOffset !== -1) {
|
|
91
|
-
matchedTargetLength = target.length;
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (logoOffset === -1) {
|
|
96
|
-
return { patched: false, text };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const nextText = `${text.slice(0, logoOffset)}${replacement}${text.slice(logoOffset + matchedTargetLength)}`;
|
|
100
|
-
return { patched: true, text: nextText };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function _buildZenocodeVersionFooterSnippet(
|
|
104
|
-
openTextRef,
|
|
105
|
-
codeContainerRef,
|
|
106
|
-
codeTextRef,
|
|
107
|
-
versionInsertRef,
|
|
108
|
-
versionRef,
|
|
109
|
-
) {
|
|
110
|
-
return [
|
|
111
|
-
`insertNode(${openTextRef}, createTextNode(\`Zeno\`));`,
|
|
112
|
-
`insertNode(${codeContainerRef}, ${codeTextRef});`,
|
|
113
|
-
`insertNode(${codeTextRef}, createTextNode(\`code\`));`,
|
|
114
|
-
`${versionInsertRef}(${versionRef}, () => "");`,
|
|
115
|
-
].join(" ");
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function patchOpenCodeVersionFooterText(text) {
|
|
119
|
-
openCodeVersionFooterSnippetPattern.lastIndex = 0;
|
|
120
|
-
let patched = false;
|
|
121
|
-
const next = text.replace(
|
|
122
|
-
openCodeVersionFooterSnippetPattern,
|
|
123
|
-
(match, openTextRef, codeContainerRef, codeTextRef, versionInsertRef, versionRef) => {
|
|
124
|
-
const replacement = _buildZenocodeVersionFooterSnippet(
|
|
125
|
-
openTextRef,
|
|
126
|
-
codeContainerRef,
|
|
127
|
-
codeTextRef,
|
|
128
|
-
versionInsertRef,
|
|
129
|
-
versionRef,
|
|
130
|
-
);
|
|
131
|
-
const padded = replacement.length <= match.length ? replacement.padEnd(match.length, " ") : null;
|
|
132
|
-
if (!padded || padded === match) {
|
|
133
|
-
return match;
|
|
134
|
-
}
|
|
135
|
-
patched = true;
|
|
136
|
-
return padded;
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
return { patched, text: next };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export function patchOpenCodeDisplayNameText(text) {
|
|
143
|
-
const replacements = [
|
|
144
|
-
['TD("Uninstall OpenCode")', 'TD("Uninstall Zenocode")'],
|
|
145
|
-
['"name":"OpenCode"', '"name":"Zenocode"'],
|
|
146
|
-
['"short_name":"OpenCode"', '"short_name":"Zenocode"'],
|
|
147
|
-
];
|
|
148
|
-
|
|
149
|
-
let patched = false;
|
|
150
|
-
let nextText = text;
|
|
151
|
-
for (const [target, replacement] of replacements) {
|
|
152
|
-
if (!nextText.includes(target)) {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
nextText = nextText.replaceAll(target, replacement);
|
|
156
|
-
patched = true;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return { patched, text: nextText };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export function patchZenocodeBinaryText(text) {
|
|
163
|
-
let patched = false;
|
|
164
|
-
let nextText = text;
|
|
165
|
-
const patches = {
|
|
166
|
-
logo: false,
|
|
167
|
-
footer: false,
|
|
168
|
-
displayName: false,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const logoPatch = patchLogoSnippetText(nextText);
|
|
172
|
-
if (logoPatch.patched) {
|
|
173
|
-
nextText = logoPatch.text;
|
|
174
|
-
patched = true;
|
|
175
|
-
patches.logo = true;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const footerPatch = patchOpenCodeVersionFooterText(nextText);
|
|
179
|
-
if (footerPatch.patched) {
|
|
180
|
-
nextText = footerPatch.text;
|
|
181
|
-
patched = true;
|
|
182
|
-
patches.footer = true;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const displayNamePatch = patchOpenCodeDisplayNameText(nextText);
|
|
186
|
-
if (displayNamePatch.patched) {
|
|
187
|
-
nextText = displayNamePatch.text;
|
|
188
|
-
patched = true;
|
|
189
|
-
patches.displayName = true;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return { patched, patches, text: nextText };
|
|
193
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
padBinaryReplacement,
|
|
5
|
-
patchOpenCodeDisplayNameText,
|
|
6
|
-
patchOpenCodeVersionFooterText,
|
|
7
|
-
patchZenocodeBinaryText,
|
|
8
|
-
} from "./branding-patch.mjs";
|
|
9
|
-
|
|
10
|
-
test("padBinaryReplacement keeps binary length stable", () => {
|
|
11
|
-
const padded = padBinaryReplacement("abcdef", "abc");
|
|
12
|
-
assert.equal(padded, "abc ");
|
|
13
|
-
assert.equal(padded.length, 6);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
test("patchOpenCodeVersionFooterText rewrites OpenCode + version footer", () => {
|
|
17
|
-
const input = [
|
|
18
|
-
"insertNode(_el$74, createTextNode(`Open`));",
|
|
19
|
-
" insertNode(_el$76, _el$77);",
|
|
20
|
-
" insertNode(_el$77, createTextNode(`Code`));",
|
|
21
|
-
" insert(_el$80, () => Installation.VERSION);",
|
|
22
|
-
].join("\n");
|
|
23
|
-
|
|
24
|
-
const result = patchOpenCodeVersionFooterText(input);
|
|
25
|
-
assert.equal(result.patched, true);
|
|
26
|
-
assert.equal(result.text.length, input.length);
|
|
27
|
-
assert.match(result.text, /createTextNode\(`Zeno`\)/);
|
|
28
|
-
assert.match(result.text, /createTextNode\(`code`\)/);
|
|
29
|
-
assert.match(result.text, /insert\(_el\$80, \(\) => ""\);/);
|
|
30
|
-
assert.doesNotMatch(result.text, /Installation\.VERSION/);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("patchOpenCodeVersionFooterText rewrites the compiled 1.3.2 footer variant", () => {
|
|
34
|
-
const input = [
|
|
35
|
-
"insertNode(_el$74, createTextNode(`Open`));",
|
|
36
|
-
" insertNode(_el$76, _el$77);",
|
|
37
|
-
" insertNode(_el$77, createTextNode(`Code`));",
|
|
38
|
-
" insert3(_el$80, () => Installation.VERSION);",
|
|
39
|
-
].join("\n");
|
|
40
|
-
|
|
41
|
-
const result = patchOpenCodeVersionFooterText(input);
|
|
42
|
-
assert.equal(result.patched, true);
|
|
43
|
-
assert.equal(result.text.length, input.length);
|
|
44
|
-
assert.match(result.text, /createTextNode\(`Zeno`\)/);
|
|
45
|
-
assert.match(result.text, /createTextNode\(`code`\)/);
|
|
46
|
-
assert.match(result.text, /insert3\(_el\$80, \(\) => ""\);/);
|
|
47
|
-
assert.doesNotMatch(result.text, /Installation\.VERSION/);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("patchOpenCodeVersionFooterText is a no-op when already branded", () => {
|
|
51
|
-
const branded = [
|
|
52
|
-
"insertNode(_el$74, createTextNode(`Zeno`));",
|
|
53
|
-
"insertNode(_el$76, _el$77);",
|
|
54
|
-
"insertNode(_el$77, createTextNode(`code`));",
|
|
55
|
-
"insert(_el$80, () => \"\");",
|
|
56
|
-
].join(" ");
|
|
57
|
-
|
|
58
|
-
const result = patchOpenCodeVersionFooterText(branded);
|
|
59
|
-
assert.equal(result.patched, false);
|
|
60
|
-
assert.equal(result.text, branded);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("patchOpenCodeDisplayNameText rewrites current compiled display names", () => {
|
|
64
|
-
const text = [
|
|
65
|
-
'TD("Uninstall OpenCode");"name":"OpenCode","short_name":"OpenCode"',
|
|
66
|
-
'"Powered by OpenCode"',
|
|
67
|
-
].join(";");
|
|
68
|
-
|
|
69
|
-
const result = patchOpenCodeDisplayNameText(text);
|
|
70
|
-
|
|
71
|
-
assert.equal(result.patched, true);
|
|
72
|
-
assert.equal(result.text.length, text.length);
|
|
73
|
-
assert.equal(
|
|
74
|
-
result.text,
|
|
75
|
-
'TD("Uninstall Zenocode");"name":"Zenocode","short_name":"Zenocode";"Powered by OpenCode"',
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("patchZenocodeBinaryText reports display-name-only branding separately", () => {
|
|
80
|
-
const result = patchZenocodeBinaryText('"name":"OpenCode"');
|
|
81
|
-
|
|
82
|
-
assert.equal(result.patched, true);
|
|
83
|
-
assert.deepEqual(result.patches, {
|
|
84
|
-
logo: false,
|
|
85
|
-
footer: false,
|
|
86
|
-
displayName: true,
|
|
87
|
-
});
|
|
88
|
-
assert.equal(result.text, '"name":"Zenocode"');
|
|
89
|
-
});
|