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.
- package/.github/workflows/ci.yml +8 -0
- package/Makefile +5 -1
- package/README.md +9 -0
- package/build/routes.ts +27 -10
- package/package.json +2 -1
- package/public/Click.ogg +0 -0
- package/public/addons/rage-volley.txt +1 -1
- package/public/addons/rueg-wa-druid.txt +1 -1
- package/public/addons/rueg-wa-mage.txt +1 -1
- package/public/addons/rueg-wa-paladin.txt +1 -0
- package/public/addons/rueg-wa-priest.txt +1 -1
- package/public/addons/rueg-wa-rueg.txt +1 -1
- package/public/addons/rueg-wa-shaman.txt +1 -1
- package/public/blog/random/branch.md +29 -0
- package/public/blog/random/google.md +25 -0
- package/public/checksums.txt +70 -47
- package/public/documents/drift-report.json +46 -148
- package/public/loading.css +7 -0
- package/scripts/asset-reference.mjs +37 -0
- package/scripts/mutable-assets.mjs +46 -39
- package/scripts/refresh-soundcloud.mjs +152 -414
- package/scripts/verify-policy.mjs +206 -0
- package/scripts/write-dist-checksums.mjs +251 -135
- package/src/content/addons.json +13 -17
- package/src/content/blog.json +5 -26
- package/src/content/characters.json +6 -6
- package/src/content/configs.json +6 -2
- package/src/content/index.ts +105 -12
- package/src/content/pages.json +10 -1
- package/src/content/projects/development.json +9 -1
- package/src/content/projects/doftiles.json +9 -1
- package/src/content/projects/frontend.json +9 -1
- package/src/content/projects/graphbrowser.json +9 -1
- package/src/content/projects/herbstutil.json +93 -4
- package/src/content/projects/lightdni-jssas-toggle.json +9 -1
- package/src/content/projects/pagerts.json +13 -2
- package/src/content/projects/rarebert.json +12 -2
- package/src/content/projects/webuser.json +9 -1
- package/src/content/schema.ts +10 -1
- package/src/content/sections.json +2 -3
- package/src/content/soundcloud.json +204 -72
- package/src/lib/audio.ts +14 -0
- package/src/lib/clippy.ts +1 -7
- package/src/lib/embeds.ts +1 -1
- package/src/lib/musicSchema.ts +1 -0
- package/src/main.tsx +8 -0
- package/src/pages/MusicPage.tsx +0 -1
- package/src/pages/SitemapPage.tsx +1 -1
- package/src/pages/WowPage.tsx +1 -1
- package/src/shell/App.tsx +4 -1
- package/src/styles/extras.css +85 -30
- package/src/styles/layout.css +27 -18
- package/src/styles/window.css +53 -50
- package/src/themes/pageSlide/index.ts +115 -13
- package/src/themes/pageSlide/pageSlide.css +99 -6
- package/src/window/Embed.tsx +3 -1
- package/src/window/MaximizedWindow.tsx +250 -0
- package/src/window/OkButton.tsx +6 -1
- package/src/window/PageWindows.tsx +3 -9
- package/src/window/Window.tsx +129 -53
- package/src/window/model.ts +22 -0
- package/src/window/state.tsx +54 -30
- package/test/asset-reference.test.js +53 -0
- package/test/content.test.js +60 -6
- package/test/mutable-assets.test.js +27 -0
- package/test/verify-policy.test.js +92 -0
- package/tsconfig.node.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/xp.css/README.md +10 -0
package/src/content/addons.json
CHANGED
|
@@ -7,45 +7,46 @@
|
|
|
7
7
|
"heading": "Rueg WeakAuras — class aura sets",
|
|
8
8
|
"content": [
|
|
9
9
|
{
|
|
10
|
-
"heading": "Rogue (v5.0.
|
|
10
|
+
"heading": "Rogue (v5.0.5)",
|
|
11
11
|
"content": "Weak Aura tracker for GCD, energy tickrate, and range",
|
|
12
12
|
"status": "available",
|
|
13
13
|
"link": "/addons/rueg-wa-rueg.txt"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
|
-
"heading": "Mage (
|
|
16
|
+
"heading": "Mage (v5.0.5)",
|
|
17
17
|
"content": "Weak Aura tracker for GCD, energy tickrate, and range",
|
|
18
18
|
"status": "available",
|
|
19
19
|
"link": "/addons/rueg-wa-mage.txt"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
|
-
"heading": "Priest (v5.0.
|
|
22
|
+
"heading": "Priest (v5.0.5)",
|
|
23
23
|
"content": "Weak Aura tracker for GCD, mana tickrate, and range",
|
|
24
24
|
"status": "available",
|
|
25
25
|
"link": "/addons/rueg-wa-priest.txt"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
"heading": "Warrior (
|
|
28
|
+
"heading": "Warrior (v5.0.5)",
|
|
29
29
|
"content": "Weak Aura tracker for GCD, rage starvation, and range",
|
|
30
30
|
"status": "available",
|
|
31
31
|
"link": "/addons/rage-volley.txt"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
"heading": "Druid (v5.0.
|
|
34
|
+
"heading": "Druid (v5.0.5)",
|
|
35
35
|
"content": "Weak Aura tracker for swing, energy recharge, and range",
|
|
36
36
|
"status": "available",
|
|
37
37
|
"link": "/addons/rueg-wa-druid.txt"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
-
"heading": "Shaman (v5.0.
|
|
40
|
+
"heading": "Shaman (v5.0.5)",
|
|
41
41
|
"content": "Weak Aura tracker for swing, energy recharge, and range",
|
|
42
42
|
"status": "available",
|
|
43
43
|
"link": "/addons/rueg-wa-shaman.txt"
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
"heading": "Paladin (
|
|
46
|
+
"heading": "Paladin (v5.0.5)",
|
|
47
47
|
"content": "Weak Aura tracker for GCD, mana starvation, and range",
|
|
48
|
-
"status": "
|
|
48
|
+
"status": "available",
|
|
49
|
+
"link": "/addons/rueg-wa-paladin.txt"
|
|
49
50
|
}
|
|
50
51
|
]
|
|
51
52
|
},
|
|
@@ -83,21 +84,16 @@
|
|
|
83
84
|
"content": [
|
|
84
85
|
{
|
|
85
86
|
"heading": "Rueg Distributable Config (dist.7z)",
|
|
86
|
-
"content": "
|
|
87
|
-
"status": "available"
|
|
88
|
-
"link": "/dist.7z"
|
|
87
|
+
"content": "See bottom of this page.",
|
|
88
|
+
"status": "available"
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
|
-
"heading": "addons
|
|
91
|
+
"heading": "addons list",
|
|
92
92
|
"content": [
|
|
93
93
|
"",
|
|
94
94
|
""
|
|
95
95
|
],
|
|
96
|
-
"status": "available
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"heading": "more addons coming after I finish my work",
|
|
100
|
-
"link": "https://akinevz.dev/"
|
|
96
|
+
"status": "available"
|
|
101
97
|
}
|
|
102
98
|
]
|
|
103
99
|
}
|
package/src/content/blog.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"heading": "kine's blog posts",
|
|
4
4
|
"content": [
|
|
5
5
|
{
|
|
6
|
-
"heading": "Stories",
|
|
6
|
+
"heading": "Stories / Writing",
|
|
7
7
|
"content": [
|
|
8
8
|
"### Hot Action under a Cold Moon",
|
|
9
9
|
"Click here to read",
|
|
@@ -60,28 +60,13 @@
|
|
|
60
60
|
"theme": "experimental",
|
|
61
61
|
"link": "/images/booger_Boogie%20Long.gif"
|
|
62
62
|
},
|
|
63
|
-
"blog operating normally! :D",
|
|
64
|
-
{
|
|
65
|
-
"heading": "Rueg Config published! (#world of warcraft, #addons)",
|
|
66
|
-
"theme": "open",
|
|
67
|
-
"content": [
|
|
68
|
-
"Packed up the full Rueg configuration into a distributable archive — addons, WeakAuras, and profiles in one drop.",
|
|
69
|
-
"Grab it from the [download page](/wow#download) or the [addons page](/addons).",
|
|
70
|
-
"I had a bad copy of the zip stuck in website cache:",
|
|
71
|
-
"If you downloaded an archive with 2 folders",
|
|
72
|
-
"Delete it, the correct dist.7z should have 3",
|
|
73
|
-
"You can skip copying WTF/ and just copy interface",
|
|
74
|
-
{
|
|
75
|
-
"heading": "Open the download page",
|
|
76
|
-
"link": "/wow#download"
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
},
|
|
80
63
|
{
|
|
81
64
|
"heading": "Runisch Glossary (#russian, #glossary, #tool)",
|
|
82
65
|
"content": [
|
|
83
66
|
{
|
|
84
|
-
"
|
|
67
|
+
"heading": "An interactive SQLite-backed REPL for storing and retrieving Runisch terms.",
|
|
68
|
+
"theme": "centered",
|
|
69
|
+
"content": "with translation, usage examples, and tags",
|
|
85
70
|
"embed": "/blog/рунисч-глоссарий.md"
|
|
86
71
|
}
|
|
87
72
|
]
|
|
@@ -201,13 +186,7 @@
|
|
|
201
186
|
]
|
|
202
187
|
},
|
|
203
188
|
{
|
|
204
|
-
"heading": "twelfth post (#
|
|
205
|
-
"content": [
|
|
206
|
-
"Although no verified cases of official ElvUI performing malicious opaque bank transfers (gold+items) have ever been publicly confirmed by Blizzard or the developer, concerns about its security have circulated for years. While the 2014 ElvUI backdoor - a debug command that allowed the addon's developers to remotely execute arbitrary Lua code on users' clients - was widely documented across gaming forums, Reddit, and tech blogs at the time and subsequently removed from official releases, similar malicious behavior reportedly persisted years later. During the World of Warcraft Classic Hardcore rush, one player encountered what appeared to be surreptitious opaque bank transfer functionality (gold+items) while using an ElvUI installation, an incident captured on livestream that raised fresh questions about the risks of third-party UI modifications and unverified addon distributions"
|
|
207
|
-
]
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
"heading": "thirteenth post (#mixing, #phase, #technique, #audio, #music)",
|
|
189
|
+
"heading": "twelfth post (#mixing, #phase, #technique, #audio, #music)",
|
|
211
190
|
"content": [
|
|
212
191
|
"i found a mixing technique by accident and now i can't stop using it",
|
|
213
192
|
"* i usually build my final mixes from 3 \"core\" channels",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"heading": "
|
|
2
|
+
"heading": "Gallery",
|
|
3
3
|
"content": [
|
|
4
4
|
{
|
|
5
5
|
"heading": "rueg",
|
|
6
|
-
"theme":
|
|
6
|
+
"theme": "centered",
|
|
7
7
|
"content": [
|
|
8
8
|
"<img src=\"/images/rueg1.png\" alt=\"rueg\" style=\"width: auto; height: auto; max-height: 600px;\" />",
|
|
9
9
|
"<img src=\"/images/rueg2.png\" alt=\"rueg\" style=\"width: auto; height: auto; max-height: 600px;\" />"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"heading": "ateric",
|
|
14
|
-
"theme":
|
|
14
|
+
"theme": "centered",
|
|
15
15
|
"content": [
|
|
16
16
|
"<img src=\"/images/Ateric1.png\" alt=\"ateric\" style=\"width: auto; height: auto; max-height: 600px;\" />",
|
|
17
17
|
"<img src=\"/images/Ateric2.png\" alt=\"ateric\" style=\"width: auto; height: auto; max-height: 600px;\" />"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"heading": "equal",
|
|
22
|
-
"theme":
|
|
22
|
+
"theme": "centered",
|
|
23
23
|
"content": [
|
|
24
24
|
"<img src=\"/images/equal1.png\" alt=\"equal\" style=\"width: auto; height: auto; max-height: 600px;\" />"
|
|
25
25
|
]
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"heading": "kogg",
|
|
29
|
-
"theme":
|
|
29
|
+
"theme": "centered",
|
|
30
30
|
"content": [
|
|
31
31
|
"<img src=\"/images/kogg1.png\" alt=\"kogg\" style=\"width: auto; height: auto; max-height: 600px;\" />",
|
|
32
32
|
"<img src=\"/images/kogg2.png\" alt=\"kogg\" style=\"width: auto; height: auto; max-height: 600px;\" />"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"heading": "brúdder",
|
|
37
|
-
"theme":
|
|
37
|
+
"theme": "centered",
|
|
38
38
|
"content": [
|
|
39
39
|
"<img src=\"/images/brudder.png\" alt=\"brúdder\" style=\"width: auto; height: auto; max-height: 600px;\" />"
|
|
40
40
|
]
|
package/src/content/configs.json
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
"heading": "Linux Configs",
|
|
7
7
|
"content": [
|
|
8
8
|
"My Linux setup files — a window-manager configuration based on herbstluftwm, documented in the doftiles project.",
|
|
9
|
-
"[doftiles project](/projects/doftiles)",
|
|
10
9
|
"[github.com/akinevz2/doftiles](https://github.com/akinevz2/doftiles)",
|
|
11
10
|
{
|
|
12
11
|
"heading": "Gallery",
|
|
@@ -22,7 +21,12 @@
|
|
|
22
21
|
"link": "/projects/doftiles"
|
|
23
22
|
},
|
|
24
23
|
{
|
|
25
|
-
"heading": "
|
|
24
|
+
"heading": "WoW Configs",
|
|
25
|
+
"content": [
|
|
26
|
+
"My World of Warcraft configuration files — the window layout of Rueg's UI, the Simple WoW UI Pack, running wow classic.",
|
|
27
|
+
"[everything world of warcraft](/wow)",
|
|
28
|
+
{ "include": "characters" }
|
|
29
|
+
],
|
|
26
30
|
"link": "/wow"
|
|
27
31
|
}
|
|
28
32
|
]
|
package/src/content/index.ts
CHANGED
|
@@ -23,22 +23,115 @@ export const projects = Object.values(projectModules).sort((a, b) =>
|
|
|
23
23
|
a.title.localeCompare(b.title),
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Short-hand URL for a project: /<slug>. Redirects to the canonical
|
|
28
|
+
* /projects/<slug> route via the same alias mechanism pages.json uses.
|
|
29
|
+
*/
|
|
30
|
+
export const projectShortPath = (project: Project) => `/${project.slug}`;
|
|
31
|
+
|
|
32
|
+
function projectRoute(project: Project): Route {
|
|
33
|
+
return {
|
|
30
34
|
path: projectPath(project),
|
|
31
35
|
title: project.title,
|
|
32
36
|
description: project.description,
|
|
33
37
|
page: "ProjectPage",
|
|
34
38
|
menu: false,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Alias route: hidden, redirects to the canonical project route. */
|
|
43
|
+
function projectAliasRoute(project: Project): Route {
|
|
44
|
+
return {
|
|
45
|
+
path: projectShortPath(project),
|
|
46
|
+
title: project.title,
|
|
47
|
+
description: project.description,
|
|
48
|
+
page: "ProjectPage",
|
|
49
|
+
alias: projectPath(project),
|
|
50
|
+
menu: false,
|
|
51
|
+
hidden: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Static pages from pages.json, kept separate so project aliases can check clashes. */
|
|
56
|
+
const pageRoutes: Route[] = pagesJson as Route[];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* One canonical route per project (/projects/<slug>) plus a hidden
|
|
60
|
+
* short-hand alias route (/<slug>) redirecting to it. The alias is
|
|
61
|
+
* skipped when the slug would clash with an existing route path.
|
|
62
|
+
*/
|
|
63
|
+
const projectRoutes: Route[] = projects.flatMap((project): Route[] => {
|
|
64
|
+
const taken =
|
|
65
|
+
pageRoutes.some((page) => page.path === projectShortPath(project)) ||
|
|
66
|
+
projects.some(
|
|
67
|
+
(other) =>
|
|
68
|
+
other !== project && projectPath(other) === projectShortPath(project),
|
|
69
|
+
);
|
|
70
|
+
return taken
|
|
71
|
+
? [projectRoute(project)]
|
|
72
|
+
: [projectRoute(project), projectAliasRoute(project)];
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export const routes: Route[] = [...pageRoutes, ...projectRoutes];
|
|
76
|
+
/* ------------------------------------------------------------------ includes
|
|
77
|
+
* A content file can embed another content file's window tree with an
|
|
78
|
+
* include directive instead of duplicating it:
|
|
79
|
+
*
|
|
80
|
+
* { "include": "characters" } → the top-level Section of characters.json
|
|
81
|
+
*
|
|
82
|
+
* Directives are expanded at load time, recursively (an included tree may
|
|
83
|
+
* itself contain directives). Unknown or circular directives throw during
|
|
84
|
+
* module load, failing the build loudly instead of rendering an opaque
|
|
85
|
+
* object. Each file may be included multiple times across sibling items;
|
|
86
|
+
* cycles are broken by the seen-set, which tracks one inclusion chain.
|
|
87
|
+
*/
|
|
88
|
+
const includeRegistry: Record<string, Section> = {
|
|
89
|
+
characters: charactersJson as Section,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
function expandContent(
|
|
93
|
+
content: NonNullable<Section["content"]>,
|
|
94
|
+
ancestors: Set<string>,
|
|
95
|
+
): NonNullable<Section["content"]> {
|
|
96
|
+
if (typeof content === "string") return content;
|
|
97
|
+
const items = Array.isArray(content) ? content : [content];
|
|
98
|
+
return items.map((item) => {
|
|
99
|
+
if (typeof item !== "object" || item === null) return item;
|
|
100
|
+
if ("include" in item) {
|
|
101
|
+
const name = item.include;
|
|
102
|
+
if (typeof name !== "string" || !includeRegistry[name]) {
|
|
103
|
+
throw new Error(`Unknown include directive: ${String(name)}`);
|
|
104
|
+
}
|
|
105
|
+
if (ancestors.has(name)) {
|
|
106
|
+
throw new Error(`Circular include directive: ${name}`);
|
|
107
|
+
}
|
|
108
|
+
const target = includeRegistry[name];
|
|
109
|
+
const chain = new Set(ancestors);
|
|
110
|
+
chain.add(name);
|
|
111
|
+
return expandSection(target, chain);
|
|
112
|
+
}
|
|
113
|
+
if ("banner" in item || "url" in item) return item;
|
|
114
|
+
return expandSection(item as Section, ancestors);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Expands a nested section, preserving the absence of content exactly. */
|
|
119
|
+
function expandSection(section: Section, ancestors: Set<string>): Section {
|
|
120
|
+
if (!section.content) return section;
|
|
121
|
+
return { ...section, content: expandContent(section.content, ancestors) };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Expands every include directive in the tree rooted at `section`. */
|
|
125
|
+
const resolveIncludes = (section: Section): Section => {
|
|
126
|
+
if (!section.content) return section;
|
|
127
|
+
return { ...section, content: expandContent(section.content, new Set()) };
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const sections = resolveIncludes(sectionsJson as Section);
|
|
131
|
+
export const contacts = resolveIncludes(contactsJson as Section);
|
|
132
|
+
export const addons = resolveIncludes(addonsJson as Section);
|
|
133
|
+
export const configs = resolveIncludes(configsJson as Section);
|
|
134
|
+
export const characters = resolveIncludes(charactersJson as Section);
|
|
135
|
+
export const blog = resolveIncludes(blogJson as Section);
|
|
43
136
|
export const soundcloud = soundcloudJson as SoundCloudData;
|
|
44
137
|
export const musicExt = musicExtJson;
|
package/src/content/pages.json
CHANGED
|
@@ -37,11 +37,20 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"path": "/wow",
|
|
40
|
-
"menuLabel": "wow addons",
|
|
40
|
+
"menuLabel": "wow & addons",
|
|
41
41
|
"title": "everything world of warcraft",
|
|
42
42
|
"description": "my addons and configurations for wow classic",
|
|
43
43
|
"page": "WowPage"
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
"path": "/addons",
|
|
47
|
+
"title": "wow addons",
|
|
48
|
+
"description": "short-hand redirect to the world of warcraft page",
|
|
49
|
+
"page": "AddonsPage",
|
|
50
|
+
"alias": "/wow#addons",
|
|
51
|
+
"menu": false,
|
|
52
|
+
"hidden": true
|
|
53
|
+
},
|
|
45
54
|
{
|
|
46
55
|
"path": "/music",
|
|
47
56
|
"menuLabel": "music",
|
|
@@ -10,7 +10,15 @@
|
|
|
10
10
|
"It contains various projects and configurations that power my personal website.",
|
|
11
11
|
"I work inside a WSL Ubuntu environment, with the development repository mounted as a devcontainer.",
|
|
12
12
|
"",
|
|
13
|
-
"[https://github.com/akinevz2/development](https://github.com/akinevz2/development)"
|
|
13
|
+
"[https://github.com/akinevz2/development](https://github.com/akinevz2/development)",
|
|
14
|
+
{
|
|
15
|
+
"heading": "From the README",
|
|
16
|
+
"theme": "open",
|
|
17
|
+
"content": [
|
|
18
|
+
"The repo runs as a persistent Development Workstation Devcontainer for VS Code.",
|
|
19
|
+
"Ships the latest Git and GitHub CLI, bootstraps Node.js LTS via nvm, restores akinevz2/doftiles into ~/dots, and stows the bar, dunst, herbst, rofi, shell and vim packages with `stow --adopt`."
|
|
20
|
+
]
|
|
21
|
+
}
|
|
14
22
|
]
|
|
15
23
|
}
|
|
16
24
|
}
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
"heading": "doftiles",
|
|
8
8
|
"content": [
|
|
9
9
|
"A window manager setup based on herbstluftwm, almost ready for public use.",
|
|
10
|
-
"[https://github.com/akinevz2/doftiles](https://github.com/akinevz2/doftiles)"
|
|
10
|
+
"[https://github.com/akinevz2/doftiles](https://github.com/akinevz2/doftiles)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"configs for kine@home - Ubuntu deploys are as simple as `make install` now.",
|
|
16
|
+
"Deployed with GNU stow: the repo is cloned into ~/dots and its packages (bar, dunst, herbst, rofi, shell, vim) are adopted into $HOME."
|
|
17
|
+
]
|
|
18
|
+
}
|
|
11
19
|
]
|
|
12
20
|
}
|
|
13
21
|
}
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
"heading": "frontend",
|
|
8
8
|
"content": [
|
|
9
9
|
"The source of this personal website.",
|
|
10
|
-
"[https://github.com/akinevz2/frontend](https://github.com/akinevz2/frontend)"
|
|
10
|
+
"[https://github.com/akinevz2/frontend](https://github.com/akinevz2/frontend)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"Built as a landing page and a point-of-interest for those that stumble upon it: personal storytelling through UI, JSON-driven content that is easy to edit, and small interactive features (windows, modals, media embeds).",
|
|
16
|
+
"React + TypeScript, Vite for development and builds, xp.css for the nostalgia."
|
|
17
|
+
]
|
|
18
|
+
}
|
|
11
19
|
]
|
|
12
20
|
}
|
|
13
21
|
}
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
"heading": "graphbrowser",
|
|
8
8
|
"content": [
|
|
9
9
|
"Describes a website's external dependency graph one layer at a time as structured markdown, with hyperlinks for navigating between graph nodes.",
|
|
10
|
-
"[https://github.com/akinevz2/graphbrowser](https://github.com/akinevz2/graphbrowser)"
|
|
10
|
+
"[https://github.com/akinevz2/graphbrowser](https://github.com/akinevz2/graphbrowser)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"A software package to visualise page dependencies without having to view the page content: the set of navigable items of a webpage, linking from page to page within the World Wide Web.",
|
|
16
|
+
"GraphBrowser is the GUI counterpart of PagerTS, built with Quarkus and web technologies - the same dependency list that pagerts parses with JSDOM into `title`, `url` and `resources`."
|
|
17
|
+
]
|
|
18
|
+
}
|
|
11
19
|
]
|
|
12
20
|
}
|
|
13
21
|
}
|
|
@@ -1,13 +1,102 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "herbstutil",
|
|
3
3
|
"title": "herbstutil",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "A stdin filter that turns the verbose output of herbstclient attr into clean JSON - for scripting the herbstluftwm tiling window manager.",
|
|
5
5
|
"github": "https://github.com/akinevz2/herbstutil",
|
|
6
6
|
"content": {
|
|
7
|
-
"heading": "herbstutil",
|
|
7
|
+
"heading": "herbstutil - JSON bridge to herbstluftwm",
|
|
8
8
|
"content": [
|
|
9
|
-
"
|
|
10
|
-
"[https://github.com/akinevz2/herbstutil](https://github.com/akinevz2/herbstutil)"
|
|
9
|
+
"herbstutil is a small command-line filter that post-processes the output of `herbstclient attr` into clean JSON - so the state of the herbstluftwm window manager can be consumed wherever JSON is spoken.",
|
|
10
|
+
"[https://github.com/akinevz2/herbstutil](https://github.com/akinevz2/herbstutil)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "herbstluftwm in a nutshell",
|
|
13
|
+
"anchor": "herbstluftwm",
|
|
14
|
+
"theme": "open",
|
|
15
|
+
"content": [
|
|
16
|
+
"herbstluftwm is a manual tiling window manager for Linux. Its core idea: the whole desktop is one global object tree - monitors, tags, clients (windows), settings - queried and modified over IPC with the companion tool herbstclient.",
|
|
17
|
+
"The tree is probed with `herbstclient attr <path>`: it prints a short description of the node, its children, and a table of every attribute (typed, writable, hookable).",
|
|
18
|
+
"```sh\n$ herbstclient attr clients. # children of the clients node\n$ herbstclient attr clients.focus. # introspect the focused window\n$ herbstclient attr clients.focus.tag # read a single leaf value\n```",
|
|
19
|
+
"The catch: `attr` output is written for humans first - padded type tables, prose, legends. Great to read, fragile to parse."
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"heading": "What herbstutil does",
|
|
24
|
+
"anchor": "about",
|
|
25
|
+
"status": "early release",
|
|
26
|
+
"theme": "open",
|
|
27
|
+
"content": [
|
|
28
|
+
"herbstutil reads `herbstclient attr` output on stdin and rebuilds it as JSON, preserving the node's shape:",
|
|
29
|
+
"value - the node's description; children - the names of the child nodes; attributes - every attribute as a name-value pair.",
|
|
30
|
+
"Where herbstclient speaks humans, herbstutil speaks machine.",
|
|
31
|
+
{
|
|
32
|
+
"heading": "Usage",
|
|
33
|
+
"theme": "open",
|
|
34
|
+
"content": [
|
|
35
|
+
"herbstutil is a stdin filter built with Bun and bunli, packaged as a single executable:",
|
|
36
|
+
"```sh\n$ herbstclient attr clients. | herbstutil\n$ herbstclient attr clients.focus. | herbstutil --space 2\n```",
|
|
37
|
+
"s, --space <n> - pretty-print with `n` spaces of indentation (default 4)",
|
|
38
|
+
"It refuses to run attached to a terminal: herbstutil always reads from stdin."
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"heading": "Examples",
|
|
45
|
+
"anchor": "examples",
|
|
46
|
+
"theme": "open",
|
|
47
|
+
"content": [
|
|
48
|
+
"The same node, before and after `| herbstutil`.",
|
|
49
|
+
{
|
|
50
|
+
"heading": "Root node: herbstclient attr clients.",
|
|
51
|
+
"theme": "open",
|
|
52
|
+
"content": [
|
|
53
|
+
"Raw:",
|
|
54
|
+
"```text\n$ herbstclient attr clients.\nThe managed windows. For every (managed) window id there is an entry here.\n\n5 children:\n 0x400003.\n 0x700003.\n 0xc00003.\n 0xe80003.\n focus.\n0 attributes.\n .---- type\n | .-- writable\n | | .-- hookable\n V V V\n```",
|
|
55
|
+
"Piped through herbstutil:",
|
|
56
|
+
"```json\n{\n \"value\": \"The managed windows. For every (managed) window id there is an entry here.\",\n \"children\": [\n \"0x400003.\",\n \"0x700003.\",\n \"0xc00003.\",\n \"0xe80003.\",\n \"focus.\"\n ],\n \"attributes\": {}\n}\n```"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"heading": "Node with attributes: herbstclient attr clients.focus.",
|
|
61
|
+
"theme": "open",
|
|
62
|
+
"content": [
|
|
63
|
+
"Raw (excerpt):",
|
|
64
|
+
"```text\n$ herbstclient attr clients.focus.\na managed window\n\n1 child:\n parent_frame.\n24 attributes:\n s - - class = \"Alacritty\"\n b w h decorated = true\n b w h floating = false\n i - h pid = 61763\n s - h tag = \"work\"\n s - h title = \"OC | Customizing opencode and dotfiles\"\n b - h visible = true\n```",
|
|
65
|
+
"Piped through herbstutil (excerpt - all 24 attributes arrive in the JSON):",
|
|
66
|
+
"```json\n{\n \"value\": \"a managed window\",\n \"children\": [\n \"parent_frame.\"\n ],\n \"attributes\": {\n \"class\": \"\\\"Alacritty\\\"\",\n \"decorated\": \"true\",\n \"floating\": \"false\",\n \"pid\": \"61763\",\n \"tag\": \"\\\"work\\\"\",\n \"title\": \"\\\"OC | Customizing opencode and dotfiles\\\"\",\n \"urgent\": \"false\",\n \"visible\": \"true\",\n \"winid\": \"\\\"0x700003\\\"\"\n }\n}\n```",
|
|
67
|
+
"Note how attribute values stay as raw strings - a reminder that everything coming from `attr` is text until you parse it downstream."
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"heading": "Leaf node: herbstclient attr clients.focus.tag",
|
|
72
|
+
"theme": "open",
|
|
73
|
+
"content": [
|
|
74
|
+
"Raw:",
|
|
75
|
+
"```text\n$ herbstclient attr clients.focus.tag\nwork\n```",
|
|
76
|
+
"Piped through herbstutil:",
|
|
77
|
+
"```json\n{\n \"value\": \"work\",\n \"children\": [],\n \"attributes\": {}\n}\n```"
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"heading": "Links",
|
|
84
|
+
"theme": "open",
|
|
85
|
+
"content": [
|
|
86
|
+
{
|
|
87
|
+
"heading": "GitHub repository",
|
|
88
|
+
"link": "https://github.com/akinevz2/herbstutil"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"heading": "herbstluftwm project",
|
|
92
|
+
"link": "https://herbstluftwm.org"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"heading": "herbstclient reference",
|
|
96
|
+
"link": "https://herbstluftwm.org/herbstclient.html"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
11
100
|
]
|
|
12
101
|
}
|
|
13
102
|
}
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
"heading": "lightdni-jssas-toggle",
|
|
8
8
|
"content": [
|
|
9
9
|
"LightDNI (Doesn't Need Integration) provides a simple declarative API for adding a theme toggle to your website.",
|
|
10
|
-
"[https://github.com/akinevz2/lightdni-jssas-toggle](https://github.com/akinevz2/lightdni-jssas-toggle)"
|
|
10
|
+
"[https://github.com/akinevz2/lightdni-jssas-toggle](https://github.com/akinevz2/lightdni-jssas-toggle)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"TypeScript utility package for applying and toggling CSS themes: theme classes and attributes on the root element, dynamic CSS variables, localStorage/cookie persistence, and accessibility metadata (color-scheme and aria-live announcements).",
|
|
16
|
+
"A consolidated one-call setTheme API - dependency-safe, and works in vanilla JS/TS, React, and Vue projects."
|
|
17
|
+
]
|
|
18
|
+
}
|
|
11
19
|
]
|
|
12
20
|
}
|
|
13
21
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "pagerts",
|
|
3
|
-
"path": "/pagerts",
|
|
4
3
|
"title": "pagerts",
|
|
5
4
|
"description": "A TypeScript CLI that lists every link and resource a webpage references, as plain JSON.",
|
|
6
5
|
"github": "https://github.com/akinevz2/pagerts",
|
|
@@ -8,9 +7,21 @@
|
|
|
8
7
|
"heading": "pagerts - Webpage resource extractor",
|
|
9
8
|
"content": [
|
|
10
9
|
"pagerts fetches a URL (or reads a local HTML file) and prints every external resource it references - links, meta tags, scripts, styles - as JSON.",
|
|
10
|
+
{
|
|
11
|
+
"heading": "From the README",
|
|
12
|
+
"theme": "open",
|
|
13
|
+
"content": [
|
|
14
|
+
"PagerTS fetches web pages, parses their HTML, and reports each page's title, URL, and external resources - inspecting common resource-bearing tags, or scanning every element for selected link properties.",
|
|
15
|
+
"Requires Node.js 20 or later; installs globally with `npm install --global pagerts`."
|
|
16
|
+
]
|
|
17
|
+
},
|
|
11
18
|
{
|
|
12
19
|
"heading": "Quick start",
|
|
13
|
-
"content": [
|
|
20
|
+
"content": [
|
|
21
|
+
"npm install -g pagerts",
|
|
22
|
+
"",
|
|
23
|
+
"pagerts https://example.com"
|
|
24
|
+
],
|
|
14
25
|
"theme": "open"
|
|
15
26
|
},
|
|
16
27
|
{
|
|
@@ -6,8 +6,18 @@
|
|
|
6
6
|
"content": {
|
|
7
7
|
"heading": "rarebert",
|
|
8
8
|
"content": [
|
|
9
|
-
"
|
|
10
|
-
"[https://github.com/akinevz2/rarebert](https://github.com/akinevz2/rarebert)"
|
|
9
|
+
"A self-modifying scripting environment for interactive, AI-driven development.",
|
|
10
|
+
"[https://github.com/akinevz2/rarebert](https://github.com/akinevz2/rarebert)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"Rarebert scaffolds modules, opens them in your editor side-by-side with opencode, lets the model implement them, summarises the diff, and commits - then runs the result and remembers what happened.",
|
|
16
|
+
"Built around a TypeScript runtime (`lib/runtime/` + Bun) that orchestrates $EDITOR, git, and opencode, and a memo subsystem that threads observations between the model and your shell.",
|
|
17
|
+
"Each turn ends in a commit, so the working tree is always clean before the next cycle.",
|
|
18
|
+
"Work in progress: the branch is mid-port from Node.js/ESM to TypeScript/Bun, not yet stable for daily use."
|
|
19
|
+
]
|
|
20
|
+
}
|
|
11
21
|
]
|
|
12
22
|
}
|
|
13
23
|
}
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
"heading": "webuser",
|
|
8
8
|
"content": [
|
|
9
9
|
"A jail and shell with mounted paths, packaged as a bun CLI.",
|
|
10
|
-
"[https://github.com/akinevz2/webuser](https://github.com/akinevz2/webuser)"
|
|
10
|
+
"[https://github.com/akinevz2/webuser](https://github.com/akinevz2/webuser)",
|
|
11
|
+
{
|
|
12
|
+
"heading": "From the README",
|
|
13
|
+
"theme": "open",
|
|
14
|
+
"content": [
|
|
15
|
+
"A CLI built with Bunli on the Bun runtime: `bun install`, `bun dev -- [command]`, `bun run build`.",
|
|
16
|
+
"MIT licensed."
|
|
17
|
+
]
|
|
18
|
+
}
|
|
11
19
|
]
|
|
12
20
|
}
|
|
13
21
|
}
|
package/src/content/schema.ts
CHANGED
|
@@ -10,12 +10,21 @@ export type Embed = {
|
|
|
10
10
|
provider?: "soundcloud";
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* A content-file include directive: `{"include": "<name>"}` expands, at
|
|
15
|
+
* load time (src/content/index.ts), into the referenced content file's
|
|
16
|
+
* top-level Section as a nested child — JSON cannot import, so this is
|
|
17
|
+
* the "include" mechanism for reusing a section across pages.
|
|
18
|
+
*/
|
|
19
|
+
export type IncludeRef = { include: string };
|
|
20
|
+
|
|
13
21
|
/** A clickable image tile with caption lines (artist profile headers). */
|
|
14
22
|
export type Banner = {
|
|
15
23
|
banner: { image: string; href: string; lines: string[] };
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
export type Item =
|
|
26
|
+
export type Item =
|
|
27
|
+
string | Section | Embed | Banner | IncludeRef | ReactElement;
|
|
19
28
|
|
|
20
29
|
/** A window as written in the JSON content files. */
|
|
21
30
|
export type Section = {
|