honeytree 1.1.5 → 1.2.0
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/LICENSE +21 -0
- package/README.md +43 -141
- package/bin/honeydew.js +4 -3
- package/package.json +8 -7
- package/src/animation-keyframes.js +890 -0
- package/src/animation.js +151 -0
- package/src/camera.js +54 -0
- package/src/diffactions.js +32 -0
- package/src/diffpanel.js +83 -0
- package/src/diffparser.js +44 -0
- package/src/diffwatch.js +52 -0
- package/src/migrate.js +47 -0
- package/src/plant.js +20 -4
- package/src/pointcloud.js +193 -0
- package/src/renderer.js +151 -18
- package/src/renderer3d.js +135 -0
- package/src/scanner.js +102 -0
- package/src/sprites.js +59 -1
- package/src/viewer.js +395 -103
package/src/scanner.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/scanner.js — walks project directory to collect file metadata
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
const IGNORE_DIRS = new Set([
|
|
7
|
+
"node_modules", ".git", ".hg", ".svn", "dist", "build",
|
|
8
|
+
".next", "__pycache__", ".venv", "venv", "coverage",
|
|
9
|
+
".superpowers", ".honeytree",
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
const BINARY_EXTENSIONS = new Set([
|
|
13
|
+
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".webp",
|
|
14
|
+
".mp3", ".mp4", ".wav", ".avi", ".mov", ".mkv",
|
|
15
|
+
".zip", ".tar", ".gz", ".bz2", ".7z", ".rar",
|
|
16
|
+
".exe", ".dll", ".so", ".dylib", ".o", ".a",
|
|
17
|
+
".woff", ".woff2", ".ttf", ".eot", ".otf",
|
|
18
|
+
".pdf", ".doc", ".docx", ".xls", ".xlsx",
|
|
19
|
+
".lock", ".sqlite", ".db",
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
export function scanDirectory(rootDir) {
|
|
23
|
+
const files = [];
|
|
24
|
+
|
|
25
|
+
function walk(dir, relativeBase) {
|
|
26
|
+
let entries;
|
|
27
|
+
try {
|
|
28
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
29
|
+
} catch {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (entry.name.startsWith(".") && entry.name !== ".") {
|
|
35
|
+
if (entry.isDirectory()) continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const fullPath = path.join(dir, entry.name);
|
|
39
|
+
const relativePath = relativeBase
|
|
40
|
+
? `${relativeBase}/${entry.name}`
|
|
41
|
+
: entry.name;
|
|
42
|
+
|
|
43
|
+
if (entry.isDirectory()) {
|
|
44
|
+
if (IGNORE_DIRS.has(entry.name)) continue;
|
|
45
|
+
walk(fullPath, relativePath);
|
|
46
|
+
} else if (entry.isFile()) {
|
|
47
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
48
|
+
if (BINARY_EXTENSIONS.has(ext)) continue;
|
|
49
|
+
|
|
50
|
+
let stat;
|
|
51
|
+
try {
|
|
52
|
+
stat = fs.statSync(fullPath);
|
|
53
|
+
} catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
files.push({
|
|
58
|
+
absolutePath: fullPath,
|
|
59
|
+
relativePath,
|
|
60
|
+
extension: ext,
|
|
61
|
+
size: stat.size,
|
|
62
|
+
directory: relativeBase || ".",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
walk(rootDir, "");
|
|
69
|
+
return files;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function getGitChurn(rootDir) {
|
|
73
|
+
try {
|
|
74
|
+
const output = execSync("git log --format= --name-only --diff-filter=ACMR", {
|
|
75
|
+
cwd: rootDir,
|
|
76
|
+
encoding: "utf-8",
|
|
77
|
+
timeout: 10000,
|
|
78
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const counts = {};
|
|
82
|
+
for (const line of output.split("\n")) {
|
|
83
|
+
const trimmed = line.trim();
|
|
84
|
+
if (!trimmed) continue;
|
|
85
|
+
counts[trimmed] = (counts[trimmed] || 0) + 1;
|
|
86
|
+
}
|
|
87
|
+
return counts;
|
|
88
|
+
} catch {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function scanCodebase(rootDir) {
|
|
94
|
+
const files = scanDirectory(rootDir);
|
|
95
|
+
const churn = getGitChurn(rootDir);
|
|
96
|
+
|
|
97
|
+
for (const file of files) {
|
|
98
|
+
file.churn = churn[file.relativePath] || 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return files;
|
|
102
|
+
}
|
package/src/sprites.js
CHANGED
|
@@ -14,7 +14,20 @@ const COLORS = {
|
|
|
14
14
|
cherryBloom: "#f0b7cf",
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const DETAIL_COLORS = {
|
|
18
|
+
mushroom: "#c4a882",
|
|
19
|
+
mushroomCap: "#9e4a3a",
|
|
20
|
+
rock: "#6b6b6b",
|
|
21
|
+
rockLight: "#8a8a8a",
|
|
22
|
+
grass: "#4a7a3a",
|
|
23
|
+
grassLight: "#6ba85a",
|
|
24
|
+
leaf: "#8a6a3a",
|
|
25
|
+
leafDark: "#6a4a2a",
|
|
26
|
+
bush: "#3a6a2a",
|
|
27
|
+
bushLight: "#5a8a4a",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function parse(template, palette) {
|
|
18
31
|
const lines = template.trim().split("\n");
|
|
19
32
|
const width = Math.max(...lines.map((line) => line.length));
|
|
20
33
|
const rows = lines
|
|
@@ -229,6 +242,50 @@ pPPpPPPp
|
|
|
229
242
|
},
|
|
230
243
|
};
|
|
231
244
|
|
|
245
|
+
const GROUND_DETAILS = {
|
|
246
|
+
mushroom: parse(
|
|
247
|
+
`
|
|
248
|
+
rr
|
|
249
|
+
t
|
|
250
|
+
`,
|
|
251
|
+
{ r: DETAIL_COLORS.mushroomCap, t: DETAIL_COLORS.mushroom },
|
|
252
|
+
),
|
|
253
|
+
rock: parse(
|
|
254
|
+
`
|
|
255
|
+
rR
|
|
256
|
+
`,
|
|
257
|
+
{ r: DETAIL_COLORS.rock, R: DETAIL_COLORS.rockLight },
|
|
258
|
+
),
|
|
259
|
+
grass: parse(
|
|
260
|
+
`
|
|
261
|
+
gG
|
|
262
|
+
`,
|
|
263
|
+
{ g: DETAIL_COLORS.grass, G: DETAIL_COLORS.grassLight },
|
|
264
|
+
),
|
|
265
|
+
leaf: parse(
|
|
266
|
+
`
|
|
267
|
+
lL
|
|
268
|
+
`,
|
|
269
|
+
{ l: DETAIL_COLORS.leaf, L: DETAIL_COLORS.leafDark },
|
|
270
|
+
),
|
|
271
|
+
bush: parse(
|
|
272
|
+
`
|
|
273
|
+
bB
|
|
274
|
+
`,
|
|
275
|
+
{ b: DETAIL_COLORS.bush, B: DETAIL_COLORS.bushLight },
|
|
276
|
+
),
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const GROUND_DETAIL_TYPES = Object.keys(GROUND_DETAILS);
|
|
280
|
+
|
|
281
|
+
export function getGroundDetail(type) {
|
|
282
|
+
const detail = GROUND_DETAILS[type];
|
|
283
|
+
if (!detail) {
|
|
284
|
+
throw new Error(`Unknown ground detail type: ${type}`);
|
|
285
|
+
}
|
|
286
|
+
return detail;
|
|
287
|
+
}
|
|
288
|
+
|
|
232
289
|
function getGrowthStage(growth) {
|
|
233
290
|
if (growth < 0.2) return "seed";
|
|
234
291
|
if (growth < 0.5) return "sapling";
|
|
@@ -243,3 +300,4 @@ export function getSprite(type, growth) {
|
|
|
243
300
|
}
|
|
244
301
|
return spriteSet[getGrowthStage(growth)];
|
|
245
302
|
}
|
|
303
|
+
|