aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/apkg_helpers.html238
-rw-r--r--docs/bootloader.html242
-rw-r--r--docs/index.html4
-rw-r--r--docs/install.html66
-rw-r--r--docs/networking.html4
-rw-r--r--docs/packagemanager.html4
-rw-r--r--docs/using_autils.html353
-rw-r--r--docs/writing_abuild.html367
-rw-r--r--ports.html1
9 files changed, 1239 insertions, 40 deletions
diff --git a/docs/apkg_helpers.html b/docs/apkg_helpers.html
new file mode 100644
index 00000000..cc56ebee
--- /dev/null
+++ b/docs/apkg_helpers.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Alice Linux - docs</title>
+ <link rel="icon" type="image/svg+xml" href="/files/favicon.svg">
+ <style>
+ :root {
+ color-scheme: dark;
+ --bg: #0d0d0d;
+ --bg-alt: #141414;
+ --bg-code: #1a1a1a;
+ --fg: #e0e0e0;
+ --fg-dim: #888;
+ --accent: #a8a8a8;
+ --accent-hover: #e0e0e0;
+ --border: #222;
+ }
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: "Terminus", "Monaco", "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", Consolas, monospace;
+ font-size: 15px;
+ line-height: 1.6;
+ max-width: 88ch;
+ margin: 0 auto;
+ padding: 2em 1.5em;
+ background: var(--bg);
+ color: var(--fg);
+ -webkit-font-smoothing: antialiased;
+ }
+ h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; }
+ h1 { font-size: 1.75rem; margin-bottom: 0.6em; }
+ h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; }
+ h3 { font-size: 1.1rem; margin: 1.4em 0 0.4em; }
+ h4 { font-size: 1rem; margin: 1.2em 0 0.3em; }
+ p { margin: 0 0 1em; }
+ a {
+ color: var(--accent);
+ text-decoration: none;
+ }
+ a:hover { color: var(--accent-hover); text-decoration: underline; }
+ nav { margin-bottom: 1.5em; }
+ nav a { color: var(--fg-dim); font-size: 0.9em; }
+ nav a:hover { color: var(--accent); }
+ nav span { color: var(--border); margin: 0 0.3em; }
+ hr {
+ border: 0;
+ border-top: 1px solid var(--border);
+ margin: 1.5em 0;
+ }
+ pre, code { font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; font-size: 0.9em; }
+ code {
+ background: var(--bg-code);
+ padding: 0.15em 0.4em;
+ border-radius: 3px;
+ color: #c0c0c0;
+ }
+ pre {
+ background: var(--bg-code);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 1em;
+ overflow-x: auto;
+ margin: 1em 0;
+ line-height: 1.45;
+ }
+ pre code {
+ background: none;
+ padding: 0;
+ border-radius: 0;
+ }
+ img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1em 0;
+ border-radius: 4px;
+ }
+ blockquote {
+ margin: 1em 0;
+ padding-left: 1em;
+ border-left: 3px solid var(--border);
+ color: var(--fg-dim);
+ }
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 1em 0;
+ }
+ th, td {
+ padding: 0.5em 0.6em;
+ text-align: left;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ font-weight: 600;
+ border-bottom-color: #333;
+ }
+ tr:last-child td { border-bottom: none; }
+ ul, ol { margin: 0 0 1em 1.5em; }
+ li { margin-bottom: 0.3em; }
+ input, button, textarea { font: inherit; color: inherit; }
+ .ports-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5em;
+ margin-bottom: 1em;
+ }
+ .ports-toolbar button {
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ padding: 0.3em 0;
+ cursor: pointer;
+ color: var(--fg-dim);
+ font-size: 0.9em;
+ }
+ .ports-toolbar button.active {
+ color: var(--accent);
+ border-bottom-color: var(--accent);
+ }
+ .ports-toolbar button:hover { color: var(--fg); }
+ .ports-toolbar input {
+ flex: 1 1 18em;
+ min-width: 0;
+ background: var(--bg-alt);
+ border: 1px solid var(--border);
+ border-radius: 3px;
+ padding: 0.4em 0.6em;
+ }
+ .ports-toolbar input:focus { outline: none; border-color: var(--accent); }
+ .ports-count { margin-bottom: 0.8em; color: var(--fg-dim); font-size: 0.9em; }
+ #commits { list-style: none; margin: 0; }
+ #commits li {
+ padding: 0.8em 0;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: flex-start;
+ gap: 0.8em;
+ }
+ #commits li:last-child { border-bottom: none; }
+ .commit-hash {
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace;
+ font-size: 0.8em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ min-width: 7em;
+ }
+ .commit-msg { flex: 1; word-break: break-word; }
+ .commit-meta {
+ font-size: 0.85em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ text-align: right;
+ min-width: 9em;
+ }
+ #commits-loading {
+ text-align: center;
+ padding: 1.5em;
+ color: var(--fg-dim);
+ display: none;
+ }
+ #commits-error {
+ text-align: center;
+ padding: 1em;
+ color: #e77;
+ display: none;
+ }
+ .dl-table td:nth-child(1) { width: 60%; }
+ .dl-table td:nth-child(2) { width: 15%; text-align: right; }
+ .dl-table td:nth-child(3) { width: 25%; white-space: nowrap; }
+ .dl-empty { color: var(--fg-dim); font-style: italic; }
+ </style>
+</head>
+<body>
+<div class="centered-wrapper">
+ <nav>
+ <a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
+ </nav>
+ <hr>
+<a href="/docs/">&lt;- back to docs</a>
+
+<h1>apkg helper scripts</h1>
+<p>autils includes several helper scripts that work alongside <code>apkg</code> for package inspection, cleanup, and maintenance. See <code>man &lt;program&gt;</code> for full details on each command.</p>
+<h2>apkg-chroot</h2>
+<p>Enter a chroot environment with virtual filesystems mounted. Useful for building packages or performing system maintenance inside an alternative root.</p>
+<pre><code class="language-sh">apkg-chroot /mnt/alice # launch interactive shell
+apkg-chroot /mnt/alice apkg -i mypkg # run a command inside the chroot
+</code></pre>
+<p>Must be run as root. Mounts <code>/dev</code>, <code>/proc</code>, <code>/sys</code>, <code>/run</code>, copies <code>/etc/resolv.conf</code>, and cleans up all mounts on exit.</p>
+<h2>apkg-clean</h2>
+<p>List stale <code>.spm</code> package files and orphaned source tarballs that are no longer referenced by any current package recipe. Pipe to <code>xargs rm</code> to actually clean up.</p>
+<pre><code class="language-sh">apkg-clean # list all unreferenced files
+apkg-clean -p # list only stale packages
+apkg-clean -s # list only stale sources
+apkg-clean | xargs rm # remove them
+</code></pre>
+<h2>apkg-deps</h2>
+<p>Show runtime library dependencies of an installed package. Uses <code>ldd</code> to find shared libraries needed by the package's binaries, then maps those libraries back to the packages that provide them.</p>
+<pre><code class="language-sh">apkg-deps mypkg
+</code></pre>
+<p>Useful for discovering implicit runtime dependencies not listed in the formal <code>depends</code> file. Excludes the package itself and base system packages (gcc, musl, binutils, glibc).</p>
+<h2>apkg-foreign</h2>
+<p>List installed packages that are not found in any configured repository. These may have been installed from an external source or had their recipes removed.</p>
+<pre><code class="language-sh">apkg-foreign
+</code></pre>
+<p>Takes no arguments; outputs one package name per line.</p>
+<h2>apkg-genabuild</h2>
+<p>Scaffold a new package recipe from a source URL. Parses the name and version from the URL and creates a directory with skeleton <code>abuild</code> and <code>info</code> files.</p>
+<pre><code class="language-sh">apkg-genabuild https://example.com/mypkg-1.2.3.tar.gz
+apkg-genabuild https://github.com/user/repo/archive/v1.0.tar.gz myname
+</code></pre>
+<p>Special handling for GitHub tag archives, PyPI packages (prefixes <code>python-</code>), and CPAN packages (prefixes <code>perl-</code>). An optional second argument overrides the derived package name.</p>
+<h2>apkg-orphan</h2>
+<p>List orphan packages: packages that are installed and exist in a repository, but have no other installed package depending on them. These may be safe to remove.</p>
+<pre><code class="language-sh">apkg-orphan
+</code></pre>
+<p>Takes no arguments; outputs one package name per line.</p>
+<h2>apkg-purge</h2>
+<p>Remove a package and all its dependencies that are no longer needed by any other installed package. This is a &quot;deep&quot; removal compared to <code>apkg -r</code> which only removes the specified package.</p>
+<pre><code class="language-sh">apkg-purge mypkg # dry-run: show what would be removed
+apkg-purge -p mypkg # actually purge from the system
+</code></pre>
+<h2>apkg-redundantdeps</h2>
+<p>Find redundant entries in <code>depends</code> files. A dependency is redundant if another listed dependency already pulls it in transitively.</p>
+<pre><code class="language-sh">apkg-redundantdeps mypkg # check one package
+apkg-redundantdeps # check all packages
+apkg-redundantdeps -f mypkg # fix by removing redundant entries
+apkg-redundantdeps -f # fix all packages
+</code></pre>
+
+<a href="/docs/">&lt;- back to docs</a>
+ <hr>
+ <p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
+</div>
+</body>
+</html>
diff --git a/docs/bootloader.html b/docs/bootloader.html
new file mode 100644
index 00000000..debd8c6f
--- /dev/null
+++ b/docs/bootloader.html
@@ -0,0 +1,242 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Alice Linux - docs</title>
+ <link rel="icon" type="image/svg+xml" href="/files/favicon.svg">
+ <style>
+ :root {
+ color-scheme: dark;
+ --bg: #0d0d0d;
+ --bg-alt: #141414;
+ --bg-code: #1a1a1a;
+ --fg: #e0e0e0;
+ --fg-dim: #888;
+ --accent: #a8a8a8;
+ --accent-hover: #e0e0e0;
+ --border: #222;
+ }
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: "Terminus", "Monaco", "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", Consolas, monospace;
+ font-size: 15px;
+ line-height: 1.6;
+ max-width: 88ch;
+ margin: 0 auto;
+ padding: 2em 1.5em;
+ background: var(--bg);
+ color: var(--fg);
+ -webkit-font-smoothing: antialiased;
+ }
+ h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; }
+ h1 { font-size: 1.75rem; margin-bottom: 0.6em; }
+ h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; }
+ h3 { font-size: 1.1rem; margin: 1.4em 0 0.4em; }
+ h4 { font-size: 1rem; margin: 1.2em 0 0.3em; }
+ p { margin: 0 0 1em; }
+ a {
+ color: var(--accent);
+ text-decoration: none;
+ }
+ a:hover { color: var(--accent-hover); text-decoration: underline; }
+ nav { margin-bottom: 1.5em; }
+ nav a { color: var(--fg-dim); font-size: 0.9em; }
+ nav a:hover { color: var(--accent); }
+ nav span { color: var(--border); margin: 0 0.3em; }
+ hr {
+ border: 0;
+ border-top: 1px solid var(--border);
+ margin: 1.5em 0;
+ }
+ pre, code { font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; font-size: 0.9em; }
+ code {
+ background: var(--bg-code);
+ padding: 0.15em 0.4em;
+ border-radius: 3px;
+ color: #c0c0c0;
+ }
+ pre {
+ background: var(--bg-code);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 1em;
+ overflow-x: auto;
+ margin: 1em 0;
+ line-height: 1.45;
+ }
+ pre code {
+ background: none;
+ padding: 0;
+ border-radius: 0;
+ }
+ img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1em 0;
+ border-radius: 4px;
+ }
+ blockquote {
+ margin: 1em 0;
+ padding-left: 1em;
+ border-left: 3px solid var(--border);
+ color: var(--fg-dim);
+ }
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 1em 0;
+ }
+ th, td {
+ padding: 0.5em 0.6em;
+ text-align: left;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ font-weight: 600;
+ border-bottom-color: #333;
+ }
+ tr:last-child td { border-bottom: none; }
+ ul, ol { margin: 0 0 1em 1.5em; }
+ li { margin-bottom: 0.3em; }
+ input, button, textarea { font: inherit; color: inherit; }
+ .ports-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5em;
+ margin-bottom: 1em;
+ }
+ .ports-toolbar button {
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ padding: 0.3em 0;
+ cursor: pointer;
+ color: var(--fg-dim);
+ font-size: 0.9em;
+ }
+ .ports-toolbar button.active {
+ color: var(--accent);
+ border-bottom-color: var(--accent);
+ }
+ .ports-toolbar button:hover { color: var(--fg); }
+ .ports-toolbar input {
+ flex: 1 1 18em;
+ min-width: 0;
+ background: var(--bg-alt);
+ border: 1px solid var(--border);
+ border-radius: 3px;
+ padding: 0.4em 0.6em;
+ }
+ .ports-toolbar input:focus { outline: none; border-color: var(--accent); }
+ .ports-count { margin-bottom: 0.8em; color: var(--fg-dim); font-size: 0.9em; }
+ #commits { list-style: none; margin: 0; }
+ #commits li {
+ padding: 0.8em 0;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: flex-start;
+ gap: 0.8em;
+ }
+ #commits li:last-child { border-bottom: none; }
+ .commit-hash {
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace;
+ font-size: 0.8em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ min-width: 7em;
+ }
+ .commit-msg { flex: 1; word-break: break-word; }
+ .commit-meta {
+ font-size: 0.85em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ text-align: right;
+ min-width: 9em;
+ }
+ #commits-loading {
+ text-align: center;
+ padding: 1.5em;
+ color: var(--fg-dim);
+ display: none;
+ }
+ #commits-error {
+ text-align: center;
+ padding: 1em;
+ color: #e77;
+ display: none;
+ }
+ .dl-table td:nth-child(1) { width: 60%; }
+ .dl-table td:nth-child(2) { width: 15%; text-align: right; }
+ .dl-table td:nth-child(3) { width: 25%; white-space: nowrap; }
+ .dl-empty { color: var(--fg-dim); font-style: italic; }
+ </style>
+</head>
+<body>
+<div class="centered-wrapper">
+ <nav>
+ <a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
+ </nav>
+ <hr>
+<a href="/docs/">&lt;- back to docs</a>
+
+<h1>Bootloader</h1>
+<p>This document covers installing and configuring the two bootloaders available in Alice Linux: Limine and GRUB.</p>
+<h2>Limine</h2>
+<p>Limine is a modern, lightweight bootloader supporting BIOS and UEFI.</p>
+<p>Install the package:</p>
+<pre><code># apkg -I limine
+</code></pre>
+<h3>BIOS</h3>
+<p>Deploy Limine to the target disk:</p>
+<pre><code># limine bios-install /dev/sdX
+</code></pre>
+<h3>UEFI</h3>
+<p>Copy the Limine EFI executable to the EFI system partition:</p>
+<pre><code># mkdir -p /boot/EFI/BOOT
+# cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT
+</code></pre>
+<h3>Configuration</h3>
+<p>Create <code>/boot/limine.conf</code>:</p>
+<pre><code>timeout: 5
+
+/Alice Linux
+ protocol: linux
+ kernel_path: boot():/vmlinuz
+ cmdline: root=/dev/sda2 rw loglevel=3 quiet
+ module_path: boot():/initrd-linux
+</code></pre>
+<p>Use <code>boot()</code> to reference the partition where <code>/boot</code> resides, or specify the partition directly with <code>uuid()</code> or a path like <code>hd(0,2)</code>.</p>
+<p>For full configuration options, see the <a href="https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md">Limine documentation</a>.</p>
+<h2>GRUB</h2>
+<p>GRUB is the GNU Grand Unified Bootloader, supporting UEFI on x86_64 only.</p>
+<p>Install the package:</p>
+<pre><code># apkg -I grub
+</code></pre>
+<h3>Install</h3>
+<p>Install GRUB for UEFI (requires the EFI system partition mounted at <code>/boot</code>):</p>
+<pre><code># grub-install --target=x86_64-efi --efi-directory=/boot
+</code></pre>
+<h3>Configuration</h3>
+<p>Generate the GRUB configuration file:</p>
+<pre><code># grub-mkconfig -o /boot/grub/grub.cfg
+</code></pre>
+<p>GRUB settings are controlled by <code>/etc/default/grub</code>. Key options:</p>
+<ul>
+<li><strong><code>GRUB_DEFAULT</code></strong>: Default menu entry (default: <code>0</code>)</li>
+<li><strong><code>GRUB_TIMEOUT</code></strong>: Seconds before booting the default entry (default: <code>5</code>)</li>
+<li><strong><code>GRUB_CMDLINE_LINUX_DEFAULT</code></strong>: Kernel command line arguments</li>
+<li><strong><code>GRUB_GFXMODE</code></strong>: Framebuffer resolution (default: <code>auto</code>)</li>
+<li><strong><code>GRUB_DISABLE_OS_PROBER</code></strong>: Disable probing for other operating systems (default: enabled for security)</li>
+</ul>
+<p>After editing <code>/etc/default/grub</code>, regenerate the config:</p>
+<pre><code># grub-mkconfig -o /boot/grub/grub.cfg
+</code></pre>
+
+<a href="/docs/">&lt;- back to docs</a>
+ <hr>
+ <p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
+</div>
+</body>
+</html>
diff --git a/docs/index.html b/docs/index.html
index c204516b..5ba0e91b 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -183,9 +183,13 @@
<p>This section covers the main parts of <strong>Alice Linux</strong>: installation, package
management, networking, service supervision, etc.</p>
<ul>
+<li><a href="./apkg_helpers.html">apkg helper scripts</a></li>
+<li><a href="./bootloader.html">Bootloader</a></li>
<li><a href="./install.html">Install Alice</a></li>
<li><a href="./networking.html">Networking</a></li>
<li><a href="./packagemanager.html">Package Manager</a></li>
+<li><a href="./using_autils.html">Using autils</a></li>
+<li><a href="./writing_abuild.html">Writing an abuild recipe</a></li>
</ul>
<hr>
<p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
diff --git a/docs/install.html b/docs/install.html
index 51063424..aac29e84 100644
--- a/docs/install.html
+++ b/docs/install.html
@@ -179,10 +179,12 @@
<a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
</nav>
<hr>
+<a href="/docs/">&lt;- back to docs</a>
+
<h1>Install Alice</h1>
<p>Here is a guide to installing Alice Linux on your computer using the chroot method. You can do this from your existing Linux distribution or from a live environment, such as Alice Live or another Linux distribution. Make sure your chosen environment has the necessary partitioning tools, filesystem tools, and extraction tools.</p>
<h2>Get Alice rootfs tarball</h2>
-<p>Download the Alice rootfs tarball from the <a href="https://codeberg.org/emmett1/alicelinux/releases">release</a> page, along with its <code>sha256sum</code> file.</p>
+<p>Download the Alice rootfs tarball from the <a href="https://alicelinux.org/download.html">download</a> page, along with its <code>sha256sum</code> file.</p>
<pre><code>$ curl -O &lt;url&gt;
$ curl -O &lt;url&gt;.sha256sum
</code></pre>
@@ -208,31 +210,31 @@ alicelinux-rootfs-20240525.tar.xz: OK
<pre><code># /mnt/alice/usr/bin/apkg-chroot /mnt/alice
</code></pre>
<p>Any further commands after this will be executed inside the Alice environment.</p>
-<h2>Configure apkg.conf</h2>
-<p>Once we have the repositories cloned, we need to configure <code>apkg</code>. <code>apkg</code> is Alice's package build system (or package manager). By default, Alice does not provide an <code>apkg</code> config file (yes, <code>apkg</code> can work without a config file), but we need to create one. The <code>apkg</code> config file should be located at <code>/etc/apkg.conf</code> by default. Let's create one.</p>
+<h2>Configure apkg</h2>
+<p>Once we have the repositories cloned, we need to configure <code>apkg</code>. <code>apkg</code> is Alice's package build system (or package manager). <code>apkg</code> configuration is environment-based -- settings are exported as environment variables. Place them in <code>/etc/profile.d/apkg.sh</code> for system-wide configuration, or in <code>~/.profile</code> for per-user configuration.</p>
<p>First, we set <code>CFLAGS</code> and <code>CXXFLAGS</code>. Alice base packages are built using <code>-O3 -march=x86-64 -pipe</code>. You can use these settings or change them to your preference.</p>
-<pre><code># echo 'export CFLAGS=&quot;-O3 -march=x86-64 -pipe&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export CFLAGS=&quot;-O3 -march=x86-64 -pipe&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>And use whats in <code>CFLAGS</code> for <code>CXXFLAGS</code>.</p>
-<pre><code># echo 'export CXXFLAGS=&quot;$CFLAGS&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export CXXFLAGS=&quot;$CFLAGS&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>Next set <code>MAKEFLAGS</code>. I will use <code>6</code> for my <code>8 threads</code> machine.</p>
-<pre><code># echo 'export MAKEFLAGS=&quot;-j6&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export MAKEFLAGS=&quot;-j6&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>I'm also going to set <code>NINJAJOBS</code> here. Without it, <code>ninja</code> will use all threads of your machine when compiling.</p>
-<pre><code># echo 'export NINJAJOBS=&quot;6&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export NINJAJOBS=&quot;6&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>Next, we need to set the package's build scripts path (I'll call it <code>package repos</code>) so <code>apkg</code> can find them. The <code>APKG_REPO</code> variable can accept multiple values for multiple <code>package repos</code>.</p>
<p>Alice provides two (2) <code>package repos</code> (at the time of this writing): <code>core</code> and <code>extra</code>. <code>core</code> contains all base packages, and <code>extra</code> includes other packages beyond the base.</p>
<p>I'm gonna use directory <code>/var/lib/repos/core</code> and <code>/var/lib/repos/extra</code> for <code>core</code> and <code>extra</code> repos respectively.</p>
-<pre><code># echo 'APKG_REPO=&quot;/var/lib/repos/core /var/lib/repos/extra&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export APKG_REPO=&quot;/var/lib/repos/core /var/lib/repos/extra&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>You can also create a directory the community repo.</p>
<blockquote>
<p>NOTE: The community repo is not held to the same standards as the official repos.
Additionally all repo paths must be declared in the APKG_REPO variable, separated by a single space.</p>
</blockquote>
-<pre><code># echo 'APKG_REPO=&quot;/var/lib/repos/core /var/lib/repos/extra /var/lib/repos/community&quot;' &gt;&gt; /etc/apkg.conf
+<pre><code># echo 'export APKG_REPO=&quot;/var/lib/repos/core /var/lib/repos/extra /var/lib/repos/community&quot;' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
<p>Next, we will set up directories for <code>packages</code>, <code>sources</code>, and <code>work</code>. By default, these directories are inside the package template, but we will change them to <code>/var/cache/pkg</code>, <code>/var/cache/src</code>, and <code>/var/cache/work</code> respectively. You can change these to any location where you want to store these files.</p>
<p>First, create the directories.</p>
@@ -240,21 +242,21 @@ Additionally all repo paths must be declared in the APKG_REPO variable, separate
# mkdir -p /var/cache/src
# mkdir -p /var/cache/work
</code></pre>
-<p>Then add these paths to <code>/etc/apkg.conf</code>.</p>
-<pre><code># echo 'APKG_PACKAGE_DIR=/var/cache/pkg' &gt;&gt; /etc/apkg.conf
-# echo 'APKG_SOURCE_DIR=/var/cache/src' &gt;&gt; /etc/apkg.conf
-# echo 'APKG_WORK_DIR=/var/cache/work' &gt;&gt; /etc/apkg.conf
+<p>Then add these paths to <code>/etc/profile.d/apkg.sh</code>.</p>
+<pre><code># echo 'export APKG_PACKAGE_DIR=/var/cache/pkg' &gt;&gt; /etc/profile.d/apkg.sh
+# echo 'export APKG_SOURCE_DIR=/var/cache/src' &gt;&gt; /etc/profile.d/apkg.sh
+# echo 'export APKG_WORK_DIR=/var/cache/work' &gt;&gt; /etc/profile.d/apkg.sh
</code></pre>
-<h2>Configure reposync.conf</h2>
-<p><code>reposync</code> is a tool to sync package templates from git repositories. Add remote repos for <code>core</code> and <code>extra</code> into <code>/etc/reposync.conf</code>. The format of remote repos in <code>reposync.conf</code> is <code>&lt;gitrepo&gt;|&lt;branch&gt;|&lt;localpath&gt;</code>.</p>
-<pre><code># echo 'https://codeberg.org/emmett1/alicelinux|core|/var/lib/repos/core' &gt;&gt; /etc/reposync.conf
-# echo 'https://codeberg.org/emmett1/alicelinux|extra|/var/lib/repos/extra' &gt;&gt; /etc/reposync.conf
+<h2>Configure reposync</h2>
+<p><code>reposync</code> is a tool to sync package templates from git repositories. Like <code>apkg</code>, <code>reposync</code> configuration is environment-based. Add remote repos for <code>core</code> and <code>extra</code> to <code>/etc/profile.d/reposync.sh</code> (system-wide) or <code>~/.profile</code> (per-user). The format is <code>&lt;gitrepo&gt;|&lt;branch&gt;|&lt;localpath&gt;</code>.</p>
+<pre><code># echo 'export REPOSYNC_CORE=&quot;https://codeberg.org/emmett1/alicelinux|core|/var/lib/repos/core&quot;' &gt;&gt; /etc/profile.d/reposync.sh
+# echo 'export REPOSYNC_EXTRA=&quot;https://codeberg.org/emmett1/alicelinux|extra|/var/lib/repos/extra&quot;' &gt;&gt; /etc/profile.d/reposync.sh
</code></pre>
<p>If you also want the community repo, add it as well.</p>
<blockquote>
<p>NOTE: The community repo is not held to the same standards as the official repos.</p>
</blockquote>
-<pre><code># echo 'https://codeberg.org/emmett1/alicelinux|community|/var/lib/repos/community' &gt;&gt; /etc/reposync.conf
+<pre><code># echo 'export REPOSYNC_COMMUNITY=&quot;https://codeberg.org/emmett1/alicelinux|community|/var/lib/repos/community&quot;' &gt;&gt; /etc/profile.d/reposync.sh
</code></pre>
<p>Now run <code>reposync</code> to sync latest package templates.</p>
<pre><code># reposync
@@ -307,14 +309,6 @@ NOTE: <code>apkg -a</code> prints all installed packages on the system.</p>
<p>If your hardware requires firmware, install it using.</p>
<pre><code># apkg -I linux-firmware
</code></pre>
-<h2>Install bootloader</h2>
-<p>In this guide, I'm going to use <code>grub</code> as the bootloader. Install <code>grub</code>.</p>
-<pre><code># apkg -I grub
-</code></pre>
-<p>Then generate grub config.</p>
-<pre><code># grub-install /dev/sdX
-# grub-mkconfig -o /boot/grub/grub.cfg
-</code></pre>
<h2>Hostname</h2>
<p>Change <code>alice</code> to the hostname of your choice.</p>
<pre><code># echo alice &gt; /etc/hostname
@@ -351,20 +345,6 @@ Create a symlink from <code>/etc/sv/&lt;service&gt;</code> to <code>/var/service
<p>Set the password for the <code>root</code> user.</p>
<pre><code># passwd
</code></pre>
-<h2>Networking</h2>
-<p>You might want to set up networking before rebooting. For wifi connection, install <code>wpa_supplicant</code>.</p>
-<pre><code># apkg -I wpa_supplicant
-</code></pre>
-<p>Configure your SSID.</p>
-<pre><code># wpa_passphrase &lt;YOUR SSID&gt; &lt;ITS PASSWORD&gt; &gt;&gt; /etc/wpa_supplicant.conf
-</code></pre>
-<p>Enable the service.</p>
-<pre><code># ln -s /etc/sv/wpa_supplicant /var/service
-</code></pre>
-<p>Then configure &amp; enable <code>udhcpc</code> service.</p>
-<pre><code># vi /etc/sv/udhcpc/conf
-# ln -s /etc/sv/udhcpc /var/service
-</code></pre>
<h2>Timezone</h2>
<p>Install <code>tzdata</code>.</p>
<pre><code># apkg -I tzdata
@@ -376,6 +356,10 @@ Create a symlink from <code>/etc/sv/&lt;service&gt;</code> to <code>/var/service
<pre><code># cp /usr/share/zoneinfo/Asia/Kuala_Lumpur /etc/localtime
# apkg -r tzdata
</code></pre>
+<h2>Install bootloader</h2>
+<p>See the <a href="bootloader.html">bootloader documentation</a> for installing and configuring a bootloader.</p>
+<h2>Networking</h2>
+<p>See the <a href="networking.html">networking documentation</a> for setting up networking.</p>
<h2>Reboot and enjoy!</h2>
<p>Exit the chroot environment and unmount the Alice partition, then reboot.</p>
<pre><code># exit
@@ -389,6 +373,8 @@ Create a symlink from <code>/etc/sv/&lt;service&gt;</code> to <code>/var/service
<li>Use <code>revdep</code> to scan for broken libraries and binaries after system upgrades and package removals. You can use <code>revdep -v</code> to print out missing required libraries, and use <code>apkg -f -u $(revdep)</code> to scan and rebuild broken packages.</li>
<li>Run <code>updateconf</code> to update config files in <code>/etc</code> after package upgrades.</li>
</ul>
+
+<a href="/docs/">&lt;- back to docs</a>
<hr>
<p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
</div>
diff --git a/docs/networking.html b/docs/networking.html
index 324ea4f9..d641a353 100644
--- a/docs/networking.html
+++ b/docs/networking.html
@@ -179,6 +179,8 @@
<a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
</nav>
<hr>
+<a href="/docs/">&lt;- back to docs</a>
+
<h1>Networking</h1>
<p>This document describes how to configure networking on <strong>Alice Linux</strong> using <code>eiwd</code>/<code>wpa_supplicant</code> + <code>udhcpc</code>/<code>dhcpcd</code>.</p>
<hr />
@@ -309,6 +311,8 @@ DisablePeriodicScan=true
# ln -s /etc/sv/wpa_supplicant /var/service
# ln -s /etc/sv/udhcpc /var/service
</code></pre>
+
+<a href="/docs/">&lt;- back to docs</a>
<hr>
<p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
</div>
diff --git a/docs/packagemanager.html b/docs/packagemanager.html
index 076a0141..af1e1b6c 100644
--- a/docs/packagemanager.html
+++ b/docs/packagemanager.html
@@ -179,6 +179,8 @@
<a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
</nav>
<hr>
+<a href="/docs/">&lt;- back to docs</a>
+
<h1>Package Manager</h1>
<p>In Alice, two package manager are used, <a href="https://codeberg.org/emmett1/spm">spm</a> and <a href="https://codeberg.org/emmett1/autils">autils</a>. And why two package manager? <code>spm</code> was written for generic package manager for linux distribution. And <code>autils</code> is written specifically for <code>Alice</code> and requires <code>spm</code> in order to install, remove and update packages while managing conflicts. The command <code>apkg</code> (part of <code>autils</code>) is used to fetch and build packages from ports and their <code>abuild</code> files.</p>
<h2>spm</h2>
@@ -483,6 +485,8 @@ $ apkg-redundantdeps
(remove redundant dependencies for depends list)
$ apkg-redundantdeps -f
</code></pre>
+
+<a href="/docs/">&lt;- back to docs</a>
<hr>
<p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
</div>
diff --git a/docs/using_autils.html b/docs/using_autils.html
new file mode 100644
index 00000000..55fdc805
--- /dev/null
+++ b/docs/using_autils.html
@@ -0,0 +1,353 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Alice Linux - docs</title>
+ <link rel="icon" type="image/svg+xml" href="/files/favicon.svg">
+ <style>
+ :root {
+ color-scheme: dark;
+ --bg: #0d0d0d;
+ --bg-alt: #141414;
+ --bg-code: #1a1a1a;
+ --fg: #e0e0e0;
+ --fg-dim: #888;
+ --accent: #a8a8a8;
+ --accent-hover: #e0e0e0;
+ --border: #222;
+ }
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: "Terminus", "Monaco", "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", Consolas, monospace;
+ font-size: 15px;
+ line-height: 1.6;
+ max-width: 88ch;
+ margin: 0 auto;
+ padding: 2em 1.5em;
+ background: var(--bg);
+ color: var(--fg);
+ -webkit-font-smoothing: antialiased;
+ }
+ h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; }
+ h1 { font-size: 1.75rem; margin-bottom: 0.6em; }
+ h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; }
+ h3 { font-size: 1.1rem; margin: 1.4em 0 0.4em; }
+ h4 { font-size: 1rem; margin: 1.2em 0 0.3em; }
+ p { margin: 0 0 1em; }
+ a {
+ color: var(--accent);
+ text-decoration: none;
+ }
+ a:hover { color: var(--accent-hover); text-decoration: underline; }
+ nav { margin-bottom: 1.5em; }
+ nav a { color: var(--fg-dim); font-size: 0.9em; }
+ nav a:hover { color: var(--accent); }
+ nav span { color: var(--border); margin: 0 0.3em; }
+ hr {
+ border: 0;
+ border-top: 1px solid var(--border);
+ margin: 1.5em 0;
+ }
+ pre, code { font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; font-size: 0.9em; }
+ code {
+ background: var(--bg-code);
+ padding: 0.15em 0.4em;
+ border-radius: 3px;
+ color: #c0c0c0;
+ }
+ pre {
+ background: var(--bg-code);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 1em;
+ overflow-x: auto;
+ margin: 1em 0;
+ line-height: 1.45;
+ }
+ pre code {
+ background: none;
+ padding: 0;
+ border-radius: 0;
+ }
+ img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1em 0;
+ border-radius: 4px;
+ }
+ blockquote {
+ margin: 1em 0;
+ padding-left: 1em;
+ border-left: 3px solid var(--border);
+ color: var(--fg-dim);
+ }
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 1em 0;
+ }
+ th, td {
+ padding: 0.5em 0.6em;
+ text-align: left;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ font-weight: 600;
+ border-bottom-color: #333;
+ }
+ tr:last-child td { border-bottom: none; }
+ ul, ol { margin: 0 0 1em 1.5em; }
+ li { margin-bottom: 0.3em; }
+ input, button, textarea { font: inherit; color: inherit; }
+ .ports-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5em;
+ margin-bottom: 1em;
+ }
+ .ports-toolbar button {
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ padding: 0.3em 0;
+ cursor: pointer;
+ color: var(--fg-dim);
+ font-size: 0.9em;
+ }
+ .ports-toolbar button.active {
+ color: var(--accent);
+ border-bottom-color: var(--accent);
+ }
+ .ports-toolbar button:hover { color: var(--fg); }
+ .ports-toolbar input {
+ flex: 1 1 18em;
+ min-width: 0;
+ background: var(--bg-alt);
+ border: 1px solid var(--border);
+ border-radius: 3px;
+ padding: 0.4em 0.6em;
+ }
+ .ports-toolbar input:focus { outline: none; border-color: var(--accent); }
+ .ports-count { margin-bottom: 0.8em; color: var(--fg-dim); font-size: 0.9em; }
+ #commits { list-style: none; margin: 0; }
+ #commits li {
+ padding: 0.8em 0;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: flex-start;
+ gap: 0.8em;
+ }
+ #commits li:last-child { border-bottom: none; }
+ .commit-hash {
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace;
+ font-size: 0.8em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ min-width: 7em;
+ }
+ .commit-msg { flex: 1; word-break: break-word; }
+ .commit-meta {
+ font-size: 0.85em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ text-align: right;
+ min-width: 9em;
+ }
+ #commits-loading {
+ text-align: center;
+ padding: 1.5em;
+ color: var(--fg-dim);
+ display: none;
+ }
+ #commits-error {
+ text-align: center;
+ padding: 1em;
+ color: #e77;
+ display: none;
+ }
+ .dl-table td:nth-child(1) { width: 60%; }
+ .dl-table td:nth-child(2) { width: 15%; text-align: right; }
+ .dl-table td:nth-child(3) { width: 25%; white-space: nowrap; }
+ .dl-empty { color: var(--fg-dim); font-style: italic; }
+ </style>
+</head>
+<body>
+<div class="centered-wrapper">
+ <nav>
+ <a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
+ </nav>
+ <hr>
+<a href="/docs/">&lt;- back to docs</a>
+
+<h1>Using autils</h1>
+<p>autils is a collection of POSIX shell scripts for source-based package management on Alice Linux.</p>
+<p>For full command details, see the man pages: <code>man apkg</code>, <code>man reposync</code>, etc.</p>
+<h2>Installation</h2>
+<pre><code class="language-sh">make install
+</code></pre>
+<p>This installs all scripts to <code>/usr/bin</code> and man pages to <code>/usr/share/man/man8</code>. Override with:</p>
+<pre><code class="language-sh">make install DESTDIR=/tmp/root PREFIX=/usr/local
+</code></pre>
+<h2>Core concepts</h2>
+<p>The package manager, <strong>apkg</strong>, builds packages from source using <code>abuild</code> recipe files and installs them as <code>.spm</code> packages via the <strong>spm</strong>(8) backend. Package recipes live in git repositories referenced by the <code>APKG_REPO</code> environment variable.</p>
+<p>Configuration is done through environment variables: there is no config file.</p>
+<h2>Basic usage</h2>
+<h3>Building a package</h3>
+<p>From inside a recipe directory:</p>
+<pre><code class="language-sh">cd /path/to/repo/mypkg
+apkg
+</code></pre>
+<p>This fetches sources, verifies checksums, builds, and creates a <code>.spm</code> in <code>$APKG_PACKAGE_DIR</code>.</p>
+<h3>Installing and upgrading</h3>
+<pre><code class="language-sh">apkg -i mypkg # build and install
+apkg -i # same, from inside the recipe directory
+apkg -I firefox # install with automatic dependency resolution
+apkg -u mypkg # upgrade (rebuild and reinstall)
+apkg -f mypkg # force rebuild even if .spm already exists
+apkg -o mypkg # download sources only, don't build
+</code></pre>
+<h3>Removing packages</h3>
+<pre><code class="language-sh">apkg -r mypkg # remove a package
+apkg-purge mypkg # show what would be removed (dry-run)
+apkg-purge -p mypkg # remove package and its unneeded dependencies
+</code></pre>
+<h3>Searching and listing</h3>
+<pre><code class="language-sh">apkg -s icon # search packages by name pattern
+apkg -s -v icon # search with version info
+apkg -a # list all installed packages
+apkg -a -v # list installed packages with versions
+apkg -S libpng.so # find which package owns a file
+apkg -l # list outdated packages on the system
+</code></pre>
+<h3>Dependency queries</h3>
+<pre><code class="language-sh">apkg -d mypkg # list direct dependencies of a package
+apkg -D mypkg # list all dependencies recursively, in install order
+apkg -j mypkg # list packages that depend on mypkg
+</code></pre>
+<h3>System upgrade</h3>
+<pre><code class="language-sh">apkg -U
+</code></pre>
+<p>This checks all installed packages for outdated versions, resolves the full dependency tree, installs any new packages, then upgrades existing ones. Set <code>APKG_NOPROMPT=1</code> to skip the confirmation prompt (useful for scripting). Packages listed in <code>APKG_MASK</code> are skipped.</p>
+<h3>Checksums and file lists</h3>
+<pre><code class="language-sh">apkg -g mypkg # regenerate .shasum file
+apkg -k mypkg # regenerate .files list from the .spm
+</code></pre>
+<h3>Triggers</h3>
+<p>After installing or upgrading packages, apkg can refresh system caches:</p>
+<pre><code class="language-sh">apkg -t # run triggers for all installed packages
+apkg -t mypkg # run only triggers relevant to mypkg
+</code></pre>
+<p>Triggers include: fontconfig cache, GDK-Pixbuf loaders, GIO modules, GSettings schemas, GTK input method modules, icon theme cache, udev hardware database, X font indices, desktop MIME cache, and shared MIME database. Each trigger only fires if the package actually provides files that need it.</p>
+<h2>Helper scripts</h2>
+<h3>Package inspection</h3>
+<pre><code class="language-sh">apkg-deps mypkg # show runtime library dependencies (via ldd)
+apkg-foreign # list installed packages not found in any repo
+apkg-orphan # list packages with no dependents installed
+</code></pre>
+<h3>Cleanup</h3>
+<pre><code class="language-sh">apkg-clean # list stale .spm and source files
+apkg-clean | xargs rm # actually remove them
+apkg-clean -p # list only stale packages
+apkg-clean -s # list only stale sources
+</code></pre>
+<h3>Dependency maintenance</h3>
+<pre><code class="language-sh">apkg-redundantdeps mypkg # find transitive deps listed explicitly
+apkg-redundantdeps # check all packages
+apkg-redundantdeps -f mypkg # fix by removing redundant entries
+</code></pre>
+<h3>Scaffolding</h3>
+<pre><code class="language-sh">apkg-genabuild https://example.com/pkg-1.2.3.tar.gz
+apkg-genabuild https://github.com/user/repo/archive/v1.0.tar.gz
+</code></pre>
+<p>Derives <code>name</code> and <code>version</code> from the URL and creates a directory with a skeleton <code>abuild</code>. Recognizes GitHub tag archives, PyPI packages (prefixes <code>python-</code>), and CPAN packages (prefixes <code>perl-</code>). An optional second argument overrides the name.</p>
+<h2>Standalone utilities</h2>
+<h3>revdep: find broken library links</h3>
+<p>Scans system binaries and libraries for missing shared library dependencies. Run after major upgrades, especially those with library version bumps.</p>
+<pre><code class="language-sh">revdep # plain output
+revdep -v # verbose progress
+</code></pre>
+<p><strong>Note:</strong> revdep only reports problems; it does not rebuild anything. Use <code>apkg -f</code> to rebuild affected packages.</p>
+<h3>updateconf: merge .new config files</h3>
+<p>When packages are upgraded, new default config files are installed with a <code>.new</code> suffix to avoid overwriting local changes. Run <code>updateconf</code> as root to interactively handle them:</p>
+<pre><code class="language-sh">updateconf
+</code></pre>
+<p>For each <code>.new</code> file it shows a diff and prompts:</p>
+<ul>
+<li><strong>U</strong>: update: replace current with new</li>
+<li><strong>D</strong>: discard: delete the <code>.new</code> file, keep current</li>
+<li><strong>E</strong>: edit: open current file in <code>$EDITOR</code> (default: <code>vi</code>)</li>
+<li><strong>K</strong>: keep: leave both files as-is</li>
+</ul>
+<h3>reposync: sync git repositories</h3>
+<p>Syncs git-based package repos using <code>REPOSYNC_*</code> environment variables:</p>
+<pre><code class="language-sh">export REPOSYNC_CORE=&quot;https://codeberg.org/emmett1/alicelinux.git|main|/var/lib/alicelinux&quot;
+export REPOSYNC_EXTRA=&quot;https://codeberg.org/emmett1/extra.git|main|/var/lib/alicelinux/extra&quot;
+reposync
+</code></pre>
+<p>Options:</p>
+<ul>
+<li><strong><code>-n</code></strong>: dry-run</li>
+<li><strong><code>-l</code></strong>: log to <code>/var/log/reposync.log</code></li>
+<li><strong><code>-f</code></strong>: force fresh clones</li>
+<li><strong><code>-h</code></strong>: help</li>
+</ul>
+<h2>Working in a chroot</h2>
+<pre><code class="language-sh">apkg-chroot /mnt/alice # enter interactive shell
+apkg-chroot /mnt/alice apkg -i mypkg # run apkg inside chroot
+</code></pre>
+<p>Mounts <code>/dev</code>, <code>/proc</code>, <code>/sys</code>, <code>/run</code>, copies <code>/etc/resolv.conf</code>, and cleans up on exit. Must be run as root.</p>
+<h2>Environment variables</h2>
+<h3>Core paths</h3>
+<ul>
+<li><strong><code>APKG_REPO</code></strong> (default: <code>$PWD</code>): Space-separated repo directories, searched in order</li>
+<li><strong><code>APKG_PACKAGE_DIR</code></strong> (default: <code>$PWD</code>): Where built <code>.spm</code> files are stored</li>
+<li><strong><code>APKG_SOURCE_DIR</code></strong> (default: <code>$PWD</code>): Source tarball cache</li>
+<li><strong><code>APKG_WORK_DIR</code></strong> (default: <code>$PWD</code>): Build working tree (extraction + fakeroot)</li>
+<li><strong><code>APKG_ROOT</code></strong> (default: <code>/</code>): Alternative install root</li>
+</ul>
+<h3>Build behavior</h3>
+<ul>
+<li><strong><code>APKG_NOPROMPT</code></strong>: Skip confirmation prompt in <code>-I</code> and <code>-U</code></li>
+<li><strong><code>APKG_KEEP_WORKDIR</code></strong>: Keep build tree on failure (for debugging)</li>
+<li><strong><code>APKG_ALIAS</code></strong>: Dependency substitution: <code>real:alias</code> pairs (e.g. <code>openssl:libressl</code>)</li>
+<li><strong><code>APKG_MASK</code></strong>: Packages to skip during <code>-l</code> and <code>-U</code></li>
+</ul>
+<h3>Logging</h3>
+<ul>
+<li><strong><code>APKG_LOG</code></strong>: Enable build logging</li>
+<li><strong><code>APKG_LOG_DIR</code></strong>: Directory for log files (filename: <code>$name.log</code>)</li>
+</ul>
+<h3>Compiler</h3>
+<ul>
+<li><strong><code>CFLAGS</code></strong>, <strong><code>CXXFLAGS</code></strong>: Compiler flags (used by cmake builds)</li>
+<li><strong><code>CROSS_COMPILE</code></strong>: Prefix for <code>strip</code> (e.g. <code>x86_64-linux-musl-</code>)</li>
+</ul>
+<h2>Common workflows</h2>
+<h3>Building and installing a new package</h3>
+<pre><code class="language-sh">cd $APKG_REPO
+apkg-genabuild https://example.com/mypkg-1.0.tar.gz
+cd mypkg
+# edit abuild as needed, add depends file
+apkg -I mypkg
+</code></pre>
+<h3>Full system maintenance</h3>
+<pre><code class="language-sh">reposync # sync repos
+apkg -U # system upgrade
+revdep # check for broken libraries
+updateconf # merge config files
+apkg-clean | xargs rm # clean up stale files
+apkg-orphan # review packages to potentially remove
+</code></pre>
+<h3>Debugging a failed build</h3>
+<pre><code class="language-sh">APKG_KEEP_WORKDIR=1 apkg -f mypkg
+# inspect $APKG_WORK_DIR/apkg-src-mypkg and apkg-pkg-mypkg
+</code></pre>
+
+<a href="/docs/">&lt;- back to docs</a>
+ <hr>
+ <p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
+</div>
+</body>
+</html>
diff --git a/docs/writing_abuild.html b/docs/writing_abuild.html
new file mode 100644
index 00000000..3dd20471
--- /dev/null
+++ b/docs/writing_abuild.html
@@ -0,0 +1,367 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Alice Linux - docs</title>
+ <link rel="icon" type="image/svg+xml" href="/files/favicon.svg">
+ <style>
+ :root {
+ color-scheme: dark;
+ --bg: #0d0d0d;
+ --bg-alt: #141414;
+ --bg-code: #1a1a1a;
+ --fg: #e0e0e0;
+ --fg-dim: #888;
+ --accent: #a8a8a8;
+ --accent-hover: #e0e0e0;
+ --border: #222;
+ }
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: "Terminus", "Monaco", "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", Consolas, monospace;
+ font-size: 15px;
+ line-height: 1.6;
+ max-width: 88ch;
+ margin: 0 auto;
+ padding: 2em 1.5em;
+ background: var(--bg);
+ color: var(--fg);
+ -webkit-font-smoothing: antialiased;
+ }
+ h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; }
+ h1 { font-size: 1.75rem; margin-bottom: 0.6em; }
+ h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; }
+ h3 { font-size: 1.1rem; margin: 1.4em 0 0.4em; }
+ h4 { font-size: 1rem; margin: 1.2em 0 0.3em; }
+ p { margin: 0 0 1em; }
+ a {
+ color: var(--accent);
+ text-decoration: none;
+ }
+ a:hover { color: var(--accent-hover); text-decoration: underline; }
+ nav { margin-bottom: 1.5em; }
+ nav a { color: var(--fg-dim); font-size: 0.9em; }
+ nav a:hover { color: var(--accent); }
+ nav span { color: var(--border); margin: 0 0.3em; }
+ hr {
+ border: 0;
+ border-top: 1px solid var(--border);
+ margin: 1.5em 0;
+ }
+ pre, code { font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; font-size: 0.9em; }
+ code {
+ background: var(--bg-code);
+ padding: 0.15em 0.4em;
+ border-radius: 3px;
+ color: #c0c0c0;
+ }
+ pre {
+ background: var(--bg-code);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 1em;
+ overflow-x: auto;
+ margin: 1em 0;
+ line-height: 1.45;
+ }
+ pre code {
+ background: none;
+ padding: 0;
+ border-radius: 0;
+ }
+ img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+ margin: 1em 0;
+ border-radius: 4px;
+ }
+ blockquote {
+ margin: 1em 0;
+ padding-left: 1em;
+ border-left: 3px solid var(--border);
+ color: var(--fg-dim);
+ }
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 1em 0;
+ }
+ th, td {
+ padding: 0.5em 0.6em;
+ text-align: left;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ font-weight: 600;
+ border-bottom-color: #333;
+ }
+ tr:last-child td { border-bottom: none; }
+ ul, ol { margin: 0 0 1em 1.5em; }
+ li { margin-bottom: 0.3em; }
+ input, button, textarea { font: inherit; color: inherit; }
+ .ports-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5em;
+ margin-bottom: 1em;
+ }
+ .ports-toolbar button {
+ background: none;
+ border: none;
+ border-bottom: 2px solid transparent;
+ padding: 0.3em 0;
+ cursor: pointer;
+ color: var(--fg-dim);
+ font-size: 0.9em;
+ }
+ .ports-toolbar button.active {
+ color: var(--accent);
+ border-bottom-color: var(--accent);
+ }
+ .ports-toolbar button:hover { color: var(--fg); }
+ .ports-toolbar input {
+ flex: 1 1 18em;
+ min-width: 0;
+ background: var(--bg-alt);
+ border: 1px solid var(--border);
+ border-radius: 3px;
+ padding: 0.4em 0.6em;
+ }
+ .ports-toolbar input:focus { outline: none; border-color: var(--accent); }
+ .ports-count { margin-bottom: 0.8em; color: var(--fg-dim); font-size: 0.9em; }
+ #commits { list-style: none; margin: 0; }
+ #commits li {
+ padding: 0.8em 0;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: flex-start;
+ gap: 0.8em;
+ }
+ #commits li:last-child { border-bottom: none; }
+ .commit-hash {
+ font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace;
+ font-size: 0.8em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ min-width: 7em;
+ }
+ .commit-msg { flex: 1; word-break: break-word; }
+ .commit-meta {
+ font-size: 0.85em;
+ color: var(--fg-dim);
+ white-space: nowrap;
+ text-align: right;
+ min-width: 9em;
+ }
+ #commits-loading {
+ text-align: center;
+ padding: 1.5em;
+ color: var(--fg-dim);
+ display: none;
+ }
+ #commits-error {
+ text-align: center;
+ padding: 1em;
+ color: #e77;
+ display: none;
+ }
+ .dl-table td:nth-child(1) { width: 60%; }
+ .dl-table td:nth-child(2) { width: 15%; text-align: right; }
+ .dl-table td:nth-child(3) { width: 25%; white-space: nowrap; }
+ .dl-empty { color: var(--fg-dim); font-style: italic; }
+ </style>
+</head>
+<body>
+<div class="centered-wrapper">
+ <nav>
+ <a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="/development.html">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a>
+ </nav>
+ <hr>
+<a href="/docs/">&lt;- back to docs</a>
+
+<h1>Writing an abuild recipe</h1>
+<p>An <code>abuild</code> file is a POSIX shell snippet that tells apkg how to build a package. The directory containing it must have the same name as the package.</p>
+<p>See <code>man apkg</code> for full details on all options and environment variables, and <code>man apkg-genabuild</code> for the recipe scaffolding tool.</p>
+<p>To quickly scaffold a new recipe from a source URL, use <code>apkg-genabuild</code>:</p>
+<pre><code class="language-sh">apkg-genabuild https://example.com/mypkg-1.2.3.tar.gz
+</code></pre>
+<p>This creates the directory and a skeleton <code>abuild</code> with <code>name</code>, <code>version</code>, <code>release</code>, and <code>source</code> already populated.</p>
+<h2>Directory structure</h2>
+<pre><code>mypkg/
+ abuild - package recipe (required)
+ info - package metadata template (description, homepage, license, maintainer)
+ depends - dependency list, one per line (optional)
+ preinstall - script run before the package is built (optional)
+ postinstall - script run after the package is installed (optional)
+ .shasum - source checksums, auto-generated (regenerate with `apkg -g`)
+ .files - package file list, auto-generated (regenerate with `apkg -k`)
+</code></pre>
+<h2>Minimal recipe</h2>
+<pre><code class="language-sh">name=mypkg
+version=1.2.3
+release=1
+source=&quot;https://example.com/$name-$version.tar.gz&quot;
+</code></pre>
+<h3>Required variables</h3>
+<ul>
+<li><strong><code>name</code></strong>: package name. Must match the directory name exactly.</li>
+<li><strong><code>version</code></strong>: upstream version string. Use the <code>$name</code> and <code>$version</code> variables in the source URL so updates are easier.</li>
+<li><strong><code>release</code></strong>: an incrementing integer starting at 1. Reset to 1 when <code>version</code> changes. Bump when the package needs a rebuild without a source change.</li>
+</ul>
+<h2>Source formats</h2>
+<p>The <code>source</code> variable accepts a whitespace-separated list. Five formats are supported:</p>
+<ul>
+<li><strong><code>https://example.com/pkg-1.0.tar.gz</code></strong>: A remote URL, downloaded with curl</li>
+<li><strong><code>mypkg-1.0.tar.gz::https://example.com/v1.0.tar.gz</code></strong>: Custom local filename for a remote URL</li>
+<li><strong><code>https://example.com/pkg.tar.gz::noextract</code></strong>: Download but do not unpack</li>
+<li><strong><code>my-file</code></strong>: A local file in the recipe directory (not downloaded)</li>
+<li>(empty): Create a meta/dummy package with only <code>/usr</code></li>
+</ul>
+<p>Multiple sources can be specified:</p>
+<pre><code class="language-sh">source=&quot;https://example.com/$name-$version.tar.gz
+ fix-build.patch
+ default-config::noextract&quot;
+</code></pre>
+<p>If <code>source</code> is empty, apkg creates a dummy package: useful for meta packages that exist only to pull in dependencies.</p>
+<h2>Optional variables</h2>
+<h3>Build control</h3>
+<ul>
+<li><strong><code>build_type</code></strong>: force a specific build system instead of auto-detection. One of: <code>meson_build</code>, <code>configure_build</code>, <code>cmake_build</code>, <code>python_build</code>, <code>perlmodule_build</code>, <code>makefile_build</code>.</li>
+<li><strong><code>build_dir</code></strong>: subdirectory within the extracted source tree to enter before building. Useful when a tarball extracts into a differently-named directory.</li>
+<li><strong><code>build_opt</code></strong>: extra flags appended to the build system command. The defaults (<code>--prefix=/usr</code>, <code>--sysconfdir=/etc</code>, etc.) are always included; this adds on top.</li>
+<li><strong><code>skip_patch</code></strong>: set to <code>1</code> to skip automatic patch application. Use this if you need to call <code>apply_patch</code> manually from <code>build()</code>.</li>
+<li><strong><code>patch_opt</code></strong>: options for <code>patch(1)</code>. Default: <code>-p1</code>.</li>
+</ul>
+<h3>Package content control</h3>
+<ul>
+<li><strong><code>keep_static</code></strong>: set to keep <code>*.a</code> static libraries (removed by default).</li>
+<li><strong><code>keep_libtool</code></strong>: set to keep <code>*.la</code> libtool archives (removed by default).</li>
+<li><strong><code>keep_locale</code></strong>: set to keep locale files in <code>/usr/share/locale</code> and <code>/usr/lib/locale</code>.</li>
+<li><strong><code>keep_doc</code></strong>: set to keep documentation in <code>/usr/share/doc</code> and <code>/usr/doc</code>.</li>
+<li><strong><code>no_strip</code></strong>: set to skip ELF binary and library stripping.</li>
+</ul>
+<h3>Runit services</h3>
+<ul>
+<li><strong><code>sv</code></strong>: service files to install into <code>/etc/sv</code>. Accepts:
+<ul>
+<li><code>run</code> → <code>/etc/sv/$name/run</code></li>
+<li><code>finish</code> → <code>/etc/sv/$name/finish</code></li>
+<li><code>&lt;name&gt;.run</code> → <code>/etc/sv/&lt;name&gt;/run</code></li>
+<li><code>&lt;name&gt;.finish</code> → <code>/etc/sv/&lt;name&gt;/finish</code></li>
+<li><code>&lt;name&gt;.&lt;ext&gt;</code> → <code>/etc/sv/&lt;name&gt;/&lt;ext&gt;</code></li>
+</ul>
+</li>
+</ul>
+<pre><code class="language-sh">sv=&quot;run finish mydaemon.run mydaemon.finish&quot;
+</code></pre>
+<h2>Build hooks</h2>
+<h3>Custom build function</h3>
+<p>If a <code>build()</code> function is defined, it completely replaces the auto-detected build system. Two variables are available:</p>
+<ul>
+<li><strong><code>$SRC</code></strong>: where sources were extracted</li>
+<li><strong><code>$PKG</code></strong>: the fakeroot directory where files must be installed</li>
+</ul>
+<p>Several <code>DESTDIR</code>-style variables are pre-exported: <code>DESTDIR</code>, <code>DEST_DIR</code>, <code>INSTALLROOT</code>, <code>install_root</code>, <code>INSTALL_ROOT</code>.</p>
+<pre><code class="language-sh">build() {
+ cd &quot;$SRC/$name-$version&quot;
+ ./configure --prefix=/usr --sysconfdir=/etc
+ make
+ make DESTDIR=&quot;$PKG&quot; install
+}
+</code></pre>
+<p><code>build()</code> runs with <code>set -ex</code>, so the script exits on any error and prints each command.</p>
+<h3>Pre/post build hooks</h3>
+<p>Without a <code>build()</code> function, you can use <code>prebuild()</code> and <code>postbuild()</code>:</p>
+<pre><code class="language-sh">prebuild() {
+ sed -i 's/broken/fixed/g' src/whatever.c
+}
+
+postbuild() {
+ mv &quot;$PKG/usr/bin/wrongname&quot; &quot;$PKG/usr/bin/rightname&quot;
+}
+</code></pre>
+<p>The execution order is: <code>prebuild()</code> → auto-detected build system → <code>postbuild()</code>.</p>
+<h2>Build system auto-detection</h2>
+<p>When no <code>build()</code> is defined and no <code>build_type</code> is set, apkg checks for these files in order:</p>
+<ol>
+<li><code>meson.build</code>: meson with LTO, PIE, <code>wrap_mode=nodownload</code>, <code>buildtype=plain</code></li>
+<li><code>configure</code>: autotools <code>./configure --prefix=/usr --sysconfdir=/etc ...</code></li>
+<li><code>CMakeLists.txt</code>: cmake with <code>Release</code> build type, prefers ninja</li>
+<li><code>setup.py</code>: <code>python3 setup.py build &amp;&amp; install --root=$PKG</code></li>
+<li><code>Makefile.PL</code>: <code>perl Makefile.PL &amp;&amp; make &amp;&amp; make install</code></li>
+<li><code>Makefile</code> / <code>makefile</code> / <code>GNUmakefile</code>: raw make with standard variables</li>
+</ol>
+<p>The exact flags for each build system are documented in <code>doc/defaultbuildopts</code>.</p>
+<h2>Post-build processing</h2>
+<p>After compilation, apkg automatically:</p>
+<ul>
+<li>Compresses man pages (man1–man8 only, gzip) and info pages</li>
+<li>Removes common conflict files: <code>fonts.dir</code>, <code>fonts.scale</code>, <code>perllocal.pod</code>, <code>charset.alias</code></li>
+<li>Removes static libraries (<code>*.a</code>), libtool archives (<code>*.la</code>), locales, and docs unless the corresponding <code>keep_*</code> variable is set</li>
+<li>Strips ELF binaries (<code>--strip-all</code>), shared objects (<code>--strip-unneeded</code>), and static archives (<code>--strip-debug</code>) unless <code>no_strip</code> is set</li>
+<li>Installs runit service files from the <code>sv</code> variable</li>
+</ul>
+<h2>The info file</h2>
+<p><code>apkg-genabuild</code> creates an <code>info</code> file alongside the <code>abuild</code> with package metadata:</p>
+<pre><code>description:
+homepage:
+license:
+maintainer: name &lt;name at mail dot com&gt;
+</code></pre>
+<p>Fill in each field as appropriate. The <code>maintainer</code> line uses the format <code>name &lt;email&gt;</code>.</p>
+<h2>The depends file</h2>
+<p>One dependency per line. Lines starting with <code>#</code> are comments. Dependencies are just package names: no version constraints.</p>
+<pre><code># Direct dependencies of mypkg
+zlib
+libpng
+freetype
+</code></pre>
+<p>Dependencies are recursive: when installing with <code>-I</code>, apkg will resolve the full tree. Only list direct dependencies; transitive ones are handled automatically. Use <code>apkg-redundantdeps</code> to find and clean up transitive entries.</p>
+<h2>preinstall / postinstall scripts</h2>
+<p>These are optional executable scripts in the recipe directory:</p>
+<ul>
+<li><strong><code>preinstall</code></strong>: runs before the package is built (only during <code>apkg -i</code> or <code>apkg -u</code>). Good for pre-flight checks or preparing the system.</li>
+<li><strong><code>postinstall</code></strong>: runs after the package is installed or upgraded. Good for one-time setup that can't be done at build time.</li>
+</ul>
+<p>If <code>APKG_ROOT</code> is set (alternative install root), these scripts run inside a chroot.</p>
+<h2>Checksums and file lists</h2>
+<ul>
+<li><strong><code>.shasum</code></strong>: sha3sum of each source file, auto-generated on first build. Regenerate with <code>apkg -g &lt;pkg&gt;</code>.</li>
+<li><strong><code>.files</code></strong>: sorted list of every file in the built <code>.spm</code>, auto-generated after packaging. Regenerate with <code>apkg -k &lt;pkg&gt;</code>. Used by <code>apkg -S</code> for file search.</li>
+</ul>
+<h2>Complete example</h2>
+<pre><code class="language-sh">name=hello
+version=2.12.1
+release=1
+source=&quot;https://ftp.gnu.org/gnu/hello/$name-$version.tar.gz&quot;
+
+build() {
+ cd &quot;$SRC/$name-$version&quot;
+ ./configure --prefix=/usr
+ make
+ make DESTDIR=&quot;$PKG&quot; install
+}
+</code></pre>
+<p>With a <code>depends</code> file:</p>
+<pre><code>zlib
+</code></pre>
+<p>With a <code>postinstall</code> script:</p>
+<pre><code class="language-sh">#!/bin/sh
+echo &quot;hello was installed!&quot;
+</code></pre>
+<h2>Tips</h2>
+<ul>
+<li>Use <code>apkg-genabuild &lt;url&gt;</code> to scaffold a recipe from a source URL quickly.</li>
+<li>Use <code>$name</code> and <code>$version</code> in source URLs so bumping the version only requires changing two variables.</li>
+<li>Patches (<code>.patch</code> / <code>.diff</code> files) listed in <code>source</code> are applied automatically with <code>patch -p1</code> before the build. Use <code>patch_opt</code> to change the strip level.</li>
+<li>Set <code>APKG_KEEP_WORKDIR=1</code> in your environment to inspect the build tree when debugging a failed build.</li>
+</ul>
+
+<a href="/docs/">&lt;- back to docs</a>
+ <hr>
+ <p style="color: var(--fg-dim); font-size: 0.85em;">Copyright &copy; Alice Linux, 2024-2026</p>
+</div>
+</body>
+</html>
diff --git a/ports.html b/ports.html
index 4d691705..2075587b 100644
--- a/ports.html
+++ b/ports.html
@@ -471,6 +471,7 @@
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/spirv-tools">spirv-tools</a></td><td>1.4.341.0-1</td><td>spirv-headers</td></tr>
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/sqlite">sqlite</a></td><td>3.53.1-1</td><td></td></tr>
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/squashfs-tools">squashfs-tools</a></td><td>4.7.5-1</td><td>lzo zstd lz4</td></tr>
+<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/ssu">ssu</a></td><td>0.3.2-1</td><td></td></tr>
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/stagit">stagit</a></td><td>1.2-1</td><td>libgit2</td></tr>
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/strace">strace</a></td><td>7.0-1</td><td></td></tr>
<tr data-repo="extra"><td>extra</td><td><a href="https://codeberg.org/emmett1/alicelinux/src/branch/main/repos/extra/sway">sway</a></td><td>1.12-1</td><td>wlroots json-c pango</td></tr>