website-xp-phone 2.2.1 → 2.2.11

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.
Files changed (69) hide show
  1. package/.github/workflows/ci.yml +8 -0
  2. package/Makefile +5 -1
  3. package/README.md +9 -0
  4. package/build/routes.ts +27 -10
  5. package/package.json +2 -1
  6. package/public/Click.ogg +0 -0
  7. package/public/addons/rage-volley.txt +1 -1
  8. package/public/addons/rueg-wa-druid.txt +1 -1
  9. package/public/addons/rueg-wa-mage.txt +1 -1
  10. package/public/addons/rueg-wa-paladin.txt +1 -0
  11. package/public/addons/rueg-wa-priest.txt +1 -1
  12. package/public/addons/rueg-wa-rueg.txt +1 -1
  13. package/public/addons/rueg-wa-shaman.txt +1 -1
  14. package/public/blog/random/branch.md +29 -0
  15. package/public/blog/random/google.md +25 -0
  16. package/public/checksums.txt +70 -47
  17. package/public/documents/drift-report.json +46 -148
  18. package/public/loading.css +7 -0
  19. package/scripts/asset-reference.mjs +37 -0
  20. package/scripts/mutable-assets.mjs +46 -39
  21. package/scripts/refresh-soundcloud.mjs +152 -414
  22. package/scripts/verify-policy.mjs +206 -0
  23. package/scripts/write-dist-checksums.mjs +251 -135
  24. package/src/content/addons.json +13 -17
  25. package/src/content/blog.json +5 -26
  26. package/src/content/characters.json +6 -6
  27. package/src/content/configs.json +6 -2
  28. package/src/content/index.ts +105 -12
  29. package/src/content/pages.json +10 -1
  30. package/src/content/projects/development.json +9 -1
  31. package/src/content/projects/doftiles.json +9 -1
  32. package/src/content/projects/frontend.json +9 -1
  33. package/src/content/projects/graphbrowser.json +9 -1
  34. package/src/content/projects/herbstutil.json +93 -4
  35. package/src/content/projects/lightdni-jssas-toggle.json +9 -1
  36. package/src/content/projects/pagerts.json +13 -2
  37. package/src/content/projects/rarebert.json +12 -2
  38. package/src/content/projects/webuser.json +9 -1
  39. package/src/content/schema.ts +10 -1
  40. package/src/content/sections.json +2 -3
  41. package/src/content/soundcloud.json +204 -72
  42. package/src/lib/audio.ts +14 -0
  43. package/src/lib/clippy.ts +1 -7
  44. package/src/lib/embeds.ts +1 -1
  45. package/src/lib/musicSchema.ts +1 -0
  46. package/src/main.tsx +8 -0
  47. package/src/pages/MusicPage.tsx +0 -1
  48. package/src/pages/SitemapPage.tsx +1 -1
  49. package/src/pages/WowPage.tsx +1 -1
  50. package/src/shell/App.tsx +4 -1
  51. package/src/styles/extras.css +85 -30
  52. package/src/styles/layout.css +27 -18
  53. package/src/styles/window.css +53 -50
  54. package/src/themes/pageSlide/index.ts +115 -13
  55. package/src/themes/pageSlide/pageSlide.css +99 -6
  56. package/src/window/Embed.tsx +3 -1
  57. package/src/window/MaximizedWindow.tsx +250 -0
  58. package/src/window/OkButton.tsx +6 -1
  59. package/src/window/PageWindows.tsx +3 -9
  60. package/src/window/Window.tsx +129 -53
  61. package/src/window/model.ts +22 -0
  62. package/src/window/state.tsx +54 -30
  63. package/test/asset-reference.test.js +53 -0
  64. package/test/content.test.js +60 -6
  65. package/test/mutable-assets.test.js +27 -0
  66. package/test/verify-policy.test.js +92 -0
  67. package/tsconfig.node.tsbuildinfo +1 -1
  68. package/tsconfig.tsbuildinfo +1 -1
  69. package/xp.css/README.md +10 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "baselineUrl": "https://akinevz.com/checksums.txt",
3
- "generatedAt": "2026-10-20T14:00:28.535Z",
3
+ "generatedAt": "2026-10-23T21:21:29.982Z",
4
4
  "mutablePaths": [
5
5
  "index.html",
6
6
  "404.html",
@@ -23,154 +23,52 @@
23
23
  "pagerts/index.html",
24
24
  "projects.html",
25
25
  "projects/index.html",
26
+ "blog/",
27
+ "stories/",
26
28
  "checksums.txt",
27
29
  "assets/*.js"
28
30
  ],
29
- "violationCount": 24,
30
- "violations": [
31
- {
32
- "relPath": "Click.ogg",
33
- "status": "NEW",
34
- "prev": null,
35
- "next": "d92d71deb2164f1f11ca75607db32012eda31dc8f70afb3254288b4ed390d089"
36
- },
37
- {
38
- "relPath": "assets/index-FJbqpsQq.css",
39
- "status": "NEW",
40
- "prev": null,
41
- "next": "f9740eaec47b01c4c8c555e137be75be6dbaf76d391048a866706594ec67017c"
42
- },
43
- {
44
- "relPath": "configs.html",
45
- "status": "NEW",
46
- "prev": null,
47
- "next": "61fd7b09bdf7075cb9bae18399a66c3cef3249e40f9c7158872c24a7b3100eed"
48
- },
49
- {
50
- "relPath": "configs/index.html",
51
- "status": "NEW",
52
- "prev": null,
53
- "next": "61fd7b09bdf7075cb9bae18399a66c3cef3249e40f9c7158872c24a7b3100eed"
54
- },
55
- {
56
- "relPath": "images/development-1.png",
57
- "status": "NEW",
58
- "prev": null,
59
- "next": "1ba9c502f2c09b33c24bb497209db0404eac0cb2751e012dfa14ce6cf3e3bb56"
60
- },
61
- {
62
- "relPath": "images/herbst-1.png",
63
- "status": "NEW",
64
- "prev": null,
65
- "next": "20f1133b9d5db0bfbc9a02fb3fee81e7c2c43179382cbfd74a3b8534e048869e"
66
- },
67
- {
68
- "relPath": "images/herbst-2.png",
69
- "status": "NEW",
70
- "prev": null,
71
- "next": "96fc3f0c5683091b03219757a63768e48d0f399361d484523dbe18b651c58fb9"
72
- },
73
- {
74
- "relPath": "images/herbst-3.png",
75
- "status": "NEW",
76
- "prev": null,
77
- "next": "99fb31230e4e5d681e89cce167cafd454c110a6b0b67f4ab05c2c82bcb27304a"
78
- },
79
- {
80
- "relPath": "projects/development.html",
81
- "status": "CHANGED",
82
- "prev": "d2f6ea0f29c8805ca9ebb6864b65be048897bc56da3b2e603ccc1239af4e683f",
83
- "next": "e7c90e3cdd1d544f97bd05b4072a7ae7fb81ba3bbb1c3c64d683213f55fcf9c4"
84
- },
85
- {
86
- "relPath": "projects/development/index.html",
87
- "status": "CHANGED",
88
- "prev": "d2f6ea0f29c8805ca9ebb6864b65be048897bc56da3b2e603ccc1239af4e683f",
89
- "next": "e7c90e3cdd1d544f97bd05b4072a7ae7fb81ba3bbb1c3c64d683213f55fcf9c4"
90
- },
91
- {
92
- "relPath": "projects/doftiles.html",
93
- "status": "CHANGED",
94
- "prev": "edda434db224f799caa5d42cdeb86540a70c219fa7b2ae5022b94e8916637472",
95
- "next": "7068dc16880667a1a8c73a05caffb1cfd4a7cdf76b58e2139dfa9c9361194f48"
96
- },
97
- {
98
- "relPath": "projects/doftiles/index.html",
99
- "status": "CHANGED",
100
- "prev": "edda434db224f799caa5d42cdeb86540a70c219fa7b2ae5022b94e8916637472",
101
- "next": "7068dc16880667a1a8c73a05caffb1cfd4a7cdf76b58e2139dfa9c9361194f48"
102
- },
103
- {
104
- "relPath": "projects/frontend.html",
105
- "status": "CHANGED",
106
- "prev": "ea1f5cefe0c23d645953223499ab22c25c855edd274e3ece17840c8d132b0de8",
107
- "next": "c6ec10264fa5b04a47ab4646a7e1b0f96cfbcc65bc27ef6f9252bd3a1d09057b"
108
- },
109
- {
110
- "relPath": "projects/frontend/index.html",
111
- "status": "CHANGED",
112
- "prev": "ea1f5cefe0c23d645953223499ab22c25c855edd274e3ece17840c8d132b0de8",
113
- "next": "c6ec10264fa5b04a47ab4646a7e1b0f96cfbcc65bc27ef6f9252bd3a1d09057b"
114
- },
115
- {
116
- "relPath": "projects/graphbrowser.html",
117
- "status": "CHANGED",
118
- "prev": "65978ffa7afb7c7ee31f53c4f0336f5124f53e8c55237c47fb0b671b25fc1579",
119
- "next": "6b16fe1851cb95d75e6c7f7cd3bc03392d1684cb804b894c2bfff3ce27e281b4"
120
- },
121
- {
122
- "relPath": "projects/graphbrowser/index.html",
123
- "status": "CHANGED",
124
- "prev": "65978ffa7afb7c7ee31f53c4f0336f5124f53e8c55237c47fb0b671b25fc1579",
125
- "next": "6b16fe1851cb95d75e6c7f7cd3bc03392d1684cb804b894c2bfff3ce27e281b4"
126
- },
127
- {
128
- "relPath": "projects/herbstutil.html",
129
- "status": "CHANGED",
130
- "prev": "6988cb6bfd571f733395726b31382fd6bc036b393c79dfee3cae59d4c8374001",
131
- "next": "24859550849d8643d224b71ae14d56f6f2403aa2c79dd48cf56c7d575525d7c7"
132
- },
133
- {
134
- "relPath": "projects/herbstutil/index.html",
135
- "status": "CHANGED",
136
- "prev": "6988cb6bfd571f733395726b31382fd6bc036b393c79dfee3cae59d4c8374001",
137
- "next": "24859550849d8643d224b71ae14d56f6f2403aa2c79dd48cf56c7d575525d7c7"
138
- },
139
- {
140
- "relPath": "projects/lightdni-jssas-toggle.html",
141
- "status": "CHANGED",
142
- "prev": "a2e3c69778a1f9dbb9e20f5d38da8d709a6d4d9ef0b67c91b674f5e061ffdaf6",
143
- "next": "e7411a85a83ee29f6669e0854c9071263a77d9afa192cb1e10f6d02887448cd4"
144
- },
145
- {
146
- "relPath": "projects/lightdni-jssas-toggle/index.html",
147
- "status": "CHANGED",
148
- "prev": "a2e3c69778a1f9dbb9e20f5d38da8d709a6d4d9ef0b67c91b674f5e061ffdaf6",
149
- "next": "e7411a85a83ee29f6669e0854c9071263a77d9afa192cb1e10f6d02887448cd4"
150
- },
151
- {
152
- "relPath": "projects/rarebert.html",
153
- "status": "CHANGED",
154
- "prev": "ad05003ca37ca1022ec0857e6e87d00166d6de65833cdb66fe4005bf4caccf98",
155
- "next": "f97c97557fc5a8358b975f618d25f2020357351e0fbee8439ee409595525bb44"
156
- },
157
- {
158
- "relPath": "projects/rarebert/index.html",
159
- "status": "CHANGED",
160
- "prev": "ad05003ca37ca1022ec0857e6e87d00166d6de65833cdb66fe4005bf4caccf98",
161
- "next": "f97c97557fc5a8358b975f618d25f2020357351e0fbee8439ee409595525bb44"
162
- },
163
- {
164
- "relPath": "projects/webuser.html",
165
- "status": "CHANGED",
166
- "prev": "3356fc4952d479bd19f0d0a4e299e64f4a8171f800883b376be74fc50a92f194",
167
- "next": "614b0443920ea55f1938ea030d8555ffd65ecc5cc51589b95e3cfea363a8ad43"
168
- },
169
- {
170
- "relPath": "projects/webuser/index.html",
171
- "status": "CHANGED",
172
- "prev": "3356fc4952d479bd19f0d0a4e299e64f4a8171f800883b376be74fc50a92f194",
173
- "next": "614b0443920ea55f1938ea030d8555ffd65ecc5cc51589b95e3cfea363a8ad43"
174
- }
175
- ]
31
+ "violationCount": 0,
32
+ "violations": [],
33
+ "rehashOnlyCount": 36,
34
+ "rehashOnly": [
35
+ "configs.html",
36
+ "configs/index.html",
37
+ "development.html",
38
+ "development/index.html",
39
+ "doftiles.html",
40
+ "doftiles/index.html",
41
+ "frontend.html",
42
+ "frontend/index.html",
43
+ "graphbrowser.html",
44
+ "graphbrowser/index.html",
45
+ "herbstutil.html",
46
+ "herbstutil/index.html",
47
+ "lightdni-jssas-toggle.html",
48
+ "lightdni-jssas-toggle/index.html",
49
+ "projects/development.html",
50
+ "projects/development/index.html",
51
+ "projects/doftiles.html",
52
+ "projects/doftiles/index.html",
53
+ "projects/frontend.html",
54
+ "projects/frontend/index.html",
55
+ "projects/graphbrowser.html",
56
+ "projects/graphbrowser/index.html",
57
+ "projects/herbstutil.html",
58
+ "projects/herbstutil/index.html",
59
+ "projects/lightdni-jssas-toggle.html",
60
+ "projects/lightdni-jssas-toggle/index.html",
61
+ "projects/pagerts.html",
62
+ "projects/pagerts/index.html",
63
+ "projects/rarebert.html",
64
+ "projects/rarebert/index.html",
65
+ "projects/webuser.html",
66
+ "projects/webuser/index.html",
67
+ "rarebert.html",
68
+ "rarebert/index.html",
69
+ "webuser.html",
70
+ "webuser/index.html"
71
+ ],
72
+ "liveMatchCount": 0,
73
+ "liveMatched": []
176
74
  }
@@ -44,6 +44,13 @@ body:not(.styles-loaded) main textarea {
44
44
  }
45
45
  }
46
46
 
47
+ /* The page's own background from the very first paint — the default
48
+ browser white must never show while the app CSS (which carries the
49
+ real theme values) fades in. */
50
+ html {
51
+ background-color: var(--background-color);
52
+ }
53
+
47
54
  body,
48
55
  #root {
49
56
  background-color: var(--mid-color);
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Canonicalization helper for the drift gate in write-dist-checksums.mjs.
3
+ *
4
+ * Vite rewrites every built HTML entry point to point at content-hashed
5
+ * bundle filenames (e.g. `/assets/index-D4oX1XA7.js`). When any bundle's
6
+ * content hash changes, EVERY entry page changes bytes at build time even
7
+ * when its authored content is identical, so a raw SHA-256 comparison
8
+ * between deployments reports false drift on all rebuilt pages.
9
+ *
10
+ * `canonicalizeAssetRefs` strips Vite's 8-character content hash from
11
+ * `/assets/<name>-<hash>.<ext>` references (script `src`, modulepreload
12
+ * `href`, stylesheet `href`, ...) so two builds that differ only in Vite's
13
+ * injected hashes canonicalize to identical text and share one digest.
14
+ * Authored page edits still change the canonical text, so real content
15
+ * drift keeps failing loudly.
16
+ *
17
+ * The canonicalization is applied to built HTML for the drift report only;
18
+ * `checksums.txt` itself keeps raw-byte digests so it remains a verifiable
19
+ * attestation of the served artifact (see doc/IMMUTABLE_DEPLOYS_BLUEPRINT.md).
20
+ */
21
+
22
+ /**
23
+ * Vite's default build asset hash: 8 characters from [A-Za-z0-9_-].
24
+ * Only JS/MJS/CSS asset references under /assets/ are normalized — other
25
+ * references (pages, documents, blog posts) keep their real filenames.
26
+ */
27
+ const VITE_HASHED_ASSET_RE =
28
+ /\/assets\/([\w@./-]+?)-[A-Za-z0-9_-]{8}\.(js|mjs|css)(?=[?"'\s<>)])/g;
29
+
30
+ export function canonicalizeAssetRefs(text) {
31
+ return text.replace(VITE_HASHED_ASSET_RE, "/assets/$1.$2");
32
+ }
33
+
34
+ /** Built artifacts whose drift comparison should canonicalize asset refs. */
35
+ export function isCanonicalizablePath(relPath) {
36
+ return relPath.endsWith(".html");
37
+ }
@@ -21,30 +21,37 @@
21
21
  * Paths are relative to `dist/` and use forward slashes.
22
22
  */
23
23
  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
- "checksums.txt",
47
- "assets/*.js",
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
+ // Blog post content: posts (.md), attachments, and embedded documents
47
+ // are authored content. Publishing a new post or editing an existing
48
+ // one is a legitimate content change, never STABLE-invariant drift,
49
+ // so every artifact under these subtrees is mutable. `stories/` holds
50
+ // documents embedded into posts via blog.json.
51
+ "blog/",
52
+ "stories/",
53
+ "checksums.txt",
54
+ "assets/*.js",
48
55
  ]);
49
56
 
50
57
  export const MUTABLE_PATH_SET = Object.freeze(new Set(MUTABLE_PATHS));
@@ -56,20 +63,20 @@ export const MUTABLE_PATH_SET = Object.freeze(new Set(MUTABLE_PATHS));
56
63
  * are considered mutable (e.g. assets/index- matches assets/index-D4oX1XA7.js).
57
64
  */
58
65
  export function isMutablePath(relPath) {
59
- if (MUTABLE_PATH_SET.has(relPath)) {
60
- return true;
66
+ if (MUTABLE_PATH_SET.has(relPath)) {
67
+ return true;
68
+ }
69
+ // Check if path starts with any mutable prefix pattern
70
+ for (const pattern of MUTABLE_PATHS) {
71
+ if (relPath.startsWith(pattern)) {
72
+ return true;
61
73
  }
62
- // Check if path starts with any mutable prefix pattern
63
- for (const pattern of MUTABLE_PATHS) {
64
- if (relPath.startsWith(pattern)) {
65
- return true;
66
- }
67
- if (pattern.includes('*')) {
68
- const [prefix, suffix] = pattern.split('*');
69
- if (relPath.startsWith(prefix) && relPath.endsWith(suffix)) {
70
- return true;
71
- }
72
- }
74
+ if (pattern.includes("*")) {
75
+ const [prefix, suffix] = pattern.split("*");
76
+ if (relPath.startsWith(prefix) && relPath.endsWith(suffix)) {
77
+ return true;
78
+ }
73
79
  }
74
- return false;
75
- }
80
+ }
81
+ return false;
82
+ }