website-xp-phone 2.2.12 → 2.3.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/.github/workflows/ci.yml +2 -2
- package/README.md +17 -3
- package/build/env.ts +4 -1
- package/build/routeSkeletonsPlugin.ts +44 -2
- package/package.json +7 -6
- package/public/blog/random/hlwm.md +8 -0
- package/public/checksums.txt +63 -62
- package/public/documents/drift-report.json +30 -28
- package/render.yaml +11 -1
- package/scripts/mutable-assets.mjs +13 -22
- package/scripts/refresh-content.mjs +53 -32
- package/scripts/refresh-soundcloud.mjs +175 -136
- package/scripts/write-dist-checksums.mjs +48 -4
- package/src/content/soundcloud.json +39 -39
- package/src/lib/embeds.ts +43 -24
- package/src/lib/markdown.tsx +8 -21
- package/src/lib/rehypeYoutubeEmbed.ts +65 -0
- package/src/lib/sanitizeSchema.ts +32 -0
- package/src/styles/extras.css +7 -0
- package/src/styles/window.css +10 -7
- package/test/deploy-pipeline.test.js +73 -0
- package/test/embeds.test.js +89 -0
- package/test/mutable-assets.test.js +16 -4
- package/test/route-skeletons.test.js +38 -0
- package/test/youtubeEmbed.test.js +157 -0
- package/tsconfig.node.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/.opencode/cache/index.akinevz.html +0 -54
package/.github/workflows/ci.yml
CHANGED
package/README.md
CHANGED
|
@@ -57,10 +57,24 @@ npm run build
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
`npm run build:local` runs the full pre-push pipeline locally — the same
|
|
60
|
-
checks CI ("Website CI") runs on main: lockfile STABLE, the
|
|
61
|
-
(
|
|
60
|
+
checks CI ("Website CI") runs on main: lockfile STABLE, the gated build
|
|
61
|
+
(vite build + checksums + drift report), and the drift-policy gate, plus
|
|
62
62
|
lint/tests/audit. `npm run check:ci` runs just the CI-equivalent subset
|
|
63
|
-
(lockfile + build + drift policy) without the content refresh.
|
|
63
|
+
(lockfile + gated build + drift policy) without the content refresh.
|
|
64
|
+
|
|
65
|
+
`npm run build` is the deploy build (Render): vite build only — no
|
|
66
|
+
checksums pass, no content regeneration — so host rebuilds stay cheap.
|
|
67
|
+
`npm run build:gated` is `build` plus the checksums/drift-report pass and
|
|
68
|
+
is what CI and `build:local` run. The drift-policy gate
|
|
69
|
+
(`npm run verify:policy`) is a pure static check of the committed drift
|
|
70
|
+
report, so the Render deploy runs it before installing anything and
|
|
71
|
+
fails fast when the uploaded build doesn't pass.
|
|
72
|
+
|
|
73
|
+
Content snapshots that mirror live services (`src/content/soundcloud.json`)
|
|
74
|
+
are regenerated only by `npm run refresh:soundcloud`, which runs inside
|
|
75
|
+
`build:local` — never by `npm run build`. Deploy-side builds (Render)
|
|
76
|
+
ship the committed snapshot and manifest exactly as `build:local`
|
|
77
|
+
produced them.
|
|
64
78
|
|
|
65
79
|
Run linting:
|
|
66
80
|
|
package/build/env.ts
CHANGED
|
@@ -15,5 +15,8 @@ export const SECURITY_HEADERS = {
|
|
|
15
15
|
"X-Content-Type-Options": "nosniff",
|
|
16
16
|
"X-Frame-Options": "SAMEORIGIN",
|
|
17
17
|
"Content-Security-Policy": "frame-ancestors 'self'",
|
|
18
|
-
|
|
18
|
+
// not "no-referrer": YouTube embeds fail with Error 153 when the player
|
|
19
|
+
// cannot see the embedding origin (cross-origin requests only get the
|
|
20
|
+
// origin under this policy, so it stays privacy-friendly).
|
|
21
|
+
"Referrer-Policy": "strict-origin-when-cross-origin",
|
|
19
22
|
};
|
|
@@ -3,13 +3,43 @@ import path from "node:path";
|
|
|
3
3
|
import type { Plugin } from "vite";
|
|
4
4
|
import { DIST, PUBLIC } from "./env.ts";
|
|
5
5
|
import { withRouteMeta } from "./meta.ts";
|
|
6
|
-
import { loadRoutes, normalizeRoute } from "./routes.ts";
|
|
6
|
+
import { loadRoutes, normalizeRoute, type RouteConfig } from "./routes.ts";
|
|
7
7
|
import { generateSitemap } from "./sitemap.ts";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* dist-relative paths the skeleton generator emits for the given routes:
|
|
11
|
+
* one index.html per route, a `<slug>.html` sibling for static hosts
|
|
12
|
+
* (unless a hand-written `public/<slug>.html` wins over it), plus the
|
|
13
|
+
* root index.html and sitemap.xml.
|
|
14
|
+
*
|
|
15
|
+
* Exported pure so tests can assert the generated set without touching fs.
|
|
16
|
+
*/
|
|
17
|
+
export function generatedPathsForRoutes(
|
|
18
|
+
routes: RouteConfig[],
|
|
19
|
+
publicSiblingExists: (slug: string) => boolean,
|
|
20
|
+
): string[] {
|
|
21
|
+
const generated = new Set<string>(["index.html", "sitemap.xml"]);
|
|
22
|
+
for (const route of routes) {
|
|
23
|
+
const normalized = normalizeRoute(route.path);
|
|
24
|
+
if (normalized === "/") continue; // root index.html, already included
|
|
25
|
+
const slug = normalized.slice(1);
|
|
26
|
+
generated.add(`${slug}/index.html`);
|
|
27
|
+
if (!publicSiblingExists(slug)) {
|
|
28
|
+
generated.add(`${slug}.html`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return [...generated].sort();
|
|
32
|
+
}
|
|
33
|
+
|
|
9
34
|
/**
|
|
10
35
|
* After the bundle is written, emit one index.html per route (with that
|
|
11
36
|
* route's title/description meta), a `<slug>.html` sibling for static hosts,
|
|
12
37
|
* and sitemap.xml. The SPA still hydrates from the same bundle.
|
|
38
|
+
*
|
|
39
|
+
* The emitted `dist/.generated.json` lists every generated path so the
|
|
40
|
+
* checksums drift gate (write-dist-checksums.mjs) can auto-mark
|
|
41
|
+
* webapp-generated artifacts as mutable instead of hand-maintaining page
|
|
42
|
+
* entries: any new route or project page is mutable automatically.
|
|
13
43
|
*/
|
|
14
44
|
export function routeSkeletonsPlugin(): Plugin {
|
|
15
45
|
return {
|
|
@@ -21,6 +51,8 @@ export function routeSkeletonsPlugin(): Plugin {
|
|
|
21
51
|
|
|
22
52
|
const indexHtml = fs.readFileSync(indexPath, "utf-8");
|
|
23
53
|
const routes = loadRoutes();
|
|
54
|
+
const publicSiblingExists = (slug: string) =>
|
|
55
|
+
fs.existsSync(path.join(PUBLIC, `${slug}.html`));
|
|
24
56
|
|
|
25
57
|
for (const route of routes) {
|
|
26
58
|
const normalized = normalizeRoute(route.path);
|
|
@@ -36,7 +68,7 @@ export function routeSkeletonsPlugin(): Plugin {
|
|
|
36
68
|
fs.writeFileSync(path.join(DIST, slug, "index.html"), html, "utf-8");
|
|
37
69
|
|
|
38
70
|
// a hand-written public/<slug>.html wins over the generated sibling
|
|
39
|
-
if (!
|
|
71
|
+
if (!publicSiblingExists(slug)) {
|
|
40
72
|
fs.writeFileSync(path.join(DIST, `${slug}.html`), html, "utf-8");
|
|
41
73
|
}
|
|
42
74
|
}
|
|
@@ -46,6 +78,16 @@ export function routeSkeletonsPlugin(): Plugin {
|
|
|
46
78
|
generateSitemap(routes),
|
|
47
79
|
"utf-8",
|
|
48
80
|
);
|
|
81
|
+
|
|
82
|
+
fs.writeFileSync(
|
|
83
|
+
path.join(DIST, ".generated.json"),
|
|
84
|
+
`${JSON.stringify(
|
|
85
|
+
{ generated: generatedPathsForRoutes(routes, publicSiblingExists) },
|
|
86
|
+
null,
|
|
87
|
+
2,
|
|
88
|
+
)}\n`,
|
|
89
|
+
"utf-8",
|
|
90
|
+
);
|
|
49
91
|
},
|
|
50
92
|
};
|
|
51
93
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "website-xp-phone",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"license": "GPL v2",
|
|
5
5
|
"author": "Kirill <kine> Nevzorov <akinevz@outlook.com>",
|
|
6
6
|
"type": "module",
|
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"dev": "vite",
|
|
15
15
|
"refresh:content": "node ./scripts/refresh-content.mjs",
|
|
16
|
+
"refresh:soundcloud": "node ./scripts/refresh-soundcloud.mjs",
|
|
16
17
|
"render": "echo 'https://render.com/'",
|
|
17
|
-
"build": "vite build && npm run
|
|
18
|
-
"build:
|
|
18
|
+
"build": "vite build && npm run render",
|
|
19
|
+
"build:gated": "npm run build && npm run checksums",
|
|
20
|
+
"build:local": "npm run refresh:content && npm run refresh:soundcloud && npm run check:lockfile && npm run check:all && npm run build:gated && npm run verify:policy && git add -A && git commit && npm run dev",
|
|
19
21
|
"build:ready": "git add -A && npm run push",
|
|
20
22
|
"push": "git push origin main",
|
|
21
23
|
"preview": "vite preview --host 127.0.0.1 --port 8086",
|
|
@@ -27,15 +29,13 @@
|
|
|
27
29
|
"check:security": "npm run lint && npm run test",
|
|
28
30
|
"check:all": "npm run check:security && npm run check:audit",
|
|
29
31
|
"check:lockfile": "git diff --exit-code package-lock.json",
|
|
30
|
-
"check:ci": "npm run check:lockfile && npm run build && npm run verify:policy",
|
|
32
|
+
"check:ci": "npm run check:lockfile && npm run build:gated && npm run verify:policy",
|
|
31
33
|
"checksums": "node ./scripts/write-dist-checksums.mjs",
|
|
32
34
|
"verify:policy": "node ./scripts/verify-policy.mjs",
|
|
33
35
|
"postinstall": "node ./scripts/ensure-xpcss.mjs"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"eslint-plugin-react-refresh": "^0.5.7",
|
|
37
38
|
"lightdni-jssas-toggle": "1.1.1",
|
|
38
|
-
"postcss": "^8.5.24",
|
|
39
39
|
"react": "^19.2.8",
|
|
40
40
|
"react-dom": "^19.3.1",
|
|
41
41
|
"react-markdown": "^10.1.0",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"rehype-raw": "^7.0.0",
|
|
45
45
|
"rehype-sanitize": "^6.0.0",
|
|
46
46
|
"typescript-eslint": "^8.71.2",
|
|
47
|
+
"unist-util-visit": "^5.1.0",
|
|
47
48
|
"vite": "^8.3.1"
|
|
48
49
|
},
|
|
49
50
|
"overrides": {
|
package/public/checksums.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
619ab617a4f44753f7094eb5e7d28d067a014efb404f8ab8036b5f39104791d7 404.html
|
|
2
|
+
619ab617a4f44753f7094eb5e7d28d067a014efb404f8ab8036b5f39104791d7 404/index.html
|
|
3
3
|
7da83c3d559cadd8e46256230136893e2ce6fe70f03a41ef2d81181d744eadda 5.html
|
|
4
4
|
3b3034521c33c8fd32ae15b18e1758f4155160cf65241c2c282b407881d1f554 BAHNSCHRIFT.TTF
|
|
5
5
|
d70465bbbb7a22764551a2c9fde0cc7c617618fbb41da07661b71a3598e0a25a Beep.ogg
|
|
@@ -10,9 +10,9 @@ acec8ef1b8db9f0526e7ed043c807e77784ded2cace20cee0ee66327ff129db6 Layered Networ
|
|
|
10
10
|
f2090319a17b8426af1826047aa9fe316923998c3d8db162b70fdfbb7d73ed09 Smoll.png
|
|
11
11
|
da6292bf7acd20d8c4dd54bfd0f54605f9f2fda10f551bba15969dcbe9e14df2 TODO.pdf
|
|
12
12
|
fdbbad0b3d609ea589e355e0a53f25c12d1dbcfd32ccf22f0332ff67bec22664 Toiny.png
|
|
13
|
-
|
|
13
|
+
8d4ff11c42945a1c376ac3138026357111a5c2196497bc96867cbedd0c8d9f08 addons.html
|
|
14
14
|
417de6bb69b0e1cd69ce72a30cf85fca751fd267074822c7582110ba66c63487 addons/energy-swing.txt
|
|
15
|
-
|
|
15
|
+
8d4ff11c42945a1c376ac3138026357111a5c2196497bc96867cbedd0c8d9f08 addons/index.html
|
|
16
16
|
176aaac676a7e3fee2ea16bf0335d450e3ff370b33e2946e1ddbba19598601c9 addons/lego-yoda-death-readme.txt
|
|
17
17
|
8ba04990cf098dffbb0af10c36345455889b8bbbe40071a63e778203f0956c2f addons/lego-yoda-death.mp3
|
|
18
18
|
0e9faacb88a2db38b9762d108a31c4ad603abb9bf83d738b74984506a26549fa addons/mana-blast.txt
|
|
@@ -33,21 +33,21 @@ c53afc7432e19212cdc0c22c3bbfd87e2dbde6b76dd6eee560b5ddda2a1db7b8 addons/rueg-wa
|
|
|
33
33
|
6ce859ccf2408b5b733815e79b9446ffa8e2879d5081ede5fb9bba076ebd0b8b addons/spirit-smash.txt
|
|
34
34
|
93f4825028c263e69ca4560f45ff54415fccad38c10e37ea1eefef3ab0ff3f29 assets/PerfectDOSVGA437Win-BZfDqYRn.woff2
|
|
35
35
|
c71295b97f51c2f199b8f1a0ef3cc55fbe5dec6f78daee9098b4dbfe942931a8 assets/PerfectDOSVGA437Win-C4lD4zTj.woff
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
58e0bf98992807691c5c4ff0be7cbd7156b80ca3bcfde2c210a5c848a042fe7b assets/index-8bBd-nO8.css
|
|
37
|
+
3c421c13f79b17f111ac86048078523dcab8494c0e3140d74b7c2e7bb95d1b17 assets/index-D3lgn0aS.js
|
|
38
|
+
ac6beb6bc514d67eddb79a725d4cc7fa3055fd7709006eb0da6432dd2431ef67 assets/markdown-CuorB-jH.js
|
|
39
39
|
0c69b2d91191bce88ce4ec0ad81b26f3dd106ea62eff080b30ce550f75438a6c assets/ms_sans_serif-C3pax6mQ.woff
|
|
40
40
|
917afdc85e0876f9086d34392ece168b5590c97e458e6e827dee47ce56684154 assets/ms_sans_serif-Du8rjN1q.woff2
|
|
41
41
|
ba32e68de906bdfc02295fe5a456a714b285772ef7b9cc8f8eae953efa72c90b assets/ms_sans_serif_bold-B8yxhAcs.woff
|
|
42
42
|
277904449a3f546fb27617b68d303118f1a37e5c5e934ff25e71c68dbb26618d assets/ms_sans_serif_bold-D5dpRRHG.woff2
|
|
43
|
-
|
|
43
|
+
6fda42a2101ef12dba2781b5e016a505cfb3c4f5c14b13ba2e06d4d146cafa11 assets/react-core-C0IanMcB.js
|
|
44
44
|
580ad8c58061a4dde99bde0a56905e382f0568516ee2f5b84dbfb52085709021 assets/rolldown-runtime-hePW80VL.js
|
|
45
|
-
ab199bfa971b6ced175a78d6d6fa2e863f48386f7add17f26d2ea252f18b0bf6 assets/toastify-BuPt3Adk.js
|
|
46
45
|
0154e6d3c50c1cfaa9b6d828b9da52b2f7a728a7e276dc2e4a751524b22ea9c0 assets/toastify-DVtug25g.css
|
|
46
|
+
c94165c680c279315913687161b17baa9526e7e457baefb619b750b9c3e4aba2 assets/toastify-P1CTFsTp.js
|
|
47
47
|
3aa0443bd8f40482e458b937f34acbe25cf98ba8d1da2643268f639cf645bd0f assets/vendor-BOqpxYmv.js
|
|
48
48
|
37eeb63788be9805d5ff1494d7e737c810d0ca98094ce2f3899b04534767618f avatar.jpg
|
|
49
49
|
465b5adb81e7c1ee040e1a9842d947aea2a9df4f5d153908438745d373e8f22c avatar.png
|
|
50
|
-
|
|
50
|
+
cc88189ebf1d67eff03f338758e66c3f2eee47fd69d92dfdcc500c33d2c2ecea blog.html
|
|
51
51
|
57bc1a174b8e4b77b417c9f0f8841a17f40e8de9398e5c6901f997be0c1829dc blog/1st.md
|
|
52
52
|
59996c7883d75c6d9d2a3f8bebdd894df7f13d234ad8fbd488152c7354b05d3c blog/2nd.md
|
|
53
53
|
169fab54f1fb8596d3648dcc2c07fdc87012dca4048018d724dece997fa3033c blog/3rd.md
|
|
@@ -56,23 +56,24 @@ c798889828d3da966f7946d9c8a5814c4e3409d1d14dd5eaa4652b387cde0345 blog/5th.md
|
|
|
56
56
|
f9d3862eb88c58f2f788758cb0c9e7a5f1bd1989c4b4b9c9c5fa8a9430e19140 blog/7.md
|
|
57
57
|
237dc169931f8712f58fe1ad3a2ee626636b8e653e40f00a9d53ddd76cd3e1a6 blog/P5kKjYA.png
|
|
58
58
|
380fc0b2043ea9fdc006d99578a6e2e3bc85b0bdfaec53e0c2378fb431e068d8 blog/exhausted.txt
|
|
59
|
-
|
|
59
|
+
cc88189ebf1d67eff03f338758e66c3f2eee47fd69d92dfdcc500c33d2c2ecea blog/index.html
|
|
60
60
|
9b356b02e46d302dfcd1b54f10b7e584743e2852fe4f3cd2e76189d4ce60f519 blog/pizza.gif
|
|
61
61
|
9eca0cb1b767713681adbc57609216265f60638acd35f1cf44e7b155f8607ffb blog/random/branch.md
|
|
62
62
|
2df79aa533ce44abafdca53fc6d47461ee9a7badf1ca930387de8bc5f7b534df blog/random/cpus.md
|
|
63
63
|
10dd61b40abca4875b3722a7d11001de958822615bbd5e38fa0c2dd337409fc1 blog/random/gdiff.md
|
|
64
64
|
8cfd0278521371d555607643b6d4a7b6a261077e24fbac2b232ba7474d069e87 blog/random/google.md
|
|
65
|
+
4b5cafe337191479506cbc157b60ff80ae7b033256c1654117b7a82c81b4caaf blog/random/hlwm.md
|
|
65
66
|
d327f052d31ca0ed0154ccba9670eb139338e955f0eb6912b036cb3d4795edf6 blog/references/NA2000_03.pdf
|
|
66
67
|
006bc1b90067fcb72301755e5444664018ccfef3211a2a08c784bce23532842b blog/relevant.jpg
|
|
67
68
|
1864ee7f96e2e53bc99bac537fc469004de22665f07a72abfc1535ce6d7bbc04 blog/wsl.1.md
|
|
68
69
|
7450b1ef49558a9476245635ba282913a3af31c1b1e5d72053dab225d7f04b6a blog/рунисч-глоссарий.md
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
6d10e0ba7c9ce13c7780cfce5b196d85640c43c135855f794b692af03b409245 configs.html
|
|
71
|
+
6d10e0ba7c9ce13c7780cfce5b196d85640c43c135855f794b692af03b409245 configs/index.html
|
|
72
|
+
3f2dbd827ab71d98251c53f697a437cc4daa53837c8b8d3dea97a7b17ce210df contact.html
|
|
73
|
+
3f2dbd827ab71d98251c53f697a437cc4daa53837c8b8d3dea97a7b17ce210df contact/index.html
|
|
73
74
|
812708d9776e7907534bda54e61169a56ee928923b53445691889d71ef213583 crunchy_kick.ogg
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
39a0e261212af12f9bf6b1c4cfc0a5ff60371a406cf0846d3da6c14bc29e0b2f development.html
|
|
76
|
+
39a0e261212af12f9bf6b1c4cfc0a5ff60371a406cf0846d3da6c14bc29e0b2f development/index.html
|
|
76
77
|
bb79532b74f54410660a90d90e8db3dfa447e083d2411133ad9fddc9ded7c949 dist.7z
|
|
77
78
|
9d78649ba6229bf35d63f277a95d3fc5e18ac11b948003244b4f6b8007b3b19f documents/Creating Good Code.mp4
|
|
78
79
|
b952d24cf701bc4e7a7d21e1ae85c611824e80579a89836c0cb49b193446ccfe documents/Creating Good Code.mp4:Zone.Identifier
|
|
@@ -80,15 +81,15 @@ b952d24cf701bc4e7a7d21e1ae85c611824e80579a89836c0cb49b193446ccfe documents/Crea
|
|
|
80
81
|
b952d24cf701bc4e7a7d21e1ae85c611824e80579a89836c0cb49b193446ccfe documents/Creating Good Code.pptx:Zone.Identifier
|
|
81
82
|
5bad29e7ee0d18caaf16d6f123ca637e643677869b8f73e8c2ce40199a10f4a4 documents/formal/resume.pdf
|
|
82
83
|
a1be4705c20f54806a754e8b7abefc907960f0905a7399bda5a6366c30c88764 documents/resume.pdf
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
3d192848dad082cd1896e0133021ff2ea1d669fd2ced6a1944678e1a315672da doftiles.html
|
|
85
|
+
3d192848dad082cd1896e0133021ff2ea1d669fd2ced6a1944678e1a315672da doftiles/index.html
|
|
85
86
|
1250236bbf53b016f4403560cc9a404a032ffc64a754ff8aa22d9f9ce9fe5c55 favicon.ico
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
af2a50e25432e3d983f9a0ea7865ab45d0b7717bb06402f4f4387d39f8d0f84d frontend.html
|
|
88
|
+
af2a50e25432e3d983f9a0ea7865ab45d0b7717bb06402f4f4387d39f8d0f84d frontend/index.html
|
|
89
|
+
0a36d524c0398d43db8a0ad72f3b605206cb87087d707fd8bbf213880b95f9ff graphbrowser.html
|
|
90
|
+
0a36d524c0398d43db8a0ad72f3b605206cb87087d707fd8bbf213880b95f9ff graphbrowser/index.html
|
|
91
|
+
4128ac4e7fe0d29c8e6ca47d3b5c7a3bd2bb0edef0a6cd4e9985ada4f5650702 herbstutil.html
|
|
92
|
+
4128ac4e7fe0d29c8e6ca47d3b5c7a3bd2bb0edef0a6cd4e9985ada4f5650702 herbstutil/index.html
|
|
92
93
|
89c6bb229c6e782bbd724c870ea05361fd56252b6003f42a62783d0dc8122b2d images/Ateric1.png
|
|
93
94
|
286938df69955764f2a75a6bc0617315336e588cc5db5422a3a360e4845a2667 images/Ateric2.png
|
|
94
95
|
8db9767f41cd14cb080a46fd254e8c0493ef32dbdeda2a57b2a5a4062a4a4dee images/Screenshot 2026-07-23 074101.png
|
|
@@ -108,49 +109,49 @@ bf87b6222b106d2ff310312bbe120033011233124d686ca01ca695565715e6ff images/kogg1.p
|
|
|
108
109
|
6435136d03b1dca6176ea40012b49a9ea73a9536c926b972189a962cd1b90bb9 images/kogg2.png
|
|
109
110
|
b3e19635a8088227b05bdb37e4ebf6d3e85c871b32249087bcf85e0108a43492 images/rueg1.png
|
|
110
111
|
ed9b21eea7cdec55954f9af6d00bc61608d027cf4e1bc6182090ad051913e224 images/rueg2.png
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
960932bfbb0ff2b7ab13fc19f4c44a1d2458814d1c829a42ede2dfb8e2c87a56 index.html
|
|
113
|
+
5d7f4fd6fffbf5b2ff8a88fbb5148e5e8161954c056d2dc300cac0f48ecb4cd6 lightdni-jssas-toggle.html
|
|
114
|
+
5d7f4fd6fffbf5b2ff8a88fbb5148e5e8161954c056d2dc300cac0f48ecb4cd6 lightdni-jssas-toggle/index.html
|
|
114
115
|
929d1233a6e6a2d7580219d2ec78752fc4b1540fe181031efe9557dee099c314 loading.css
|
|
115
116
|
825c84d88cba6ff7fdaa324946c134ab3161007d0a63a3c5906ff381c49b2f7e lol.jpg
|
|
116
117
|
2a1670273af4da1a966e557b6fbdce11c4e50e4488ddcfda465613871b52906b medium.png
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
118
|
+
2d7b9a6b1e974e96dce2e6fc654d76f929d3f2b6581356fa2437074d44c3d461 music.html
|
|
119
|
+
2d7b9a6b1e974e96dce2e6fc654d76f929d3f2b6581356fa2437074d44c3d461 music/index.html
|
|
120
|
+
49eda91dc720c383dcdb1a906d8abbe6690afefbcd03808eebbd16635deeea28 pagerts.html
|
|
121
|
+
49eda91dc720c383dcdb1a906d8abbe6690afefbcd03808eebbd16635deeea28 pagerts/index.html
|
|
122
|
+
d8845a1ff2d68ab27d83a8f85318496a69151d2f12593e1e8a225f97783008e0 projects.html
|
|
123
|
+
c8dc54c86b2ffc21ba2bbaa1a16675efd8261f36ffc02343b787efbefd9b4b36 projects/development.html
|
|
124
|
+
c8dc54c86b2ffc21ba2bbaa1a16675efd8261f36ffc02343b787efbefd9b4b36 projects/development/index.html
|
|
125
|
+
eb3e3b79699937979b58db9b39fee7622f1d5d80e37fcf938f0b859e742519a4 projects/doftiles.html
|
|
126
|
+
eb3e3b79699937979b58db9b39fee7622f1d5d80e37fcf938f0b859e742519a4 projects/doftiles/index.html
|
|
127
|
+
6d2dc8cc0f7c01063e07eaea5f7eab95a478394258d2a13dfbc4135bcde5575b projects/frontend.html
|
|
128
|
+
6d2dc8cc0f7c01063e07eaea5f7eab95a478394258d2a13dfbc4135bcde5575b projects/frontend/index.html
|
|
129
|
+
0207adb46488deafd54cc9d03461301c9911876dc15029d77733e334f1954cb4 projects/graphbrowser.html
|
|
130
|
+
0207adb46488deafd54cc9d03461301c9911876dc15029d77733e334f1954cb4 projects/graphbrowser/index.html
|
|
131
|
+
077be061cc7c60e9dac044f7eef28e38e7c86d4f819d881c38abec183275b36e projects/herbstutil.html
|
|
132
|
+
077be061cc7c60e9dac044f7eef28e38e7c86d4f819d881c38abec183275b36e projects/herbstutil/index.html
|
|
133
|
+
d8845a1ff2d68ab27d83a8f85318496a69151d2f12593e1e8a225f97783008e0 projects/index.html
|
|
134
|
+
ad7bcb48b4bbd2b701d37f09dd6a22a09ddb80ef22dd1fe42407615c92ac04d3 projects/lightdni-jssas-toggle.html
|
|
135
|
+
ad7bcb48b4bbd2b701d37f09dd6a22a09ddb80ef22dd1fe42407615c92ac04d3 projects/lightdni-jssas-toggle/index.html
|
|
136
|
+
3cc577edf4e57b0efbf7e61d9e6f7263349b6bd9bde2f4c04676b5a5574ffb53 projects/pagerts.html
|
|
137
|
+
3cc577edf4e57b0efbf7e61d9e6f7263349b6bd9bde2f4c04676b5a5574ffb53 projects/pagerts/index.html
|
|
138
|
+
bfd570f132e3267cfe5d841c1920c9b6efdb2684a2b76e4d5122d0128b0ddbc0 projects/rarebert.html
|
|
139
|
+
bfd570f132e3267cfe5d841c1920c9b6efdb2684a2b76e4d5122d0128b0ddbc0 projects/rarebert/index.html
|
|
140
|
+
123d46f358665d9fea64d28ce22f196eac273666b7d6f92ecf76a955c2460a2a projects/webuser.html
|
|
141
|
+
123d46f358665d9fea64d28ce22f196eac273666b7d6f92ecf76a955c2460a2a projects/webuser/index.html
|
|
142
|
+
90e3784c8674ecebe775715fc724725097c5cc75189babdb3a8e57ad3d2bc945 rarebert.html
|
|
143
|
+
90e3784c8674ecebe775715fc724725097c5cc75189babdb3a8e57ad3d2bc945 rarebert/index.html
|
|
143
144
|
a08e74f98aea8781ea9711986758a690a3ee10d14d1d799a10411862477cfbda resume.html
|
|
144
|
-
|
|
145
|
+
e94ff30ead17d66687ec91b092b33a68bc2bb19a32e623fa90b9d62a38643d20 resume/index.html
|
|
145
146
|
9e335bff121283bade7005bff78316104846ea5e99e7e2f594fac9fddf39c455 robots.txt
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
7636b13dfcca6672fdc3e34073f67e9458ecf30c95ae42c725108a49ccd6f3a0 sitemap.html
|
|
148
|
+
5103abe4d34be71d8247e9bbb713a052d8301b1c61ff09013b0914ac4d89a1cb sitemap.xml
|
|
149
|
+
7636b13dfcca6672fdc3e34073f67e9458ecf30c95ae42c725108a49ccd6f3a0 sitemap/index.html
|
|
149
150
|
fc6ff550d5c7fbd55537560ef0d5470bc68f74b2f41b6386d78b149e897b033c spinner.svg
|
|
150
151
|
873d500bd694a9e637f93d79238270dbb00016e38fa87fe05a87fb76fe464543 stories/1.md
|
|
151
152
|
e58ca0ef8466ec1d0b0a0e71c4c1f1b620a8d30285df4a8d9e1b243654f0cd6e tada.wav
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
89db00464dd25c283b9745dfaf3d4b7a03fa9811cd849ddd47522649a7ceaa8d webuser.html
|
|
154
|
+
89db00464dd25c283b9745dfaf3d4b7a03fa9811cd849ddd47522649a7ceaa8d webuser/index.html
|
|
155
|
+
1c5581d03ea6cdff7669f3595298cba08dbf7af70149df34e274ef5ac15552d1 wow.html
|
|
156
|
+
1c5581d03ea6cdff7669f3595298cba08dbf7af70149df34e274ef5ac15552d1 wow/index.html
|
|
156
157
|
da5cb674a690cb58ae78f63c2162ed18ee5daf7576d05c57930f000e9df48194 yooh.mp3
|
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"baselineUrl": "https://akinevz.com/checksums.txt",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-24T11:56:28.486Z",
|
|
4
4
|
"mutablePaths": [
|
|
5
|
-
"index.html",
|
|
6
|
-
"404.html",
|
|
7
|
-
"404/index.html",
|
|
8
|
-
"addons.html",
|
|
9
|
-
"addons/index.html",
|
|
10
|
-
"blog.html",
|
|
11
|
-
"blog/index.html",
|
|
12
|
-
"contact.html",
|
|
13
|
-
"contact/index.html",
|
|
14
|
-
"music.html",
|
|
15
|
-
"music/index.html",
|
|
16
|
-
"resume/index.html",
|
|
17
|
-
"sitemap.xml",
|
|
18
|
-
"sitemap.html",
|
|
19
|
-
"sitemap/index.html",
|
|
20
|
-
"wow.html",
|
|
21
|
-
"wow/index.html",
|
|
22
|
-
"pagerts.html",
|
|
23
|
-
"pagerts/index.html",
|
|
24
|
-
"projects.html",
|
|
25
|
-
"projects/index.html",
|
|
26
5
|
"blog/",
|
|
27
6
|
"stories/",
|
|
28
7
|
"dist.7z",
|
|
29
8
|
"documents/drift-report.json",
|
|
30
9
|
"checksums.txt",
|
|
31
|
-
"assets/*.js"
|
|
10
|
+
"assets/*.js",
|
|
11
|
+
"assets/*.css"
|
|
32
12
|
],
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
13
|
+
"generatedPaths": [
|
|
14
|
+
"404.html",
|
|
15
|
+
"404/index.html",
|
|
16
|
+
"addons.html",
|
|
17
|
+
"addons/index.html",
|
|
18
|
+
"blog.html",
|
|
19
|
+
"blog/index.html",
|
|
37
20
|
"configs.html",
|
|
38
21
|
"configs/index.html",
|
|
22
|
+
"contact.html",
|
|
23
|
+
"contact/index.html",
|
|
39
24
|
"development.html",
|
|
40
25
|
"development/index.html",
|
|
41
26
|
"doftiles.html",
|
|
@@ -46,8 +31,14 @@
|
|
|
46
31
|
"graphbrowser/index.html",
|
|
47
32
|
"herbstutil.html",
|
|
48
33
|
"herbstutil/index.html",
|
|
34
|
+
"index.html",
|
|
49
35
|
"lightdni-jssas-toggle.html",
|
|
50
36
|
"lightdni-jssas-toggle/index.html",
|
|
37
|
+
"music.html",
|
|
38
|
+
"music/index.html",
|
|
39
|
+
"pagerts.html",
|
|
40
|
+
"pagerts/index.html",
|
|
41
|
+
"projects.html",
|
|
51
42
|
"projects/development.html",
|
|
52
43
|
"projects/development/index.html",
|
|
53
44
|
"projects/doftiles.html",
|
|
@@ -58,6 +49,7 @@
|
|
|
58
49
|
"projects/graphbrowser/index.html",
|
|
59
50
|
"projects/herbstutil.html",
|
|
60
51
|
"projects/herbstutil/index.html",
|
|
52
|
+
"projects/index.html",
|
|
61
53
|
"projects/lightdni-jssas-toggle.html",
|
|
62
54
|
"projects/lightdni-jssas-toggle/index.html",
|
|
63
55
|
"projects/pagerts.html",
|
|
@@ -68,9 +60,19 @@
|
|
|
68
60
|
"projects/webuser/index.html",
|
|
69
61
|
"rarebert.html",
|
|
70
62
|
"rarebert/index.html",
|
|
63
|
+
"resume/index.html",
|
|
64
|
+
"sitemap.html",
|
|
65
|
+
"sitemap.xml",
|
|
66
|
+
"sitemap/index.html",
|
|
71
67
|
"webuser.html",
|
|
72
|
-
"webuser/index.html"
|
|
68
|
+
"webuser/index.html",
|
|
69
|
+
"wow.html",
|
|
70
|
+
"wow/index.html"
|
|
73
71
|
],
|
|
72
|
+
"violationCount": 0,
|
|
73
|
+
"violations": [],
|
|
74
|
+
"rehashOnlyCount": 0,
|
|
75
|
+
"rehashOnly": [],
|
|
74
76
|
"liveMatchCount": 0,
|
|
75
77
|
"liveMatched": []
|
|
76
78
|
}
|
package/render.yaml
CHANGED
|
@@ -5,7 +5,17 @@ services:
|
|
|
5
5
|
envVars:
|
|
6
6
|
- key: NODE_VERSION
|
|
7
7
|
value: 22.22.1
|
|
8
|
-
|
|
8
|
+
# Deploy builds are deliberately cheap and side-effect-free:
|
|
9
|
+
# - no content regeneration — committed snapshots (soundcloud.json et
|
|
10
|
+
# al.) ship exactly as build:local produced and committed them;
|
|
11
|
+
# - no checksums/drift pipeline — the committed manifest + drift
|
|
12
|
+
# report (public/, copied into dist/ by vite) are served as-is; the
|
|
13
|
+
# live-baseline pipeline re-runs where it belongs (CI, build:local).
|
|
14
|
+
# The static gate below fails the deploy before ANY install/build
|
|
15
|
+
# compute when the uploaded build's drift report is missing, corrupt,
|
|
16
|
+
# or reports unresolved violations (verify-policy.mjs needs no
|
|
17
|
+
# node_modules — node builtins only).
|
|
18
|
+
buildCommand: git submodule update --init --recursive && npm run verify:policy && npm install && npm --prefix xp.css install --no-audit --no-fund && npm --prefix xp.css run build && npm run build
|
|
9
19
|
staticPublishPath: ./dist
|
|
10
20
|
routes:
|
|
11
21
|
- type: redirect
|
|
@@ -13,6 +13,13 @@
|
|
|
13
13
|
* stable entry is a silent drift regression — the unsafe failure
|
|
14
14
|
* mode for a drift detector.
|
|
15
15
|
*
|
|
16
|
+
* Pages generated by the webapp are NOT listed here: the build itself
|
|
17
|
+
* declares them in `dist/.generated.json` (emitted by
|
|
18
|
+
* routeSkeletonsPlugin — one entry per generated page, including future
|
|
19
|
+
* routes and project pages), and write-dist-checksums.mjs auto-marks
|
|
20
|
+
* every listed path as mutable. Only copied/refresh-varying artifacts
|
|
21
|
+
* (content subtrees, LFS blobs, self-generated sidecars) are listed.
|
|
22
|
+
*
|
|
16
23
|
* `checksums.txt` itself is excluded from the manifest (see
|
|
17
24
|
* write-dist-checksums.mjs), so it does not need to appear here. It is
|
|
18
25
|
* listed for documentation completeness and to guard against it ever
|
|
@@ -21,28 +28,6 @@
|
|
|
21
28
|
* Paths are relative to `dist/` and use forward slashes.
|
|
22
29
|
*/
|
|
23
30
|
export const MUTABLE_PATHS = Object.freeze([
|
|
24
|
-
"index.html",
|
|
25
|
-
"404.html",
|
|
26
|
-
"404/index.html",
|
|
27
|
-
"addons.html",
|
|
28
|
-
"addons/index.html",
|
|
29
|
-
"blog.html",
|
|
30
|
-
"blog/index.html",
|
|
31
|
-
"contact.html",
|
|
32
|
-
"contact/index.html",
|
|
33
|
-
"music.html",
|
|
34
|
-
"music/index.html",
|
|
35
|
-
"resume/index.html",
|
|
36
|
-
"sitemap.xml",
|
|
37
|
-
"sitemap.html",
|
|
38
|
-
"sitemap/index.html",
|
|
39
|
-
"wow.html",
|
|
40
|
-
"wow/index.html",
|
|
41
|
-
// new pages - allowed as NEW until baseline is updated
|
|
42
|
-
"pagerts.html",
|
|
43
|
-
"pagerts/index.html",
|
|
44
|
-
"projects.html",
|
|
45
|
-
"projects/index.html",
|
|
46
31
|
// Blog post content: posts (.md), attachments, and embedded documents
|
|
47
32
|
// are authored content. Publishing a new post or editing an existing
|
|
48
33
|
// one is a legitimate content change, never STABLE-invariant drift,
|
|
@@ -58,7 +43,13 @@ export const MUTABLE_PATHS = Object.freeze([
|
|
|
58
43
|
// every build (generatedAt, violation counts), so it changes each run.
|
|
59
44
|
"documents/drift-report.json",
|
|
60
45
|
"checksums.txt",
|
|
46
|
+
// Vite-emitted bundles: content-hashed names, and chunk hashing/module
|
|
47
|
+
// ordering can legitimately vary between rebuilds of identical inputs
|
|
48
|
+
// ("rebuild noise"). Covers every chunk vite emits under assets/
|
|
49
|
+
// (index-*.css, toastify-*.css, *.js). Hand-copied public/ files land
|
|
50
|
+
// at the dist ROOT, never in assets/, so they stay STABLE.
|
|
61
51
|
"assets/*.js",
|
|
52
|
+
"assets/*.css",
|
|
62
53
|
]);
|
|
63
54
|
|
|
64
55
|
export const MUTABLE_PATH_SET = Object.freeze(new Set(MUTABLE_PATHS));
|