diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..c76bc00f --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.vitepress/cache/ +.vitepress/dist/ diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 00000000..03ed98f4 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,141 @@ +import { defineConfig } from 'vitepress' + +const description = + 'Documentation for Soar, a fast, modern, bloat-free package manager for Linux. Install static binaries, AppImages, and portable packages across any distro.' + +export default defineConfig({ + lang: 'en-US', + title: 'Soar', + titleTemplate: ':title · Soar', + description, + cleanUrls: true, + lastUpdated: true, + appearance: 'dark', + sitemap: { hostname: 'https://soar.qaidvoid.dev' }, + + head: [ + ['link', { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' }], + ['meta', { name: 'theme-color', content: '#0d1117' }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:title', content: 'Soar Documentation' }], + ['meta', { property: 'og:description', content: description }], + ['meta', { property: 'og:url', content: 'https://soar.qaidvoid.dev' }], + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, + ], + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }, + ], + [ + 'link', + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap', + }, + ], + ], + + themeConfig: { + logo: '/favicon.svg', + siteTitle: 'Soar', + + nav: [ + { text: 'Quick Start', link: '/quick-start' }, + { text: 'CLI Reference', link: '/cli-reference' }, + { + text: 'Guide', + items: [ + { text: 'Installation', link: '/installation' }, + { text: 'Configuration', link: '/configuration' }, + { text: 'Profiles', link: '/profiles' }, + { text: 'Package Management', link: '/package-management' }, + ], + }, + { text: 'Releases', link: '/releases' }, + ], + + sidebar: [ + { + text: 'Getting Started', + collapsed: false, + items: [ + { text: 'Quick Start', link: '/quick-start' }, + { text: 'Installation', link: '/installation' }, + { text: 'Configuration', link: '/configuration' }, + { text: 'Profiles', link: '/profiles' }, + { text: 'CLI Reference', link: '/cli-reference' }, + ], + }, + { + text: 'Package Management', + collapsed: false, + items: [ + { text: 'Overview', link: '/package-management' }, + { text: 'Declarative Packages', link: '/declarative' }, + { text: 'Install Packages', link: '/install' }, + { text: 'Remove Packages', link: '/remove' }, + { text: 'Update Packages', link: '/update' }, + { text: 'Search Packages', link: '/search' }, + { text: 'List Packages', link: '/list' }, + { text: 'Use Package', link: '/use' }, + { text: 'Run Package', link: '/run' }, + { text: 'Inspect Packages', link: '/inspection' }, + ], + }, + { + text: 'Repositories & Files', + collapsed: false, + items: [ + { text: 'Repository Management', link: '/repo' }, + { text: 'Download Files', link: '/download' }, + ], + }, + { + text: 'Operations', + collapsed: false, + items: [ + { text: 'Health', link: '/health' }, + { text: 'Maintenance', link: '/maintenance' }, + ], + }, + { + text: 'Release Notes', + collapsed: false, + items: [ + { text: 'Overview', link: '/releases' }, + { text: 'Soar 0.12', link: '/releases/v0.12' }, + { text: 'Soar 0.11', link: '/releases/v0.11' }, + { text: 'Soar 0.10', link: '/releases/v0.10' }, + ], + }, + ], + + socialLinks: [ + { icon: 'github', link: 'https://github.com/pkgforge/soar' }, + { icon: 'discord', link: 'https://discord.gg/djJUs48Zbu' }, + ], + + editLink: { + pattern: 'https://github.com/pkgforge/soar/edit/main/docs/:path', + text: 'Edit this page on GitHub', + }, + + search: { + provider: 'local', + }, + + outline: { level: [2, 3], label: 'On this page' }, + + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2024-present pkgforge', + }, + + docFooter: { + prev: 'Previous', + next: 'Next', + }, + }, +}) diff --git a/docs/.vitepress/theme/components/InstallCommand.vue b/docs/.vitepress/theme/components/InstallCommand.vue new file mode 100644 index 00000000..4bb47e12 --- /dev/null +++ b/docs/.vitepress/theme/components/InstallCommand.vue @@ -0,0 +1,38 @@ + + + diff --git a/docs/.vitepress/theme/components/NotFound.vue b/docs/.vitepress/theme/components/NotFound.vue new file mode 100644 index 00000000..ecd5f4a3 --- /dev/null +++ b/docs/.vitepress/theme/components/NotFound.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/docs/.vitepress/theme/components/QuickNav.vue b/docs/.vitepress/theme/components/QuickNav.vue new file mode 100644 index 00000000..93cf138e --- /dev/null +++ b/docs/.vitepress/theme/components/QuickNav.vue @@ -0,0 +1,65 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 00000000..76ec4171 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,398 @@ +/* ============================================================ + Nightsky theme for Soar documentation. + A dark, twilight-inspired skin over the VitePress default + theme: deep charcoal background, cyan/blue accents, amber + inline code. + ============================================================ */ + +/* --- Fonts --- */ +:root { + --vp-font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', + Roboto, sans-serif; + --vp-font-family-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', + 'Source Code Pro', ui-monospace, monospace; +} + +/* --- Light palette (Daysky) --- */ +:root { + --vp-c-bg: #ffffff; + --vp-c-bg-alt: #f6f8fa; + --vp-c-bg-elv: #ffffff; + --vp-c-bg-soft: #f6f8fa; + + --vp-c-default-1: #d0d7de; + --vp-c-default-2: #e1e6eb; + --vp-c-default-3: #f0f3f6; + --vp-c-default-soft: rgba(208, 215, 222, 0.4); + + --vp-c-divider: #e1e6eb; + --vp-c-border: #d0d7de; + --vp-c-gutter: #e1e6eb; + + --vp-c-text-1: #1f2328; + --vp-c-text-2: #59636e; + --vp-c-text-3: #818b98; + + --vp-c-brand-1: #0969da; + --vp-c-brand-2: #0860c4; + --vp-c-brand-3: #0757b3; + --vp-c-brand-soft: rgba(9, 105, 218, 0.1); + + --vp-c-tip-1: #1a7f6e; + --vp-c-tip-2: #16705f; + --vp-c-tip-3: #136052; + --vp-c-tip-soft: rgba(26, 127, 110, 0.1); + + --vp-c-warning-1: #9a6700; + --vp-c-warning-2: #855800; + --vp-c-warning-3: #714b00; + --vp-c-warning-soft: rgba(154, 103, 0, 0.1); + + --vp-c-danger-1: #cf222e; + --vp-c-danger-2: #b91c28; + --vp-c-danger-3: #a01722; + --vp-c-danger-soft: rgba(207, 34, 46, 0.1); + + --soar-inline-code: #bc4c00; + --soar-inline-code-bg: rgba(188, 76, 0, 0.08); + + color-scheme: light; +} + +/* --- Dark palette (Nightsky, default) --- */ +.dark { + --vp-c-bg: #0d1117; + --vp-c-bg-alt: #0a0d12; + --vp-c-bg-elv: #161b22; + --vp-c-bg-soft: #161b22; + + --vp-c-default-1: #30363d; + --vp-c-default-2: #21262d; + --vp-c-default-3: #161b22; + --vp-c-default-soft: rgba(48, 54, 61, 0.4); + + --vp-c-divider: #21262d; + --vp-c-border: #30363d; + --vp-c-gutter: #21262d; + + --vp-c-text-1: #e6edf3; + --vp-c-text-2: #9aa4af; + --vp-c-text-3: #6e7681; + + /* Brand: cyan/blue twilight accent */ + --vp-c-brand-1: #58a6ff; + --vp-c-brand-2: #4f96ec; + --vp-c-brand-3: #388bfd; + --vp-c-brand-soft: rgba(56, 139, 253, 0.14); + + --vp-c-tip-1: #3fb9a2; + --vp-c-tip-2: #38a08c; + --vp-c-tip-3: #2f8576; + --vp-c-tip-soft: rgba(63, 185, 162, 0.14); + + --vp-c-warning-1: #d29922; + --vp-c-warning-2: #bd8a1f; + --vp-c-warning-3: #a8791b; + --vp-c-warning-soft: rgba(210, 153, 34, 0.14); + + --vp-c-danger-1: #f85149; + --vp-c-danger-2: #e0443d; + --vp-c-danger-3: #c83a34; + --vp-c-danger-soft: rgba(248, 81, 73, 0.14); + + --soar-inline-code: #f0883e; + --soar-inline-code-bg: rgba(240, 136, 62, 0.1); + + color-scheme: dark; +} + +/* --- Buttons --- */ +:root { + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-bg: var(--vp-c-brand-1); + --vp-button-brand-text: #ffffff; + --vp-button-brand-hover-text: #ffffff; +} + +/* Dark mode uses the lighter accent blue, so the button needs dark text */ +.dark { + --vp-button-brand-text: #06101f; + --vp-button-brand-hover-text: #06101f; +} + +/* --- Home hero --- */ +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: linear-gradient( + 120deg, + #58a6ff 20%, + #3fb9a2 60%, + #d29922 100% + ); + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + rgba(88, 166, 255, 0.4), + rgba(63, 185, 162, 0.3) + ); + --vp-home-hero-image-filter: blur(48px); +} + +.VPHero .name { + font-size: clamp(3rem, 8vw, 4.5rem); + letter-spacing: -0.03em; +} + +.VPHero .text { + color: var(--vp-c-text-1); + letter-spacing: -0.01em; +} + +.VPHero .tagline { + color: var(--vp-c-text-2); + max-width: 600px; +} + +/* --- Feature cards --- */ +.VPFeature { + background: var(--vp-c-bg-soft); + border: 1px solid var(--vp-c-divider); + transition: border-color 0.25s, transform 0.25s, box-shadow 0.25s; +} + +.VPFeature:hover { + border-color: var(--vp-c-brand-1); + transform: translateY(-3px); + box-shadow: 0 10px 30px -12px rgba(56, 139, 253, 0.35); +} + +.VPFeature .title { + color: var(--vp-c-text-1); +} + +/* --- Install command (under hero) --- */ +.install-command { + max-width: 1152px; + margin: 0 auto; + padding: 0 48px 8px; +} + +@media (max-width: 768px) { + .install-command { + padding: 0 24px 8px; + } +} + +.install-command-inner { + display: flex; + align-items: center; + gap: 12px; + padding: 14px 16px; + background: var(--vp-c-bg-soft); + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + font-family: var(--vp-font-family-mono); + overflow-x: auto; +} + +.install-prompt { + color: var(--vp-c-brand-1); + font-weight: 600; + user-select: none; +} + +.install-text { + flex: 1; + color: var(--vp-c-text-1); + background: none; + padding: 0; + white-space: nowrap; + font-size: 0.95em; +} + +.install-copy { + flex-shrink: 0; + padding: 5px 14px; + font-size: 0.8rem; + font-weight: 600; + font-family: var(--vp-font-family-base); + color: var(--vp-c-text-2); + background: var(--vp-c-default-3); + border: 1px solid var(--vp-c-border); + border-radius: 8px; + cursor: pointer; + transition: all 0.2s; +} + +.install-copy:hover, +.install-copy:focus-visible { + color: var(--vp-c-text-1); + border-color: var(--vp-c-brand-1); +} + +.install-copy.copied { + color: var(--vp-c-tip-1); + border-color: var(--vp-c-tip-1); +} + +.install-hint { + margin: 12px 2px 0; + font-size: 0.85rem; + color: var(--vp-c-text-3); + text-align: center; +} + +.install-hint code { + font-size: 0.82em; + color: var(--vp-c-text-2); +} + +/* --- Quick navigation (after features) --- */ +.quick-nav { + padding: 16px 24px 64px; +} + +.quick-nav-container { + max-width: 1152px; + margin: 0 auto; +} + +.quick-nav-heading { + font-size: 1.6rem; + font-weight: 700; + letter-spacing: -0.02em; + margin: 0 0 24px; + color: var(--vp-c-text-1); +} + +.quick-nav-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); + gap: 16px; +} + +.quick-nav-card { + padding: 20px 22px; + background: var(--vp-c-bg-soft); + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + transition: border-color 0.25s; +} + +.quick-nav-card:hover { + border-color: var(--vp-c-border); +} + +.quick-nav-card h3 { + margin: 0 0 12px; + font-size: 0.78rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--vp-c-text-3); +} + +.quick-nav-card ul { + list-style: none; + margin: 0; + padding: 0; +} + +.quick-nav-card li { + margin: 0; +} + +.quick-nav-card li + li { + margin-top: 8px; +} + +.quick-nav-card a { + color: var(--vp-c-text-1); + font-weight: 500; + font-size: 0.95rem; + text-decoration: none; + transition: color 0.2s; +} + +.quick-nav-card a:hover, +.quick-nav-card a:focus-visible { + color: var(--vp-c-brand-1); +} + +/* --- Content typography --- */ +.vp-doc h1, +.vp-doc h2, +.vp-doc h3, +.vp-doc h4 { + letter-spacing: -0.015em; +} + +.vp-doc h2 { + margin-top: 2.5rem; + border-top: 1px solid var(--vp-c-divider); + padding-top: 1.6rem; +} + +/* Inline code: amber, the Nightsky signature */ +.vp-doc :not(pre) > code { + color: var(--soar-inline-code); + background: var(--soar-inline-code-bg); + border-radius: 4px; + padding: 0.15em 0.4em; + font-size: 0.84em; +} + +.vp-doc a { + font-weight: 500; + text-underline-offset: 3px; +} + +/* Tables */ +.vp-doc th { + background: var(--vp-c-bg-soft); + color: var(--vp-c-text-1); +} + +.vp-doc tr:nth-child(2n) { + background: var(--vp-c-bg-soft); +} + +.dark .vp-doc tr:nth-child(2n) { + background: rgba(22, 27, 34, 0.4); +} + +/* Blockquote callouts (> **Note** style from the source docs) */ +.vp-doc blockquote { + border-left: 3px solid var(--vp-c-brand-1); + background: var(--vp-c-brand-soft); + border-radius: 0 8px 8px 0; + padding: 2px 18px; + margin: 18px 0; +} + +.vp-doc blockquote > p { + color: var(--vp-c-text-2); +} + +.vp-doc blockquote strong:first-child { + color: var(--vp-c-text-1); +} + +/* --- Code blocks --- */ +.dark { + --vp-code-block-bg: #0a0d12; +} + +.vp-doc div[class*='language-'] { + border: 1px solid var(--vp-c-divider); + border-radius: 10px; +} + +/* --- Navbar polish --- */ +.VPNavBar { + border-bottom: 1px solid var(--vp-c-divider); +} + +.VPNavBar.has-sidebar .content { + backdrop-filter: blur(8px); +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 00000000..0b139ea7 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,25 @@ +import { h } from 'vue' +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +import InstallCommand from './components/InstallCommand.vue' +import QuickNav from './components/QuickNav.vue' +import NotFound from './components/NotFound.vue' +import './custom.css' + +/** + * Custom Soar documentation theme. + * + * Extends the VitePress default theme with the Nightsky palette and injects + * an install command under the home hero plus a quick navigation grid after + * the feature cards. + */ +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + 'home-hero-after': () => h(InstallCommand), + 'home-features-after': () => h(QuickNav), + 'not-found': () => h(NotFound), + }) + }, +} satisfies Theme diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..139cefb5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,32 @@ +# Soar documentation + +Documentation site for [Soar](https://github.com/pkgforge/soar), built with +[VitePress](https://vitepress.dev) and a custom Nightsky theme. + +## Local development + +```sh +bun install +bun run dev +``` + +The site is served at `http://localhost:5173`. + +## Build + +```sh +bun run build +bun run preview +``` + +The static site is generated into `.vitepress/dist`. + +## Structure + +- `index.md` is the home page. The hero, install command, and quick navigation + come from the custom theme in `.vitepress/theme`. +- Page content lives as Markdown files at the docs root, with release notes + under `releases/`. +- The `/install.sh` path used by the install command is redirected to soar's + install script by Cloudflare, so it is not served from this site. +- Navigation and sidebar are defined in `.vitepress/config.mts`. diff --git a/docs/bun.lock b/docs/bun.lock new file mode 100644 index 00000000..ffb371e2 --- /dev/null +++ b/docs/bun.lock @@ -0,0 +1,360 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "soar-docs", + "devDependencies": { + "vitepress": "^1.6.3", + "vue": "^3.5.13", + }, + }, + }, + "packages": { + "@algolia/abtesting": ["@algolia/abtesting@1.21.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-kGvHfBa9oQCvZh0YXeguSToBD9GNJ+gzUZQ9KPTg+KSsM36obYcsKPoX0NnlJtPflHXu7RkMaIi44xs9meR6Zw=="], + + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], + + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A=="], + + "@algolia/autocomplete-preset-algolia": ["@algolia/autocomplete-preset-algolia@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA=="], + + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.7", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg=="], + + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-Zt2GjIm7vsaf7K23tk5JmtcVNc38G9p0C2L2Lrm06miyLE/NL2etHtHInvuLc1DjxTp7Y2nId4X/tzwo372K8Q=="], + + "@algolia/client-analytics": ["@algolia/client-analytics@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-7BueMuWYg/KBA2EX9zsQ+3OAleEyrJcB+SV5Al/9pLjMQq5mXB/8M5HaUPqZwN812g5kLzj9j43VThlZgWq0hg=="], + + "@algolia/client-common": ["@algolia/client-common@5.55.0", "", {}, "sha512-pJZIyhvUrs+B7c5Lw0iP5yP/NsqJMda7pKRYbfG4KtfGIVSMcAalZhdqL5UX8Z9DOC4KxO9tKV5RDeVjZU0VfQ=="], + + "@algolia/client-insights": ["@algolia/client-insights@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-RydkKDhx0GWTYuw0ndTXHGM8hD8hgwftKE65FfnJZb5bPc9CevOqv3qNPUQiviAwkqT9hQNH31uDGeV3yZkgfA=="], + + "@algolia/client-personalization": ["@algolia/client-personalization@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-XiS7gdFq/COWiwdWXZ8+RHuewfEo03TkGESk44zU8zTc/Z6R8fm4DNmV52swJKkeB2N9iC7NKpgpM22OOkcgTw=="], + + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-LBEJ/q+hn1nJ0aYg5IcWgLNCPjWHTahWmpHNx1qUZMho+9CyWM6LaEnhac45UHjQm/j0m374HP685VrpL133lA=="], + + "@algolia/client-search": ["@algolia/client-search@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-2/9jUXKH4IcdU5qxH6cbDH46ZBe46G7xr+MrcHwgEXZcUfdAvUgLSH53MAWuMgxvw0G5yoqiWMifHc62Os0fiQ=="], + + "@algolia/ingestion": ["@algolia/ingestion@1.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-80tKsQgxXWo+jK0v4YGCHqyTEXawhAKYyr3kOdN51ElfRqUFjZNPVhZk6vRiqSqXfvrH85ytacT3cbJR6+qolA=="], + + "@algolia/monitoring": ["@algolia/monitoring@1.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-4UjmAL8ywGW4rCfK6Qmgw3wIjbrO2wl2s4Eq56JTiN40L2t0XTv0HZkYAmr6nfeiXO0he/2crvZRX6SATSepag=="], + + "@algolia/recommend": ["@algolia/recommend@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-LMpJPtIkfDsHIx5Ga+baNr22ntYbY+e2wT7MSIc/FjAnu9wnBFhx1H/GfhmP/c5/IvbThDX+3ilxPRjSfCI8aA=="], + + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0" } }, "sha512-tDymJ7nFOAoUuecma3usK6o94dp8m4HYFDGh4ByYQXWkv14cpmDn+nWdylmcZO0Qvco107vqDo4+Anksnl8w1Q=="], + + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0" } }, "sha512-6IDSB5o5dkDPQ4LdOW0Yuw/qy5MdWlO2xDHgPVZgW4YDjbxvnX5PAiV7/WWZdWyVObScZZnnHpPbiqfYs/zBLg=="], + + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.55.0", "", { "dependencies": { "@algolia/client-common": "5.55.0" } }, "sha512-Yyyne4l//vDSdg4MhYJkaVne+KEPi833eCj3/T/87ernTwrvP6j9biXXZELsN8sLI/f2ndV/vugDIy2jdJQB6g=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], + + "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + + "@docsearch/css": ["@docsearch/css@3.8.2", "", {}, "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="], + + "@docsearch/js": ["@docsearch/js@3.8.2", "", { "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ=="], + + "@docsearch/react": ["@docsearch/react@3.8.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", "react-dom": ">= 16.8.0 < 19.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.86", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-t3jck5qPQuK1qy+bRn9eCoDQhIB7XSazKz1Fjp8hcan3XOAsTI5Mq/s3F0ekOKSvMQqkVORYK6ns6o6T9f5EMA=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.62.0", "", { "os": "android", "cpu": "arm" }, "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.62.0", "", { "os": "android", "cpu": "arm64" }, "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.62.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.62.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.62.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.62.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.62.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.62.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.62.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.62.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.62.0", "", { "os": "none", "cpu": "arm64" }, "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.62.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.62.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.62.0", "", { "os": "win32", "cpu": "x64" }, "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.62.0", "", { "os": "win32", "cpu": "x64" }, "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA=="], + + "@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="], + + "@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="], + + "@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="], + + "@shikijs/transformers": ["@shikijs/transformers@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg=="], + + "@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="], + + "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.4", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA=="], + + "@vue/compiler-core": ["@vue/compiler-core@3.5.38", "", { "dependencies": { "@babel/parser": "^7.29.7", "@vue/shared": "3.5.38", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-s99aGxWYig9ErHbct27KXEGhrBYlRI6c4MwAgXErOAbX9xiW37/uMa+XUDO69zLz83dng8UUZ70CTOJrLrYrEQ=="], + + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.38", "", { "dependencies": { "@vue/compiler-core": "3.5.38", "@vue/shared": "3.5.38" } }, "sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw=="], + + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.38", "", { "dependencies": { "@babel/parser": "^7.29.7", "@vue/compiler-core": "3.5.38", "@vue/compiler-dom": "3.5.38", "@vue/compiler-ssr": "3.5.38", "@vue/shared": "3.5.38", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.15", "source-map-js": "^1.2.1" } }, "sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg=="], + + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.38", "", { "dependencies": { "@vue/compiler-dom": "3.5.38", "@vue/shared": "3.5.38" } }, "sha512-7s+W5Gc42FGxZMcuwl8H5B29T8BJPMdBT7KHFE+BbAuZ/iTEdTtv7z2XiMjiaUUw4w3ZcCEdHs36RuYJ2VA7bA=="], + + "@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="], + + "@vue/devtools-kit": ["@vue/devtools-kit@7.7.9", "", { "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA=="], + + "@vue/devtools-shared": ["@vue/devtools-shared@7.7.9", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA=="], + + "@vue/reactivity": ["@vue/reactivity@3.5.38", "", { "dependencies": { "@vue/shared": "3.5.38" } }, "sha512-pG6LV/NDNRbKizcUjFFLAfjaL8mcv4DmR9avNcUw2gDHBzZneuS2TWCmp633ynzxz9YYKNeEPK2I8Wraqy2HUQ=="], + + "@vue/runtime-core": ["@vue/runtime-core@3.5.38", "", { "dependencies": { "@vue/reactivity": "3.5.38", "@vue/shared": "3.5.38" } }, "sha512-iyW8WVfF1CpCXxncZY5Ei6rSd6oZr5DgEom//fUjRBRl56AXPD+s9ATvukRt77ZFTuYlnVA1bxY+dJB94tWVYw=="], + + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.38", "", { "dependencies": { "@vue/reactivity": "3.5.38", "@vue/runtime-core": "3.5.38", "@vue/shared": "3.5.38", "csstype": "^3.2.3" } }, "sha512-apX2wt9sdfDshS+a2xueFZLVpt0GkRJZSoPmrW/SA4yzXTznhfcMVW59gr7h4YQeY0vJhdJkk2rsIDwgfFgC5A=="], + + "@vue/server-renderer": ["@vue/server-renderer@3.5.38", "", { "dependencies": { "@vue/compiler-ssr": "3.5.38", "@vue/shared": "3.5.38" }, "peerDependencies": { "vue": "3.5.38" } }, "sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw=="], + + "@vue/shared": ["@vue/shared@3.5.38", "", {}, "sha512-FTW0AFZNaK5/mOqvGBwVfUlNLU38TiQn4+DQgIFUnrBBJQ1crMJ82yeGQLV5jyKFsO8yRukpbuP7x+nRbH6aug=="], + + "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + + "@vueuse/integrations": ["@vueuse/integrations@12.8.2", "", { "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g=="], + + "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + + "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + + "algoliasearch": ["algoliasearch@5.55.0", "", { "dependencies": { "@algolia/abtesting": "1.21.0", "@algolia/client-abtesting": "5.55.0", "@algolia/client-analytics": "5.55.0", "@algolia/client-common": "5.55.0", "@algolia/client-insights": "5.55.0", "@algolia/client-personalization": "5.55.0", "@algolia/client-query-suggestions": "5.55.0", "@algolia/client-search": "5.55.0", "@algolia/ingestion": "1.55.0", "@algolia/monitoring": "1.55.0", "@algolia/recommend": "5.55.0", "@algolia/requester-browser-xhr": "5.55.0", "@algolia/requester-fetch": "5.55.0", "@algolia/requester-node-http": "5.55.0" } }, "sha512-af+rI+tUVeS9KWHPAZQHIHPOIC3StPRR6IwQu2nz1aQoTL6Gs5Ty3KsHCgbXMHOpoh9QqSjq8F3KJ8xmaCZSBA=="], + + "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "focus-trap": ["focus-trap@7.8.0", "", { "dependencies": { "tabbable": "^6.4.0" } }, "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], + + "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], + + "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], + + "oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="], + + "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], + + "preact": ["preact@10.29.2", "", {}, "sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ=="], + + "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], + + "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rollup": ["rollup@4.62.0", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.62.0", "@rollup/rollup-android-arm64": "4.62.0", "@rollup/rollup-darwin-arm64": "4.62.0", "@rollup/rollup-darwin-x64": "4.62.0", "@rollup/rollup-freebsd-arm64": "4.62.0", "@rollup/rollup-freebsd-x64": "4.62.0", "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", "@rollup/rollup-linux-arm-musleabihf": "4.62.0", "@rollup/rollup-linux-arm64-gnu": "4.62.0", "@rollup/rollup-linux-arm64-musl": "4.62.0", "@rollup/rollup-linux-loong64-gnu": "4.62.0", "@rollup/rollup-linux-loong64-musl": "4.62.0", "@rollup/rollup-linux-ppc64-gnu": "4.62.0", "@rollup/rollup-linux-ppc64-musl": "4.62.0", "@rollup/rollup-linux-riscv64-gnu": "4.62.0", "@rollup/rollup-linux-riscv64-musl": "4.62.0", "@rollup/rollup-linux-s390x-gnu": "4.62.0", "@rollup/rollup-linux-x64-gnu": "4.62.0", "@rollup/rollup-linux-x64-musl": "4.62.0", "@rollup/rollup-openbsd-x64": "4.62.0", "@rollup/rollup-openharmony-arm64": "4.62.0", "@rollup/rollup-win32-arm64-msvc": "4.62.0", "@rollup/rollup-win32-ia32-msvc": "4.62.0", "@rollup/rollup-win32-x64-gnu": "4.62.0", "@rollup/rollup-win32-x64-msvc": "4.62.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA=="], + + "search-insights": ["search-insights@2.17.3", "", {}, "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ=="], + + "shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], + + "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], + + "vue": ["vue@3.5.38", "", { "dependencies": { "@vue/compiler-dom": "3.5.38", "@vue/compiler-sfc": "3.5.38", "@vue/runtime-dom": "3.5.38", "@vue/server-renderer": "3.5.38", "@vue/shared": "3.5.38" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-vAMKHfImQlYSy0C+PBue4s3ERZ2xGKfgZg5GXAsLInq1dyh2H78ILVP5sK0KPFPVW4kv+OGCIvBEondcjpZp7A=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + } +} diff --git a/docs/cli-reference.md b/docs/cli-reference.md new file mode 100644 index 00000000..42cce5dc --- /dev/null +++ b/docs/cli-reference.md @@ -0,0 +1,190 @@ +--- +title: CLI Reference +description: Global CLI options, environment variables, and common flag combinations for the soar package manager. +--- + +# CLI Reference + +This page documents the global options that apply across soar commands, along with the environment variables that influence soar's behavior. + +## Quick Reference + +| Option | Short | Description | +|--------|-------|-------------| +| `--verbose` | `-v` | Increase output verbosity | +| `--quiet` | `-q` | Suppress all output except errors | +| `--json` | `-j` | Output results in JSON format | +| `--no-color` | - | Disable colored output | +| `--no-progress` | - | Disable progress bars | +| `--profile` | `-p` | Use a specific profile | +| `--config` | `-c` | Specify custom config file path | +| `--proxy` | `-P` | Set HTTP/HTTPS proxy server | +| `--header` | `-H` | Add custom HTTP headers | +| `--user-agent` | `-A` | Set custom User-Agent string | +| `--system` | `-S` | Operate in system-wide mode (requires root) | + +## Verbosity Control + +### `--verbose` / `-v` + +Increase output verbosity. It can be used multiple times for more detail (`-vv`, `-vvv`). + +```bash +soar -v install neovim +soar -vv sync +``` + +### `--quiet` / `-q` + +Suppress all non-error output. + +```bash +soar -q install nodejs +``` + +## Output Format + +### `--json` / `-j` + +Output results in JSON format for parsing. + +```bash +soar --json query neovim +soar --json search python | jq '.[] | .name' +``` + +## Display Options + +### `--no-color` + +Disable colored output. + +```bash +soar --no-color install ffmpeg +``` + +### `--no-progress` + +Disable progress bars. + +```bash +soar --no-progress sync > sync.log +``` + +## Configuration + +### `--profile` / `-p` + +Use a specific profile. + +```bash +soar --profile work install vscode +``` + +Profiles are defined in `~/.config/soar/config.toml`: + +```toml +[profile.work] +root_path = "/opt/soar-work" +``` + +### `--config` / `-c` + +Specify a custom configuration file path. + +```bash +soar --config /path/to/config.toml install neovim +``` + +## Network Options + +### `--proxy` / `-P` + +Set an HTTP/HTTPS proxy server. + +```bash +soar --proxy http://proxy.example.com:8080 install python +soar --proxy http://user:pass@proxy.example.com:8080 sync +``` + +### `--header` / `-H` + +Add custom HTTP headers. + +```bash +soar --header "Authorization: Bearer mytoken" sync +soar -H "X-Api-Key: secret123" install package +``` + +### `--user-agent` / `-A` + +Set a custom User-Agent string. + +```bash +soar --user-agent "MyApp/1.0" install python +``` + +## System Mode + +### `--system` / `-S` + +Operate in system-wide mode. This requires root. + +```bash +sudo soar --system install docker +``` + +System paths: + +- Config: `/etc/soar/config.toml` +- Root: `/opt/soar` +- Binaries: `/opt/soar/bin` + +## Common Combinations + +::: code-group + +```bash [Scripting] +soar --json --quiet install python +``` + +```bash [Debugging] +soar -vv --no-progress install neovim +``` + +```bash [CI/CD with proxy] +soar --json --proxy http://proxy.corp.com:8080 sync +``` + +```bash [System installation] +sudo soar --system install docker +``` + +::: + +## Environment Variables + +| Variable | Purpose | Example | +|----------|---------|---------| +| `HTTP_PROXY` | Set HTTP/HTTPS proxy | `export HTTP_PROXY=http://proxy:8080` | +| `SOAR_CONFIG` | Custom config file path | `export SOAR_CONFIG=/path/to/config.toml` | +| `SOAR_PACKAGES_CONFIG` | Custom packages.toml path | `export SOAR_PACKAGES_CONFIG=/path/to/packages.toml` | +| `NO_COLOR` | Disable colored output | `export NO_COLOR=1` | +| `SOAR_ROOT` | Override root directory | `export SOAR_ROOT=/custom/soar` | +| `SOAR_BIN` | Override bin path | `export SOAR_BIN=/custom/bin` | +| `SOAR_DB` | Override database path | `export SOAR_DB=/custom/db` | +| `SOAR_CACHE` | Override cache path | `export SOAR_CACHE=/custom/cache` | +| `SOAR_PACKAGES` | Override packages path | `export SOAR_PACKAGES=/custom/packages` | +| `SOAR_REPOSITORIES` | Override repositories path | `export SOAR_REPOSITORIES=/custom/repos` | +| `SOAR_PORTABLE_DIRS` | Override portable dirs path | `export SOAR_PORTABLE_DIRS=/custom/portable` | +| `SOAR_DESKTOP` | Override desktop entries path | `export SOAR_DESKTOP=/custom/applications` | +| `SOAR_STEALTH` | Use default config without reading file | `export SOAR_STEALTH=1` | +| `SOAR_NIGHTLY` | Force nightly update channel (self update) | `export SOAR_NIGHTLY=1` | +| `SOAR_RELEASE` | Force stable update channel (self update) | `export SOAR_RELEASE=1` | + +## See Also + +- [Configuration](./configuration.md) for the configuration file reference +- [Profiles](./profiles.md) for managing multiple installation profiles +- [Installation](./installation.md) for the installation guide +- [Health & Diagnostics](./health.md) for health checks and debugging diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..cc8ec544 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,220 @@ +--- +title: Configuration +description: Reference for soar's config.toml options, repositories, environment variables, and common fixes. +--- + +# Configuration + +Soar stores configuration at `~/.config/soar/config.toml`. If the file doesn't exist, sensible defaults are used. + +::: tip Quick Start +Run `soar defconfig` to create a default configuration file. +::: + +## Configuration Reference + +The options below are grouped by category. Every value reflects soar's defaults. + +### Paths + +Control where soar stores its data. + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `cache_path` | String | `~/.local/share/soar/cache` | Directory for cached package files | +| `db_path` | String | `~/.local/share/soar/db` | Path to package database | +| `bin_path` | String | `~/.local/share/soar/bin` | Directory for binary symlinks | +| `repositories_path` | String | `~/.local/share/soar/repos` | Local repository clones | +| `portable_dirs` | String | `~/.local/share/soar/portable-dirs` | Base path for portable app data (AppImage/FlatImage/RunImage/Wrappe only) | + +### Performance + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `parallel` | Boolean | `true` | Enable parallel downloads | +| `parallel_limit` | Integer | `4` | Max parallel downloads (1-16) | +| `ghcr_concurrency` | Integer | `8` | Max GHCR concurrent requests (1-32) | +| `search_limit` | Integer | `20` | Max search results (5-100) | +| `cross_repo_updates` | Boolean | `false` | Allow cross-repo updates (not implemented) | + +### Package Installation + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `install_patterns` | Array | `["!*.log", "!SBUILD", "!*.json", "!*.version"]` | Files to exclude during installation | + +### Security + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `signature_verification` | Boolean | `null` (auto) | Enable package signature verification | + +### Desktop Integration + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `desktop_integration` | Boolean | `null` (repo-specific) | Enable desktop menu entries | + +### Repository Sync + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `sync_interval` | String | `"3h"` | How often to sync repositories | + +Special `sync_interval` values: `"always"`, `"never"`, `"auto"` (3h), or a duration like `"30m"`, `"6h"`, `"1d"`. + +### Display + +| Configuration Option | Type | Default | Description | +|---------------------|------|---------|-------------| +| `display.progress_style` | String | `"modern"` | Progress bar style: `classic`, `modern`, `minimal` | +| `display.icons` | Boolean | `true` | Show Unicode icons | +| `display.spinners` | Boolean | `true` | Show animated spinners | + +## Key Options + +### Path Settings + +Control where soar stores data. Add `bin_path` to your PATH: + +```sh +export PATH="$HOME/.local/share/soar/bin:$PATH" +``` + +### Performance + +- **`parallel` / `parallel_limit`**: Increase for faster downloads on stable connections, decrease for slow or unstable connections. +- **`ghcr_concurrency`**: Adjust if experiencing GHCR rate limiting. + +### Install Patterns + +Glob patterns for files to exclude during installation. Patterns starting with `!` are exclusions: + +```toml +install_patterns = [ + "!*.log", # Exclude log files + "!SBUILD", # Exclude build scripts + "!*.debug", # Exclude debug symbols +] +``` + +### Security + +**`signature_verification`**: Set to `true` for maximum security or `false` for trusted local repos. This setting can be overridden per-repository. + +### Desktop Integration + +**`desktop_integration`**: Enable this for GUI applications to appear in application menus. The setting can be configured globally or per-repository. + +### Display Settings + +```toml +[display] +progress_style = "modern" # classic, modern, minimal +icons = true +spinners = true +``` + +## Repositories + +::: tip +You can manage repositories from the command line with `soar repo add/update/remove/list`. See [Repository Management](./repo.md). +::: + +Repositories are defined as arrays of tables in your configuration: + +```toml +[[repositories]] +name = "soarpkgs" +url = "https://github.com/pkgforge/soarpkgs/releases/latest/download/metadata-x86_64-linux.sdb.zstd" +pubkey = "RWQ109gKujRqohsA7RERlXFfeJi23EcHN3Dz8TxyPAywa5mLw/fbcbU4" +desktop_integration = true +enabled = true +signature_verification = true +sync_interval = "3h" +``` + +### Repository Fields + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `name` | String | (required) | Unique repository name. **Note:** `"local"` is reserved | +| `url` | String | (required) | URL to repository metadata | +| `pubkey` | String | `null` | Repository's public key (inline string) | +| `enabled` | Boolean | `true` | Enable/disable this repository | +| `desktop_integration` | Boolean | `true` | Enable desktop integration for packages | +| `signature_verification` | Boolean | auto | Enable signature verification (auto-enabled if `pubkey` exists) | +| `sync_interval` | String | `"3h"` | Sync interval: `"always"`, `"never"`, `"auto"`, or duration | + +### Default Repositories + +Soar includes one default repository for Linux platforms (aarch64, x86_64): + +- **soarpkgs**: The unified package repository + - URL: `https://github.com/pkgforge/soarpkgs/releases/latest/download/metadata-{platform}.sdb.zstd` + - Signature verification enabled + - Desktop integration enabled + +## Managing Configuration + +::: code-group + +```sh [View] +soar config +``` + +```sh [Edit] +soar config -e +``` + +```sh [Custom path] +soar -c /path/to/config.toml [subcommand] +``` + +::: + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `SOAR_CONFIG` | Custom config file path | +| `SOAR_ROOT` | Root directory override (affects all profiles) | +| `SOAR_CACHE` | Cache directory override | +| `SOAR_BIN` | Binary directory override | +| `SOAR_DB` | Database path override | +| `SOAR_PACKAGES` | Packages directory override | +| `SOAR_REPOSITORIES` | Repositories directory override | +| `SOAR_PORTABLE_DIRS` | Portable directories path override | +| `RUST_LOG` | Debug logging level (`debug`, `info`, `trace`) | + +::: info +Environment variables take precedence over configuration file settings and profile paths. +::: + +## Common Issues + +### Invalid TOML Syntax + +Check for unclosed brackets, missing quotes, or duplicate names. Use `soar config` to validate. + +### Command Not Found + +Add `bin_path` to your PATH in `~/.bashrc` or `~/.zshrc`. + +### Repository Not Syncing + +Run `soar sync` manually. Check network connectivity and repository URLs. + +### Signature Verification Failed + +Verify the `pubkey` value is correct. Run `soar sync` to update repository data. + +### Garbled Output + +Switch to classic display mode: + +```toml +[display] +progress_style = "classic" +icons = false +``` diff --git a/docs/declarative.md b/docs/declarative.md new file mode 100644 index 00000000..a07028b0 --- /dev/null +++ b/docs/declarative.md @@ -0,0 +1,679 @@ +--- +title: Declarative Package Management +description: Define packages in packages.toml and apply them in one command to keep consistent environments across machines. +--- + +# Declarative Package Management + +Soar supports declarative package management through `packages.toml`. Define your desired packages and apply them in one command to maintain consistent environments across machines. + +This page covers the file structure, every package field, advanced features such as hooks, builds, sandboxing, and portable mode, and the commands used to apply your configuration. + +## Configuration File + +Create `packages.toml` at `~/.config/soar/packages.toml`: + +```sh +soar defpackages +``` + +## File Structure + +The `packages.toml` file supports two top-level sections: + +- **`[defaults]`** - Default settings applied to all packages +- **`[packages]`** - Package specifications + +```toml +[defaults] +profile = "default" +binary_only = false +install_patterns = ["!*.log", "!SBUILD"] + +[packages] +# Package specifications go here +``` + +## Defaults Section + +The `[defaults]` section sets default values that apply to all packages unless overridden. + +| Field | Type | Description | +|-------|------|-------------| +| `profile` | String | Default profile to install packages to | +| `binary_only` | Boolean | Only extract binaries, skip other files | +| `install_patterns` | Array of Strings | File patterns to include/exclude during installation | +| `sandbox` | Object | Default sandbox configuration applied to all packages. Per-package `sandbox` blocks override individual fields; `fs_read`/`fs_write` lists are concatenated with these defaults | + +## Packages Section + +The `[packages]` section contains package specifications in multiple formats. + +### Simple String Format + +```toml +[packages] +# Latest version (never pinned) +bat = "*" + +# Specific version (auto-pinned for repo packages) +ripgrep = "14.1.0" + +# Using table format (auto-pinned for repo packages) +fd = { version = "9.0.0" } + +# Remote packages are not auto-pinned +remote-tool = { url = "https://example.com/tool.tar.gz" } +``` + +### Version Resolution and Pinning + +| Spec Format | Version | Pinned | Notes | +|-------------|---------|--------|-------| +| `pkg = "*"` | Latest | No | Always installs latest version | +| `pkg = "1.2.3"` | 1.2.3 | Yes (repo only) | Pinned for repository packages | +| `pkg = { version = "1.2.3" }` | 1.2.3 | Yes (repo only) | Pinned for repository packages | +| `pkg = { url = "..." }` | Detected | No | Remote packages not auto-pinned | +| `pkg = { version = "1.2.3", pinned = false }` | 1.2.3 | Yes | `pinned = false` does **not** unpin a versioned repo package | +| `pkg = { url = "...", pinned = true }` | Detected | Yes | Explicitly pin remote package | + +**Key points:** +- Repository packages with a specific version are always pinned. Setting `pinned = false` does not override this. A versioned non-remote package stays pinned. +- Remote packages (url/github/gitlab) are never auto-pinned unless you explicitly set `pinned = true` +- Pinned packages are skipped during auto-update operations +- Version `*` always resolves to latest and is never pinned +- After installing a package with version `"*"`, soar updates your `packages.toml` with the specific version installed + +### Detailed Format + +```toml +[packages.my_package] +pkg_id = "pkg-bin" +repo = "soarpkgs" +version = "1.0.0" +pinned = true +portable = { home = "~/.pkg", config = "~/.pkg/config" } +``` + +## Package Options Reference + +| Field | Type | Description | +|-------|------|-------------| +| `version` | String | Package version to install (`"*"` for latest) | +| `pkg_id` | String | Package variant/family identifier | +| `repo` | String | Install from a specific repository | +| `url` | String | Install directly from a URL | +| `bsum` | String | Expected BLAKE3 checksum (hex) for `url`/`github`/`gitlab` downloads; install aborts on mismatch | +| `pinned` | Boolean | Prevent automatic updates (default: `false`) | +| `profile` | String | Install to a specific profile | +| `github` | String | GitHub repo in `owner/repo` format | +| `gitlab` | String | GitLab repo in `owner/repo` format | +| `asset_pattern` | String | Glob pattern to match release assets | +| `tag_pattern` | String | Glob pattern to match release tags | +| `include_prerelease` | Boolean | Include pre-release versions | +| `version_command` | String | Custom command to fetch latest version and download URL | +| `binary_only` | Boolean | Only extract binaries, skip other files | +| `binaries` | Array | Map multiple binaries to custom names (see [Binary Mappings](#binary-mappings)) | +| `install_patterns` | Array | File patterns to include/exclude | +| `portable` | Object | Configure portable directories (see [Portable](#portable)) | +| `hooks` | Object | Lifecycle hooks (see [Hooks](#hooks)) | +| `build` | Object | Build from source (see [Build From Source](#build-from-source)) | +| `sandbox` | Object | Security sandbox (see [Sandbox](#sandbox)) | +| `pkg_type` | String | Override package type detection | +| `entrypoint` | String | Entry point executable name | +| `nested_extract` | String | Path to nested archive to extract | +| `extract_root` | String | Subdirectory to treat as root | +| `arch_map` | Object | Map standard architecture names to custom values used by the package source (see [Architecture Mapping](#architecture-mapping)) | + +### Binary Mappings + +Map multiple executables within a package to custom symlink names. The `source` field supports glob patterns to match multiple files at once. + +| Field | Type | Description | +|-------|------|-------------| +| `source` | String | Path or glob pattern to match executables within package | +| `link_as` | String | Custom symlink name (optional, defaults to the source filename) | + +When a glob matches multiple files, each is symlinked using its original filename. `link_as` is only used when a single file matches. + +### Hooks + +Execute commands at various stages of the package lifecycle: + +| Hook | Description | +|------|-------------| +| `post_download` | Run after download, before extraction | +| `post_extract` | Run after extraction | +| `post_install` | Run after symlinks created | +| `pre_remove` | Run before package removal | + +**Available environment variables:** `$INSTALL_DIR`, `$BIN_DIR`, `$PKG_NAME`, `$PKG_ID`, `$PKG_VERSION` + +```toml +[packages.myapp] +url = "https://example.com/myapp-1.0.0.tar.gz" +hooks = { post_install = "myapp --init" } +``` + +### Build From Source + +| Field | Type | Description | +|-------|------|-------------| +| `commands` | Array | Shell commands to run sequentially | +| `dependencies` | Array | Required tools (checked via `which`) | + +**Available environment variables:** `$INSTALL_DIR`, `$BIN_DIR`, `$PKG_NAME`, `$PKG_ID`, `$PKG_VERSION`, `$NPROC` + +```toml +[packages.custom-tool] +url = "https://example.com/tool-1.0.0.tar.gz" + +[packages.custom-tool.build] +commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"] +dependencies = ["gcc", "make"] +``` + +### Sandbox + +Restrict filesystem and network access for hooks and build commands using Linux's Landlock LSM (kernel 5.13+). + +| Field | Type | Description | +|-------|------|-------------| +| `enabled` | Boolean | Whether sandboxing is enabled (default: `true` when Landlock is available). Set to `false` to skip sandboxing entirely (overrides `require`) | +| `require` | Boolean | Fail if Landlock is unavailable instead of falling back to unsandboxed execution (default: `false`) | +| `fs_read` | Array | Additional readable paths (beyond defaults like `/usr`, `/lib`) | +| `fs_write` | Array | Additional writable paths (beyond install dir and `/tmp`) | +| `network` | Boolean | Allow network access (requires Landlock V4+, kernel 6.7+) | + +```toml +[packages.untrusted-tool] +url = "https://example.com/tool-1.0.0.tar.gz" +sandbox = { require = true, network = false } +``` + +### Portable + +Configure portable mode for AppImage, FlatImage, RunImage, and Wrappe packages. Creates symlinks from expected data directories to custom locations. + +| Field | Type | Description | +|-------|------|-------------| +| `path` | String | Sets both `home` and `config` to the same path | +| `home` | String | Portable home directory | +| `config` | String | Portable config directory | +| `share` | String | Portable share directory | +| `cache` | String | Portable cache directory | + +**Format support:** AppImage/RunImage (all fields), FlatImage (only `config`), Wrappe (only `path`) + +```toml +[packages.obsidian] +url = "https://example.com/obsidian.AppImage" +portable = { path = "~/.obsidian-data" } +``` + +### Architecture Mapping + +`arch_map` is a per-package field that maps standard architecture names to the +custom values used by a package source. The keys are the bare architecture +names reported by the running system (`x86_64` or `aarch64`), and the values +are whatever the source uses (e.g. `amd64`, `arm64`, `x64`). The mapped value +is substituted for the `{arch}` placeholder in `url` and `asset_pattern`. + +```toml +[packages.mytool] +url = "https://example.com/mytool-{version}-{arch}.tar.gz" + +[packages.mytool.arch_map] +x86_64 = "amd64" +aarch64 = "arm64" +``` + +On an `x86_64` machine this resolves `{arch}` to `amd64`. If no mapping is +provided for the current architecture, the bare name (`x86_64`/`aarch64`) is +used as-is. The `{os}` placeholder resolves to the operating system (e.g. +`linux`), and `{version}` resolves to the package version with any leading +`v` stripped. + +## GitHub/GitLab Integration + +Install packages directly from GitHub or GitLab releases: + +```toml +[packages] +# From GitHub releases +gh-release = { github = "cli/cli" } + +# With asset pattern +gh-release = { + github = "cli/cli", + asset_pattern = "gh_*_linux_amd64.tar.gz" +} + +# With tag pattern +gh-beta = { + github = "owner/repo", + tag_pattern = "v2*", + include_prerelease = true +} + +# From GitLab +gl-release = { gitlab = "gitlab-org/gitlab" } +``` + +::: warning Glob patterns, not regex +`asset_pattern` and `tag_pattern` use **glob patterns**, not regex. Supported patterns include: +- `*` matches any sequence of characters +- `?` matches any single character +- `[abc]` matches any character in the set +- `[!abc]` matches any character not in the set +::: + +## Version Command + +The `version_command` field is used for custom URL packages to detect what version is available from a remote source BEFORE installation. This tells soar what version it would download if it were to install the package. + +### When It Runs + +The `version_command` runs BEFORE installation for custom URL packages to: + +1. **Detect remote version**: Query the remote source to find what version is available +2. **Generate download URL**: Optionally provide the exact download URL for that version +3. **Report size**: Optionally provide the download size for progress display + +This is primarily useful for custom URL packages where the download URL needs the version number substituted, but the version isn't embedded in the URL you configure. + +### Output Format + +The `version_command` must output exactly 3 lines: + +``` + + + +``` + +- **Line 1** (required): The version available at the remote source (e.g., `1.2.3` or `v1.2.3`) +- **Line 2** (optional): Download URL for that version. If omitted or empty, soar uses the `url` field with `{version}` placeholder substituted +- **Line 3** (optional): Size of download in bytes for progress display + +### When to Use version_command + +Use `version_command` for custom URL packages when: + +1. **Your URL uses `{version}` placeholder** but you need to dynamically discover what version is available +2. **The remote source has a version API or endpoint** you can query +3. **You need to parse a download page** to extract version information +4. **You want to provide a custom download URL** that differs from the template + +::: info +For GitHub/GitLab packages, soar already handles version detection automatically. You typically don't need `version_command` unless you have special requirements. +::: + +### Examples + +**Query GitHub API for latest release:** + +```toml +[packages.my-tool] +url = "https://example.com/downloads/my-tool-{version}.tar.gz" +version_command = """ + curl -s https://api.github.com/repos/owner/my-tool/releases/latest | \\ + jq -r '.tag_name' +""" +``` + +This fetches the latest release tag from GitHub and outputs it. Soar then uses that version to substitute into the `url` field. + +**Query a version.json endpoint:** + +```toml +[packages.api-tool] +url = "https://example.com/downloads/tool-{version}.zip" +version_command = """ + VERSION=$(curl -s https://example.com/api/tool/latest | jq -r '.version') + echo "$VERSION" + echo "https://example.com/downloads/tool-$VERSION.zip" + echo "$(curl -sI https://example.com/downloads/tool-$VERSION.zip | grep -i content-length | awk '{print $2}' | tr -d '\\r')" +""" +``` + +This queries a version.json API endpoint, extracts the version, constructs the download URL, and even fetches the file size. + +**Parse a download page for version:** + +```toml +[packages.scrape-tool] +url = "https://example.com/downloads/tool-{version}.tar.gz" +version_command = """ + curl -s https://example.com/downloads.html | \\ + grep -oP 'tool-\\d+\\.\\d+\\.\\d+\\.tar\\.gz' | \\ + sed 's/tool-//' | sed 's/.tar.gz//' | \\ + sort -V | tail -n1 +""" +``` + +This scrapes the downloads page, extracts version numbers from filenames, and returns the latest one. + +**Strip version prefix:** + +```toml +[packages.custom-tool] +url = "https://example.com/{version}/download.tar.gz" +# Remote returns "v1.2.3" but we want "1.2.3" +version_command = """ + VERSION=$(curl -s https://example.com/latest | grep -oP 'v\\d+\\.\\d+\\.\\d+') + echo "${VERSION#v}" # Strip 'v' prefix +""" +``` + +### Best Practices + +1. **Use jq for JSON APIs**: More reliable than grep for parsing + ```toml + version_command = "curl -s https://api.example.com/latest | jq -r '.version'" + ``` + +2. **Handle missing API endpoints gracefully**: Return a fallback version + ```toml + version_command = "curl -s https://example.com/version.txt || echo '0.0.0'" + ``` + +3. **Use -s flag with curl**: Suppress progress bars for clean output + ```toml + version_command = "curl -s https://example.com/latest-version" + ``` + +4. **Test your command manually**: Verify it outputs exactly 3 lines + ```sh + curl -s https://api.github.com/repos/owner/repo/releases/latest | jq -r '.tag_name' + echo "" + echo "" + ``` + +5. **Consider rate limiting**: Add delays or respect rate limits when querying APIs frequently + +## Simple vs Detailed Configuration + +### When to Use Simple Version Strings + +Simple strings are ideal for straightforward package installations: + +```toml +[packages] +# Latest version from default repository +bat = "*" + +# Specific version (auto-pinned for repo packages) +ripgrep = "14.1.0" + +# Inline table for minor customization +fd = { version = "9.0.0", repo = "soarpkgs" } +``` + +**Use simple strings when:** +- Installing from the default repository with standard settings +- You only need to specify version and optionally repo/profile +- No custom asset patterns, hooks, or build configuration needed +- Quick one-line configuration is sufficient + +### When to Use Detailed Tables + +Full table format is needed for advanced configurations: + +```toml +[packages.myapp] +github = "owner/repo" +asset_pattern = "myapp_*_linux_amd64.tar.gz" +hooks = { post_install = "myapp --init" } +pinned = true +``` + +**Use detailed tables when you need:** +- GitHub/GitLab releases with `asset_pattern`, `tag_pattern`, or `include_prerelease` +- Direct URL installation with `url` +- Version fetching via `version_command` for URL packages +- Build from source with `build` commands and dependencies +- Multiple binary mappings with `binaries` +- Lifecycle hooks (`post_install`, `pre_remove`, etc.) +- Sandbox restrictions for untrusted packages +- Portable mode for AppImage/FlatImage/RunImage/Wrappe +- Custom install patterns or `binary_only` +- Explicit pinning control (especially for URL packages) + +### Decision Guide + +| Requirement | Format | Example | +|-------------|--------|---------| +| Latest version from repo | Simple string | `pkg = "*"` | +| Specific version from repo | Simple string | `pkg = "1.2.3"` | +| From custom repository | Inline table | `pkg = { version = "*", repo = "custom" }` | +| GitHub/GitLab releases | Full table | See GitHub/GitLab sections above | +| Direct URL download | Full table | `pkg = { url = "https://..." }` | +| Build from source | Full table | See BuildConfig section | +| Multiple binaries | Full table | See BinaryMapping section | +| Post-install setup | Full table | `pkg = { version = "1.0", hooks = {...} }` | +| Security sandboxing | Full table | `pkg = { version = "1.0", sandbox = {...} }` | + +## Complete Examples + +::: code-group + +```toml [Minimal] +[packages] +bat = "*" +ripgrep = "*" +soar = "0.5.2" +7z = { repo = "soarpkgs" } +``` + +```toml [Advanced] +[defaults] +profile = "default" +binary_only = false +install_patterns = ["!*.log", "!SBUILD"] + +[packages] +bat = "*" + +[packages.obsidian] +version = "1.5.0" +pinned = true +portable = { home = "~/.obsidian-data" } + +[packages.gh-cli] +github = "cli/cli" +asset_pattern = "gh_*_linux_amd64.tar.gz" + +[packages.custom-tool] +url = "https://example.com/tool-1.0.0.tar.gz" + +[packages.custom-tool.build] +commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"] +dependencies = ["gcc", "make"] + +[packages.untrusted-tool] +url = "https://example.com/tool-1.0.0.tar.gz" +hooks = { post_install = "$INSTALL_DIR/setup.sh" } +sandbox = { require = true, network = false } +``` + +::: + +## Full Reference Example + +The configuration below uses every available option at least once. Because several options are alternatives to one another, the example spreads them across multiple packages rather than forcing them into a single entry. + +::: info Pick one source per package +Each package draws from a single source: a registry entry (`pkg_id` and `repo`), a direct `url`, a `github` repo, a `gitlab` repo, or a `version_command`. The source-specific fields follow from that choice, so treat this as a field reference rather than a template to copy verbatim. +::: + +```toml +[defaults] +profile = "default" # default profile for every package +binary_only = false # extract everything, not just the binary +install_patterns = ["!*.log", "!SBUILD"] # default include/exclude globs + +# Sandbox defaults are merged into every package. Per-package sandbox blocks +# override these fields, and fs_read/fs_write are concatenated. +[defaults.sandbox] +enabled = true # sandbox hooks and builds when Landlock is available +require = false # do not fail when Landlock is unavailable +network = false # block outbound network access +fs_read = ["/etc/ssl"] # extra readable paths +fs_write = ["/tmp/soar-build"] # extra writable paths + +# Registry package pinned to a specific variant, version, and repository. +[packages.bat] +pkg_id = "catlike.tools.bat.official" # disambiguate packages that share a name +version = "0.24.0" # specific version ("*" means latest) +repo = "soarpkgs" # install from this repository +pinned = true # never update automatically +profile = "default" # override the default profile +binary_only = true # only extract the binary +install_patterns = ["!*.1"] # override the default patterns + +# GitHub release, selecting the asset, tag, and a remapped architecture. +[packages.gh-cli] +github = "cli/cli" # owner/repo +asset_pattern = "gh_*_linux_amd64.tar.gz" # glob that selects the asset +tag_pattern = "v*" # glob that selects the release tag +include_prerelease = false # skip pre-releases +extract_root = "gh_2.40.0_linux_amd64" # treat this subdirectory as the archive root +arch_map = { x86_64 = "amd64", aarch64 = "arm64" } # remap arch names for the source + +# GitLab release with a checksum pin. +[packages.glab] +gitlab = "gitlab-org/cli" +asset_pattern = "*linux_amd64.tar.gz" +bsum = "9f2d...hex..." # BLAKE3 checksum; install aborts on mismatch + +# Direct URL install with custom type, entrypoint, nested archive, and binaries. +[packages.custom-tool] +url = "https://example.com/tool-1.0.0.tar.gz" # direct download (a "local" package) +bsum = "abc1...hex..." # verify the download +pkg_type = "archive" # override package-type detection +entrypoint = "tool" # executable name inside the package +nested_extract = "inner/payload.tar.gz" # extract an archive nested inside the archive +binaries = [ # map several executables to symlink names + { source = "bin/tool", link_as = "tool" }, + { source = "bin/toolctl", link_as = "tc" }, +] + +# AppImage kept self-contained with portable directories. Portable dirs apply +# only to AppImage, RunImage, FlatImage, and Wrappe packages (FlatImage honors +# only config, Wrappe only path); archives and plain binaries ignore them. +[packages.obsidian] +url = "https://example.com/Obsidian-1.5.0.AppImage" # an AppImage source +pkg_type = "appimage" + +[packages.obsidian.portable] +path = "~/.obsidian" # base path shortcut (sets home and config) +home = "~/.obsidian/home" # portable HOME (overrides path) +config = "~/.obsidian/config" # portable config dir (overrides path) +share = "~/.obsidian/share" # portable data dir +cache = "~/.obsidian/cache" # portable cache dir + +# Resolve version and download URL with a custom command, plus lifecycle hooks. +[packages.nightly-app] +version_command = "curl -s https://example.com/latest" # line 1: version, line 2: URL, line 3: size (optional) + +[packages.nightly-app.hooks] +post_download = "echo downloaded" # after download, before extraction +post_extract = "echo extracted" # after extraction +post_install = "$INSTALL_DIR/setup.sh" # after symlinks are created +pre_remove = "echo removing" # before the package is removed + +# Build from source with a per-package sandbox override. +[packages.from-source] +url = "https://example.com/src-1.0.0.tar.gz" + +[packages.from-source.build] +commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"] # env: $INSTALL_DIR $PKG_NAME $PKG_VERSION $NPROC +dependencies = ["gcc", "make"] # soar warns if these are missing from PATH + +[packages.from-source.sandbox] +enabled = true +require = true # fail if Landlock is unavailable +network = true # allow network access (needs kernel 6.7+) +fs_read = ["/opt/sdk"] +fs_write = ["/tmp/build"] +``` + +## Applying Packages + +### Basic Apply + +To install all packages defined in your `packages.toml`: + +```sh +soar apply +``` + +### Apply Options + +| Option | Flag | Description | +|--------|------|-------------| +| Prune | `--prune` | Remove packages not listed in packages.toml | +| Dry run | `--dry-run` | Show what would be done without making changes | +| Yes | `--yes` | Auto-confirm all prompts | +| Config | `--packages ` | Use custom packages.toml path | +| No verify | `--no-verify` | Skip checksum verification (security risk) | + +### Pruning Unlisted Packages + +To also remove packages that are not listed in your `packages.toml`: + +```sh +soar apply --prune +``` + +::: warning +The `--prune` flag will remove any installed packages not defined in your `packages.toml`. Make sure your configuration includes all packages you want to keep. +::: + +### Dry Run + +Preview what would be installed without making changes: + +```sh +soar apply --dry-run +``` + +### Custom Config File + +Use a packages.toml from a custom location: + +```sh +soar apply --packages /path/to/custom-packages.toml +``` + +## Defpackages Command + +Generate a template `packages.toml` with examples: + +```sh +soar defpackages +``` + +This creates `~/.config/soar/packages.toml` with commented examples showing all available options. + +## Environment Override + +You can override the default packages.toml path using the `SOAR_PACKAGES_CONFIG` environment variable: + +```sh +export SOAR_PACKAGES_CONFIG=/path/to/my-packages.toml +soar apply +``` + +## Best Practices + +- **Version Pinning**: Pin versions for production tools, use `*` for development +- **Profiles**: Set default profile in `[defaults]`, override per-package if needed +- **Portable Mode**: Use for AppImage/FlatImage/RunImage/Wrappe packages to keep data self-contained +- **Hooks**: Use `post_install` for setup, `pre_remove` for cleanup +- **Sandbox**: Enable for untrusted tools to restrict filesystem and network access +- **Dry Run**: Always run `soar apply --dry-run` to verify changes +- **Version Commands**: Use `version_command` for URL packages to enable automatic updates + +For troubleshooting, see [Health Check](./health.md) diff --git a/docs/download.md b/docs/download.md new file mode 100644 index 00000000..8641c7c0 --- /dev/null +++ b/docs/download.md @@ -0,0 +1,536 @@ +--- +title: Download Files +description: Download files with Soar from direct URLs, GitHub and GitLab releases, GHCR, or configured repositories, with filtering and automatic extraction. +--- + +# Download Files + +Soar downloads files from direct URLs, GitHub releases, GitLab releases, and GitHub Container Registry (GHCR). The download command supports filtering to narrow down options, interactive asset selection when several matches remain, and automatic archive extraction. + +## Basic Usage + +To download a file, use the `download` command or its `dl` alias: + +```sh +soar download +``` + +Download Soar nightly: + +```sh +soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux +``` + +Set the output filename or directory with the `--output` or `-o` flag: + +```sh +soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux -o soar-nightly +``` + +Download multiple files and save them to the `downloads` directory: + +```sh +soar download https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-x86_64-linux https://github.com/pkgforge/soar/releases/download/nightly/soar-nightly-aarch64-linux -o downloads/ +``` + +::: warning +Multiple custom output filenames are not supported. If you specify an output filename, it is used for all downloads, so only the last download is saved when you pass multiple URLs. +::: + +## Package Downloads + +Download packages directly from configured Soar repositories: + +::: code-group + +```sh [By name] +soar download neovim +``` + +```sh [Specific version] +soar download neovim@0.9.5 +``` + +```sh [From a specific repo] +soar download repo/neovim +``` + +::: + +## Download Command Options + +### Confirmation Options + +| Option | Short | Description | +|--------|-------|-------------| +| `--yes` | `-y` | Skip confirmation prompts (useful for scripts) | + +### Output Options + +| Option | Short | Description | +|--------|-------|-------------| +| `--output` | `-o` | Set output filename or directory | + +### Filtering and Selection Options + +| Option | Short | Description | +|--------|-------|-------------| +| `--regex` | `-r` | Filter assets using a regular expression pattern (works with all sources) | +| `--glob` | `-g` | Filter assets using a glob pattern (works with all sources) | +| `--match` | - | Filter assets by keyword substring matching (works with all sources) | +| `--exclude` | - | Exclude assets matching this pattern (works with all sources) | +| `--exact-case` | - | Enable case-sensitive matching (default is case-insensitive) | + +::: info Filter behavior +Filters narrow down the available assets. If multiple assets remain after filtering, Soar shows an interactive selection prompt for you to choose manually. Use `--yes` to skip the prompt and automatically download the first matching asset. +::: + +### Source Options + +| Option | Description | +|--------|-------------| +| `--github` | Download from GitHub releases using format `owner/repo[@tag]` | +| `--gitlab` | Download from GitLab releases using format `owner/project[@tag]` | +| `--ghcr` | Download from GitHub Container Registry using format `owner/image[:tag]` | + +### Extraction Options + +| Option | Description | +|--------|-------------| +| `--extract` | Automatically extract downloaded archives (`.tar`, `.tar.gz`, `.tgz`, `.tar.xz`, `.txz`, `.tar.bz2`, `.tbz2`, `.tar.zst`, `.zip`, `.7z`) | +| `--extract-dir` | Custom extraction directory (default: current directory or output path) | + +### File Handling Options + +| Option | Description | +|--------|-------------| +| `--skip-existing` | Skip download if the file already exists | +| `--force-overwrite` | Overwrite existing files without prompting | + +## Download Sources + +### Direct URLs + +Download any file from the internet using a direct URL: + +```sh +# Single file +soar download https://example.com/file.tar.gz + +# Save to a specific location +soar download https://example.com/file.tar.gz -o /path/to/download/ + +# With automatic extraction +soar download https://example.com/file.tar.gz --extract +``` + +::: info URL auto-detection +Soar automatically detects GitHub, GitLab, and GHCR URLs. You do not need the `--github`, `--gitlab`, or `--ghcr` flags when using full URLs. +::: + +### GitHub Releases + +Download assets from GitHub releases using the `--github` flag: + +```sh +# Basic format: owner/repo +soar download --github pkgforge/soar + +# Specific tag/release +soar download --github pkgforge/soar@v1.0.0 + +# Filter by architecture using regex +# Shows interactive selection if multiple assets match 'x86_64-linux' +soar download --github pkgforge/soar --regex 'x86_64-linux' + +# Filter by multiple patterns +# Shows interactive selection if both x86_64 and aarch64 matches exist +soar download --github pkgforge/soar --regex 'x86_64-linux|aarch64-linux' + +# Use --yes to skip interactive selection and download first match +soar download --github pkgforge/soar --regex 'x86_64-linux' --yes + +# Download and extract automatically +soar download --github pkgforge/soar@nightly --regex 'x86_64-linux' --extract + +# Exclude certain assets +soar download --github pkgforge/soar --exclude 'musl' --exclude 'debug' +``` + +::: info Latest release behavior +Without a tag or with `@latest`, Soar downloads the latest stable release and skips prereleases. Use `@tag-name` for specific versions including prereleases. +::: + +#### GitHub Asset Selection Examples + +```sh +# Download only musl builds +# Interactive: shows all musl builds if multiple match +soar download --github cli/cli --glob '*-musl*' + +# Download only .tar.gz files +# Interactive: shows all .tar.gz files if multiple match +soar download --github pkgforge/soar --glob '*.tar.gz' + +# Match specific keywords +# Interactive: shows all assets containing 'appimage' if multiple match +soar download --github neovim/neovim --match 'appimage' + +# Auto-download first match (skip interactive selection) +soar download --github cli/cli --glob '*-musl*' --yes + +# Case-sensitive matching +soar download --github pkgforge/soar --exact-case --regex 'Linux' +``` + +### GitLab Releases + +Download assets from GitLab releases using the `--gitlab` flag: + +```sh +# Basic format: owner/project +soar download --gitlab gitlab-org/gitlab + +# Specific tag/release +soar download --gitlab gitlab-org/gitlab@v16.0.0 + +# Filter by platform +soar download --gitlab gitlab-org/gitlab --regex 'linux-amd64' + +# Download and extract +soar download --gitlab gitlab-org/gitlab@v16.0.0 --regex 'linux-amd64' --extract +``` + +::: info Latest release behavior +Without a tag or with `@latest`, Soar downloads the latest stable release and skips prereleases. Use `@tag-name` for specific versions including prereleases. +::: + +#### GitLab Asset Selection Examples + +```sh +# Download only ARM64 builds +# Interactive: shows all ARM64 builds if multiple match +soar download --gitlab gitlab-org/gitlab --glob '*-arm64*' + +# Download specific file types +# Interactive: shows all .tar.xz files if multiple match +soar download --gitlab gitlab-org/gitlab --glob '*.tar.xz' + +# Auto-download first match (skip interactive selection) +soar download --gitlab gitlab-org/gitlab --glob '*-arm64*' --yes + +# Exclude debug builds +soar download --gitlab gitlab-org/gitlab --exclude 'debug' +``` + +### GitHub Container Registry (GHCR) + +Download container images from GitHub Container Registry: + +```sh +# Basic format: owner/image +soar download --ghcr pkgforge/soar + +# Specific tag +soar download --ghcr pkgforge/soar:latest + +# Specific version +soar download --ghcr pkgforge/soar:v1.0.0 + +# Multiple tags +soar download --ghcr pkgforge/soar:alpine --ghcr pkgforge/soar:slim +``` + +::: info Automatic retry +GHCR downloads automatically retry on rate limits (HTTP 429) or network errors, up to 5 attempts with 5-second delays. +::: + +## Asset Selection Patterns + +### How Asset Selection Works + +Soar's filtering works in two stages: + +1. **Filtering stage**: Filters (`--regex`, `--glob`, `--match`, `--exclude`) narrow down the list of available assets. +2. **Selection stage**: + - If exactly one asset matches, it is automatically downloaded. + - If multiple assets match and `--yes` is not set, an interactive selection prompt appears. + - If multiple assets match and `--yes` is set, the first matching asset is automatically downloaded. + +::: info Key point +Filters reduce the options but do not automatically select which file to download when multiple matches remain. You must choose interactively unless `--yes` is specified. +::: + +### Pattern Matching Options + +Soar provides three ways to filter assets: + +1. **Regex (`--regex` / `-r`)**: Full regular expression support +2. **Glob (`--glob` / `-g`)**: Shell-style glob patterns +3. **Match (`--match`)**: Simple substring matching + +### Regex Examples + +```sh +# Match specific architecture +# Auto-downloads if exactly one match, otherwise shows selection +soar download --github pkgforge/soar --regex 'x86_64-unknown-linux-gnu' + +# Match multiple architectures +# Interactive: shows both x86_64 and aarch64 if both exist +soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux' + +# Match version patterns +soar download --github pkgforge/soar --regex 'v[0-9]+\.[0-9]+\.[0-9]+' + +# Match file extensions +# Interactive: shows all .tar.gz and .zip files if multiple match +soar download --github pkgforge/soar --regex '\.(tar\.gz|zip)$' +``` + +### Glob Examples + +```sh +# Match all Linux builds +# Interactive: shows all Linux builds if multiple match +soar download --github pkgforge/soar --glob '*linux*' + +# Match specific file type +soar download --github pkgforge/soar --glob '*.tar.gz' + +# Match architecture pattern +soar download --github pkgforge/soar --glob '*-x86_64-*' + +# Match AppImages +# Auto-downloads if only one AppImage exists +soar download --github neovim/neovim --glob '*.AppImage' +``` + +### Keyword Match Examples + +```sh +# Find assets containing "linux" +# Interactive: shows all assets with "linux" if multiple match +soar download --github pkgforge/soar --match linux + +# Find assets containing "musl" +soar download --github pkgforge/soar --match musl + +# Multiple keywords (AND logic, all must match) +# Narrows down to assets containing both "linux" AND "x86_64" +soar download --github pkgforge/soar --match linux --match x86_64 +``` + +### Exclusion Patterns + +Use `--exclude` to filter out unwanted assets. Combined with other filters, this narrows down the selection pool. If multiple assets remain after exclusions, interactive selection is shown: + +```sh +# Exclude musl builds +# Shows selection of non-musl builds if multiple remain +soar download --github pkgforge/soar --exclude 'musl' + +# Exclude debug builds +soar download --github pkgforge/soar --exclude 'debug' + +# Multiple exclusions +soar download --github pkgforge/soar --exclude 'musl' --exclude 'debug' --exclude 'test' + +# Combine with inclusion patterns +# Shows Linux builds excluding musl (interactive if multiple match) +soar download --github pkgforge/soar --regex 'linux' --exclude 'musl' +``` + +### Case Sensitivity + +By default, pattern matching is case-insensitive. Use `--exact-case` for case-sensitive matching: + +```sh +# Case-insensitive (default) matches Linux, LINUX, linux +soar download --github pkgforge/soar --match linux + +# Case-sensitive only matches lowercase "linux" +soar download --github pkgforge/soar --match linux --exact-case + +# Case-sensitive regex +soar download --github pkgforge/soar --regex '[A-Z]{2}' --exact-case +``` + +## Archive Extraction + +Soar can automatically extract downloaded archives. + +### Supported Formats + +- `.tar` +- `.tar.gz` / `.tgz` +- `.tar.xz` / `.txz` +- `.tar.bz2` / `.tbz2` +- `.tar.zst` +- `.zip` +- `.7z` + +Soar detects the format from the file's magic bytes first and falls back to the file extension, so a correctly formatted archive is extracted even if its name uses a different extension. + +### Extraction Examples + +```sh +# Extract to current directory +soar download https://example.com/file.tar.gz --extract + +# Extract to specific directory +soar download https://example.com/file.tar.gz --extract --extract-dir /opt/app + +# Download GitHub release and extract +soar download --github pkgforge/soar@v1.0.0 --regex 'x86_64-linux' --extract + +# Extract with custom output +soar download https://example.com/file.tar.gz -o myfile.tar.gz --extract --extract-dir ./mydir +``` + +## File Handling + +### Skip Existing Files + +When a target file already exists, soar prompts you to choose by default. Pass `--skip-existing` to skip it instead, which is useful when re-running download scripts. An existing file is only skipped when its checksum still matches; a partial download is resumed rather than skipped. + +```sh +# Skip files that already exist +soar download https://example.com/file.tar.gz --skip-existing + +# Useful for batch downloads +soar download --github pkgforge/soar --regex 'linux' --skip-existing +``` + +### Force Overwrite + +Overwrite existing files without prompting: + +```sh +# Force overwrite +soar download https://example.com/file.tar.gz --force-overwrite + +# Combine with extraction +soar download https://example.com/file.tar.gz --extract --force-overwrite +``` + +### Non-Interactive Mode + +Skip all confirmation prompts with `--yes`. When multiple assets match your filters, `--yes` automatically downloads the first matching asset instead of showing an interactive selection: + +```sh +# Download without confirmation +soar download https://example.com/file.tar.gz --yes + +# Batch download with all options +# Skips interactive selection and downloads first match +soar download --github pkgforge/soar --regex 'linux' --extract --yes --skip-existing + +# When multiple assets match, --yes picks the first one automatically +soar download --github cli/cli --regex 'linux' --yes +``` + +### Interactive Selection + +When multiple assets match your filters and `--yes` is not set, Soar displays an interactive selection prompt: + +```sh +soar download --github cli/cli --regex 'linux' +# > Select an asset (1-4): +# 1. cli-linux-amd64.rpm (95.2 MB) +# 2. cli-linux-arm64.deb (89.1 MB) +# 3. cli-linux-386.tar.gz (91.5 MB) +# 4. cli-linux-amd64.tar.gz (95.2 MB) +``` + +The selection works as follows: + +- **Exactly 1 match**: Automatically downloads without prompting +- **Multiple matches without `--yes`**: Shows the interactive prompt above +- **Multiple matches with `--yes`**: Automatically downloads the first matching asset + +::: tip Automatic versus interactive +Use filters to narrow down options. If only one asset remains after filtering, it downloads automatically. If multiple remain, you are prompted to choose unless you use `--yes` to accept the first match. +::: + +## Advanced Examples + +### Multi-Architecture Download + +```sh +# Download multiple architectures +# Shows interactive selection if both x86_64 and aarch64 builds exist +soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux' -o ./binaries/ + +# Auto-download first architecture match +soar download --github pkgforge/soar --regex '(x86_64|aarch64)-linux' -o ./binaries/ --yes +``` + +### Latest Release from Multiple Sources + +::: code-group + +```sh [GitHub] +soar download --github pkgforge/soar@latest --regex 'linux' --extract +``` + +```sh [GitLab] +soar download --gitlab gitlab-org/gitlab@latest --regex 'amd64' --extract +``` + +::: + +### Filter and Extract Workflow + +```sh +# Download, filter, and extract in one command +soar download --github neovim/neovim \ + --glob 'nvim-linux64.tar.gz' \ + --extract \ + --extract-dir ./nvim \ + --output nvim.tar.gz +``` + +### Batch Downloads with Exclusions + +```sh +# Download all Linux builds except musl +# Shows interactive selection if multiple non-musl Linux builds remain +soar download --github pkgforge/soar \ + --regex 'linux' \ + --exclude 'musl' \ + --exclude 'debug' \ + -o ./builds/ + +# Auto-download first match +soar download --github pkgforge/soar \ + --regex 'linux' \ + --exclude 'musl' \ + --exclude 'debug' \ + -o ./builds/ \ + --yes +``` + +### Container Image Management + +```sh +# Pull multiple image variants +soar download --ghcr pkgforge/soar:alpine +soar download --ghcr pkgforge/soar:slim +soar download --ghcr pkgforge/soar:latest +``` + +## Tips and Best Practices + +1. **Use `--glob` for simple patterns**: Easier to read than regex for common cases +2. **Combine filters**: Use both inclusion (`--regex` / `--glob`) and exclusion (`--exclude`) for precise control +3. **Understand selection behavior**: Filters narrow down options, but if multiple assets remain you are prompted to choose, or use `--yes` for automatic first-match download +4. **Test patterns first**: Use `--yes` only after verifying your filters work correctly +5. **Extraction paths**: Use `--extract-dir` to keep downloads organized +6. **Batch operations**: `--skip-existing` is essential for re-running download scripts +7. **Case sensitivity**: Most patterns are case-insensitive by default, so use `--exact-case` when needed +8. **Asset names**: GitHub and GitLab asset names typically include architecture, OS, and file type +9. **Latest releases**: Use `@latest` or omit the tag to get the newest stable release, since prereleases are skipped +10. **Filter universality**: `--regex`, `--glob`, `--match`, and `--exclude` work with all sources (GitHub, GitLab, GHCR) +11. **URL auto-detection**: Full URLs are automatically detected, so the `--github`, `--gitlab`, and `--ghcr` flags are not needed +12. **Package downloads**: Download packages directly by name from configured repositories diff --git a/docs/health.md b/docs/health.md new file mode 100644 index 00000000..d4dfc06a --- /dev/null +++ b/docs/health.md @@ -0,0 +1,239 @@ +--- +title: Health +description: Diagnose your Soar installation, fix broken packages and symlinks, and run cache and sync maintenance. +--- + +# Health + +Soar's health check quickly identifies potential problems with your +installation, including missing binaries, broken packages, and broken symlinks. + +## Checking Health + +To check Soar's health, run: + +```sh +soar health +``` + +### What It Checks + +When executed, the command: + +- Checks whether Soar's binary path is included in the `PATH` environment variable. +- Lists **broken packages**, which are incomplete package installations. +- Lists **broken symlinks**, which are dangling symlinks created by Soar that no longer point to valid files. + - **bin directory**: detects all broken symlinks. + - **desktop and icons directories**: detects only broken symlinks whose filenames end with the `-soar` suffix. + +### Reading the Output + +The health check displays results in a table with a status indicator for each +category. + +**Status icons:** + +- checkmark (green): the item is healthy. +- cross (red): issues were found. +- arrow: marks individual items in a list. + +**Table categories:** + +- **PATH**: checks whether Soar's binary directory is in your `PATH`. +- **Broken Packages**: lists incomplete package installations. +- **Broken Symlinks**: lists dangling symlinks created by Soar. + +When issues are detected, suggested commands to fix them are printed below the +table. + +### Example Output + +When everything is healthy: + +``` +╭────────────────────────────────────────╮ +│ System Health Check │ +├──────────────────┬─────────────────────┤ +│ PATH │ ✓ Configured │ +│ Broken Packages │ ✓ None │ +│ Broken Symlinks │ ✓ None │ +╰──────────────────┴─────────────────────╯ +``` + +When issues are found: + +``` +╭────────────────────────────────────────╮ +│ System Health Check │ +├──────────────────┬─────────────────────┤ +│ PATH │ ⚠ /path/to/bin not │ +│ │ in PATH │ +│ Broken Packages │ ✗ 2 found │ +│ Broken Symlinks │ ✗ 1 found │ +╰──────────────────┴─────────────────────╯ + +Broken packages: + → cat#test: /home/user/.local/share/soar/packages/cat-test-q1235 + → ls#test: /home/user/.local/share/soar/packages/ls-test-q2345 +Run soar clean --broken to remove + +Broken symlinks: + → /home/user/.local/bin/ls +Run soar clean --broken-symlinks to remove +``` + +### Fixing Issues + +| Issue | Command | +|-------|---------| +| Broken packages | `soar clean --broken` | +| Broken symlinks | `soar clean --broken-symlinks` | +| Stale cache | `soar clean --cache` | + +See [Clean Command](#clean-command) for details on each operation. + +## Environment Variables + +To view all Soar-related environment variables and their current values, run: + +```sh +soar env +``` + +This command displays: + +- `SOAR_CONFIG`: config file path. +- `SOAR_BIN`: binary directory path. +- `SOAR_DB`: database directory path. +- `SOAR_CACHE`: cache directory path. +- `SOAR_PACKAGES`: packages directory path. +- `SOAR_REPOSITORIES`: repository directory path. + +These environment variables can be set to override Soar's default paths and +behavior. For example: + +```sh +# Use a custom cache directory +export SOAR_CACHE="/tmp/soar-cache" +soar install neovim + +# Switch to nightly builds +SOAR_NIGHTLY=1 soar self update +``` + +## Clean Command + +The `clean` command performs maintenance operations that keep your Soar +installation tidy and efficient. + +### Usage + +```sh +soar clean [OPTIONS] +``` + +### Options + +| Option | Description | +|--------|-------------| +| `--cache` | Deletes the entire cache directory (all cached package files). | +| `--broken` | Removes packages marked as broken in the database (incomplete installations). | +| `--broken-symlinks` | Removes broken symlinks from the bin, desktop, and icons directories. | + +::: warning Cleaning is destructive +`--cache` deletes the entire cache directory, and the broken-package and +broken-symlink operations permanently remove the affected entries. With no +flags, `soar clean` runs every operation at once. +::: + +### Examples + +```sh +# Run all clean operations (no flags = clean everything) +soar clean + +# Clean only the cache +soar clean --cache + +# Remove only broken packages +soar clean --broken + +# Remove only broken symlinks +soar clean --broken-symlinks + +# Run specific clean operations together +soar clean --cache --broken +``` + +### When to Clean + +- **After installation failures**: when `soar health` reports broken packages. +- **To free disk space**: clear the cache, which deletes the entire cache directory. +- **After manual file removal**: clean up broken symlinks pointing to deleted files. +- **Before major updates**: clear the cache to ensure fresh downloads. +- **General maintenance**: run `soar clean` with no flags to perform all operations. + +## Sync Command + +The `sync` command updates repository metadata from remote sources so you always +have the latest package information. + +### Usage + +```sh +soar sync +``` + +The command has two aliases: + +```sh +soar S # Short alias +soar fetch # Alternative name +``` + +### What It Does + +When executed, the command: + +- Fetches the latest package metadata from all enabled repositories. +- Updates the local database with new package versions. +- Respects each repository's `sync_interval` setting. + +### Sync Intervals + +Repositories can be configured with different sync intervals: + +```toml +# In config.toml +[[repositories]] +name = "main" +url = "https://example.com/repo" +sync_interval = "3h" # Sync every 3 hours (default) +``` + +**Special `sync_interval` values:** + +- `"always"`: sync every time `soar sync` is run. +- `"never"`: never sync automatically. +- `"auto"`: use the default 3-hour interval. +- `"3h"`, `"12h"`, `"1d"`: custom duration strings. + +### When to Sync + +- **Before searching for new packages**: ensures you see the latest versions. +- **After adding a new repository**: fetches the initial metadata. +- **Before updating packages**: gets the latest version information. +- **Anytime**: run to refresh repository metadata. + +### Example + +```sh +# Sync all repositories +soar sync +``` + +``` +Syncing repository 'main'... +Fetching metadata from https://example.com/repo... +Updated: 1427 packages available +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..d23ef467 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,33 @@ +--- +layout: home +title: Fast, modern package manager for Linux + +hero: + name: Soar + text: Package manager for Linux + tagline: Fast, modern, and bloat-free. Install static binaries, AppImages, and portable packages across any distro. No root required. + actions: + - theme: brand + text: Quick Start + link: /quick-start + - theme: alt + text: Installation + link: /installation + - theme: alt + text: View on GitHub + link: https://github.com/pkgforge/soar + +features: + - title: Universal Packages + details: Static binaries, AppImages, and FlatImages. One tool handles them all, sourced from the soarpkgs repository. + - title: Fast & Efficient + details: Written in Rust. A pre-built binary cache means no local compilation, with parallel downloads and installs. + - title: Distro-Independent + details: Works the same on Debian, Arch, Fedora, Alpine, or anything else running Linux. No system dependencies. + - title: Secure by Design + details: Packages built on remote CI with auditable logs, verified using BLAKE3 checksums and minisign signatures. + - title: Desktop Integration + details: Follows freedesktop.org specs for automatic desktop entries, icon scaling, and menu integration. + - title: No Root Needed + details: Everything installs to your home directory by default. No sudo, no system changes, fully portable. +--- diff --git a/docs/inspection.md b/docs/inspection.md new file mode 100644 index 00000000..326754d7 --- /dev/null +++ b/docs/inspection.md @@ -0,0 +1,413 @@ +--- +title: Inspect Packages +description: Investigate packages with the query, inspect, and log commands before and after installation. +--- + +# Inspect Packages + +Soar provides inspection commands that help you understand packages before installation and debug issues afterward. This guide covers the `query`, `inspect`, and `log` commands. + +## Overview of Inspection Commands + +Soar offers three complementary inspection commands. + +| Command | Purpose | Use When | +|---------|---------|----------| +| **`soar query`** | View detailed package metadata | You want comprehensive package information | +| **`soar inspect`** | View build scripts | You need to understand how a package is built | +| **`soar log`** | View build logs | You are debugging installation failures | + +--- + +## Query Command + +The `query` command provides detailed metadata about packages, including versions, sizes, dependencies, and repository information. + +### Basic Usage + +```sh +# Query a package by name +soar query + +# Using the short alias +soar Q +``` + +### How Query Works + +The `query` command searches for packages and displays detailed information in a formatted table. It checks: + +- Package name +- Package ID (pkg_id) +- Version numbers +- Repository sources + +### Examples + +```sh +$ soar query bat + +✓ Name bat#cat:soarpkgs +✓ Description A cat(1) clone with wings +✓ Version 0.24.0 +✓ Size 1.8 MB +✓ Checksum abc123... (blake3) +✓ Type binary +``` + +### Query Output Format + +The query command displays the following information. + +| Field | Description | +|-------|-------------| +| **Name** | Package name in format `name#pkg_id:repo` | +| **Description** | Human-readable package description | +| **Version** | Current package version | +| **Size** | Download size (formatted for readability) | +| **Checksum** | BLAKE3 checksum for download verification | +| **Homepages** | Official project websites | +| **Licenses** | Package license information | +| **Maintainers** | Package maintainer contact information | +| **Notes** | Additional installation or usage notes | +| **Type** | Package type (appimage, flatimage, archive, etc.) | +| **Build CI** | Build action and build ID | +| **Build Date** | When the package was built | +| **Build Log** | Link to build log output | +| **Build Script** | Link to build script used | +| **GHCR Blob** | GitHub Container Registry blob URL (if available) | +| **Download URL** | Direct download URL (shown if GHCR Blob not available) | +| **GHCR Package** | Full GHCR package URL | +| **Index** | Package index page URL | + +::: info Optional fields +Some fields are optional and may not appear if they are not available for the package. The download information shows either GHCR Blob or Download URL depending on the package source. +::: + +### Use Cases + +- **Before installation:** verify package details before installing. +- **Version comparison:** check what versions are available. +- **Repository verification:** confirm which repository provides a package. +- **Size planning:** check package size for disk space planning. + +--- + +## Inspect Command + +The `inspect` command displays the build script (SBUILD) used to compile or prepare a package. This helps you understand: + +- Build dependencies +- Compilation commands +- Installation steps +- Custom build logic + +### Basic Usage + +```sh +# View build script for a package +soar inspect +``` + +### How Inspect Works + +The `inspect` command: + +1. Searches for matching packages by name, pkg_id, or version. +2. Prompts for interactive selection if multiple matches are found. +3. Checks if the package is installed locally and reads from `$INSTALL_DIR/SBUILD`. +4. Fetches from the repository URL if the package is not installed locally. +5. Displays the complete build script. + +### Examples + +```sh +$ soar inspect ffmpeg + +Reading build script from /home/user/.local/share/soar/packages/ffmpeg-7.1 [15.2 MB] + +# SBUILD file for ffmpeg +pkg_name="ffmpeg" +pkg_version="7.1" +pkg_source="https://ffmpeg.org/releases/ffmpeg-7.1.tar.xz" + +build() { + ./configure --prefix="$INSTALL_DIR" --enable-gpl + make -j$(nproc) + make install +} + +dependencies=["nasm", "pkg-config", "libx264-dev"] +``` + +### Inspect Output Format + +Build scripts follow the SBUILD format with these common sections. + +| Section | Description | +|---------|-------------| +| **pkg_name** | Package name | +| **pkg_version** | Version string | +| **pkg_source** | Download URL or source location | +| **build()** | Build commands (compilation, installation) | +| **dependencies** | Build dependencies required | + +### Interpreting Build Scripts + +#### Understanding build commands + +```sh +build() { + # Configure step - sets up build configuration + ./configure --prefix="$INSTALL_DIR" --enable-feature + + # Compile step - builds the software + make -j$(nproc) + + # Install step - copies files to install directory + make install +} +``` + +#### Available environment variables + +Build scripts have access to these variables. + +| Variable | Description | +|----------|-------------| +| `$INSTALL_DIR` | Target installation directory | +| `$PKG_NAME` | Package name | +| `$PKG_VERSION` | Package version | +| `$NPROC` | Number of CPU cores (for parallel builds) | + +### Use Cases + +- **Security audit:** review what commands run during installation. +- **Build debugging:** understand why a package fails to build. +- **Customization:** see whether you can modify build options. +- **Dependency planning:** check build dependencies before installing. +- **Learning:** understand how packages are assembled. + +--- + +## Log Command + +The `log` command displays the build log from the last installation attempt. This is invaluable for debugging failed installations. + +### Basic Usage + +```sh +# View build log for a package +soar log +``` + +### How Log Works + +The `log` command: + +1. Searches for matching packages. +2. Prompts for selection if multiple matches are found. +3. Checks if the package is installed locally and reads from `$INSTALL_DIR/.log`. +4. Fetches from the repository URL if the package is not installed locally. +5. Displays the complete build log. + +### Examples + +```sh +$ soar log bat + +[2024-01-15 10:23:45] Starting installation of bat-0.24.0 +[2024-01-15 10:23:47] Download complete: 1.8 MB +[2024-01-15 10:23:48] Installation completed successfully +``` + +```sh +$ soar log python@3.12 + +[2024-01-15 11:30:12] Starting installation of python@3.12 +[2024-01-15 11:31:20] ERROR: Build failed +[2024-01-15 11:31:20] ERROR: openssl/ssl.h: No such file or directory +``` + +#### View failed installation log + +```sh +$ soar log python@3.12 + +Reading build log from /home/user/.local/share/soar/packages/python@3.12 [25.4 MB] + +[2024-01-15 11:30:12] Starting installation of python@3.12 +[2024-01-15 11:30:12] Downloading from https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz +[2024-01-15 11:30:45] Download complete: 25.4 MB +[2024-01-15 11:30:45] Extracting to /tmp/python@3.12 +[2024-01-15 11:30:47] Running build commands from SBUILD +[2024-01-15 11:30:48] Executing: ./configure --prefix="$INSTALL_DIR" +... +[2024-01-15 11:31:20] ERROR: Build failed +[2024-01-15 11:31:20] ERROR: openssl/ssl.h: No such file or directory +[2024-01-15 11:31:20] ERROR: Build dependency 'openssl-dev' not found +[2024-01-15 11:31:20] Installation failed +``` + +#### View log for a specific version + +```sh +# Check log for a specific version +soar log "ripgrep@13.0" +``` + +### Log Output Format + +Build logs contain timestamped entries for each installation step. + +| Entry Type | Example | +|------------------|---------| +| Start/End markers | `[2024-01-15 10:23:45] Starting installation...` | +| Progress updates | `[2024-01-15 10:23:47] Download complete: 1.8 MB` | +| Success messages | `[2024-01-15 10:23:48] Installation completed successfully` | +| Error messages | `[2024-01-15 11:31:20] ERROR: Build failed` | + +### Interpreting Build Logs + +#### Common success patterns + +```sh +[timestamp] Starting installation of - +[timestamp] Downloading from +[timestamp] Download complete: +[timestamp] Verifying checksum... OK +[timestamp] Extracting to +[timestamp] Running build commands from SBUILD +[timestamp] Installation completed successfully +``` + +#### Common failure patterns + +```sh +# Missing build dependency +[timestamp] ERROR: : No such file or directory +[timestamp] ERROR: Build dependency '' not found + +# Download failure +[timestamp] ERROR: Failed to download from +[timestamp] ERROR: HTTP 404 Not Found + +# Checksum mismatch +[timestamp] ERROR: Checksum verification failed +[timestamp] ERROR: Expected , got + +# Build command failure +[timestamp] ERROR: Build failed with exit code 1 +[timestamp] ERROR: make: *** No rule to make target 'install' +``` + +### Use Cases + +- **Debug failures:** understand why an installation failed. +- **Verify installation:** confirm all steps completed successfully. +- **Performance analysis:** check how long installation took. +- **Audit trail:** review what happened during installation. +- **Bug reports:** include logs when reporting issues. + +--- + +## Package Query Syntax + +All three inspection commands support a flexible package query syntax. + +### Query Formats + +```sh +# By name only +soar query bat + +# By package ID (includes version variants) +soar query python@3.12 + +# By specific version +soar query "ripgrep@14.0" + +# By repository (using colon syntax) +soar query bat:soarpkgs +``` + +### Query Components + +| Component | Format | Example | Description | +|-----------|--------|---------|-------------| +| **Name** | `package` | `bat` | Package name | +| **Package ID** | `package@version` | `python@3.12` | Specific variant | +| **Version** | `package@version` | `ripgrep@14.0` | Exact version | +| **Repository** | `package:repo` | `bat:soarpkgs` | Source repository | + +### Interactive Selection + +When multiple packages match your query, Soar prompts for selection. + +```sh +$ soar query python + +Multiple packages found. Select one: + 1) python@3.12 (soarpkgs) - Python 3.12.1 + 2) python@3.11 (soarpkgs) - Python 3.11.8 + 3) python@3.10 (soarpkgs) - Python 3.10.13 + +Enter selection [1-3]: 1 +``` + +--- + +## Common Workflows + +### Pre-installation investigation + +```sh +soar query bat +soar inspect bat +soar info | grep bat +``` + +### Debugging failed installations + +```sh +soar log python@3.12 +soar inspect python@3.12 +soar install python@3.12 -vv +``` + +### Comparing package versions + +```sh +soar query "ripgrep@13.0" +soar query "ripgrep@14.0" +soar inspect "ripgrep@13.0" +``` + +## Tips + +- Use `soar query` before installing to verify package details. +- Check build scripts before installing to understand dependencies. +- Always check the build log first when troubleshooting. +- Search for errors with `grep ERROR` on log files. + +## Troubleshooting + +### No build script or log found + +Binary packages do not have build scripts. Build logs only exist after an installation attempt. + +### Query returns multiple matches + +Use a more specific query such as `soar query python@3.12`, or specify a repository with `soar query python:soarpkgs`. + +### Large files prompt for confirmation + +Files over 1 MB require confirmation. Use `less` for pagination or save to a file. + +For more help, see [Health Check](./health.md). + +## See Also + +- [Search Packages](./search.md) +- [Install Packages](./install.md) +- [Remove Packages](./remove.md) diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 00000000..0749d8bc --- /dev/null +++ b/docs/install.md @@ -0,0 +1,416 @@ +--- +title: Installing Packages +description: Install packages with soar from repositories, specific pkg_ids, repositories, or direct URLs, with options for portable, binary-only, and non-interactive installs. +--- + +# Installing Packages + +Soar offers several flexible ways to install packages. This guide covers every installation method, the supported input types, and the flags that control how packages are fetched and set up. + +## Installation Flow + +`soar install` accepts several forms of input and resolves each one differently: + +| Input | Example | How soar resolves it | +|-------|---------|----------------------| +| Package name | `soar install bat` | Searches all synced repositories. If several packages match, soar prompts you to choose, or selects the first match when `--yes` is set. | +| `name#pkg_id` | `soar install cat#git.busybox.net.busybox.standalone.glibc` | Searches a specific package family. | +| `name:repo` | `soar install 7z:soarpkgs` | Searches a specific repository. | +| `name@version` | `soar install soar@0.5.2` | Pins the package at a specific version. | +| URL | `soar install https://example.com/app.AppImage` | Downloads and installs directly from the URL. | + +Once the input resolves to a package, soar downloads and installs it. The sections below cover each input type in detail. + +## Basic Installation + +To install a package, use the `install` command or one of its aliases. + +::: code-group + +```sh [install] +soar install +``` + +```sh [i] +soar i +``` + +```sh [add] +soar add +``` + +::: + +Example: install the `soar` package. + +```sh +soar add soar +``` + +## Input Types + +A single argument to `soar add` can take several forms, each resolving the package differently. + +### Package name + +The plain name is searched across all synced repositories. + +```sh +soar add bat +``` + +### Specific pkg_id + +Packages can be organized into a pkg_id (like a family). Append `#` to install from a specific one. + +```sh +soar add # +``` + +Example: install the `cat` package from the `git.busybox.net.busybox.standalone.glibc` pkg_id. + +```sh +soar add cat#git.busybox.net.busybox.standalone.glibc +``` + +### Specific repository + +Append `:` to install from a specific repository. + +```sh +soar add : +``` + +Example: install the `7z` package from the `soarpkgs` repository. + +```sh +soar add 7z:soarpkgs +``` + +### Pinned version + +Append `@` to pin the package at a specific version. + +```sh +soar add @ +``` + +Example: install the `soar` package and pin it at version `0.5.2`. + +```sh +soar add soar@0.5.2 +``` + +::: warning No unpin yet +Currently there is no way to unpin the package. This will be introduced gradually. +::: + +### URL + +You can install packages directly from a URL. + +```sh +soar add +``` + +Example: install an AppImage from a URL. + +```sh +soar add https://example.com/releases/myapp-1.0.0.appimage +``` + +When installing from a URL, Soar attempts to automatically detect package metadata. You can override this behavior with the following flags. + +| Flag | Description | +|------|-------------| +| `--name` | Override the package name | +| `--version` | Override the version | +| `--pkg-type` | Override the package type (e.g., appimage, flatimage, archive) | +| `--pkg-id` | Override the package ID | +| `--binary-only` | Install only binaries, skip other files | +| `--no-verify` | Skip checksum and signature verification | +| `--portable [DIR]` | Set portable dir for home & config (optional value) | +| `--portable-home [DIR]` | Set custom home directory (optional value) | +| `--portable-config [DIR]` | Set custom config directory (optional value) | +| `--portable-share [DIR]` | Set custom share directory (optional value) | +| `--portable-cache [DIR]` | Set custom cache directory (optional value) | +| `--show` | Show all available variants for interactive selection | + +Basic example: + +```sh +soar add https://example.com/app.appimage --name myapp --version 2.0.0 +``` + +Portable installation: + +```sh +soar add https://example.com/app.AppImage \ + --name myapp \ + --portable-home ~/myapp +``` + +## Installing Multiple Packages + +List several packages after the command to install them together. + +```sh +soar add +``` + +Example: install the `bat` and `7z` packages. + +```sh +soar add bat 7z +``` + +## Installing Whole pkg_ids + +To install every package provided by a pkg_id, prefix the pkg_id with `#`. + +```sh +soar add '#git.busybox.net.busybox.standalone.glibc' +``` + +If you do not know the full pkg_id but know that `cat` is in it, use `#all`. This searches for every pkg_id that contains `cat` and prompts you to choose one. + +```sh +soar add 'cat#all' +``` + +## Portable Installation + +Portable mode creates symlinks for application data directories (home, config, share, cache) to custom locations. This keeps application data self-contained or allows running from removable media. + +::: warning Supported package types +Portable mode **only works** for AppImage, FlatImage, RunImage, and Wrappe packages. Static binaries and archive packages do **not support** portable mode. +::: + +To install a package in portable mode: + +```sh +soar add --portable +``` + +You can specify custom directories for different data types. + +| Flag | Description | +|------|-------------| +| `--portable [DIR]` | Set base portable directory (applies to home and config). Optional value: if no directory specified, uses package installation directory | +| `--portable-home [DIR]` | Custom home directory (creates symlink). Optional value | +| `--portable-config [DIR]` | Custom config directory (creates symlink). Optional value | +| `--portable-share [DIR]` | Custom share directory (creates symlink). Optional value | +| `--portable-cache [DIR]` | Custom cache directory (creates symlink). Optional value | + +Example: install with a custom home directory. + +```sh +soar add obsidian.AppImage --portable-home ~/.obsidian-data +``` + +Example: install with multiple custom directories. + +```sh +soar add myapp.AppImage --portable-home ~/myapp --portable-config ~/myapp/config --portable-share ~/myapp/share --portable-cache ~/myapp/cache +``` + +::: info +Portable options create symlinks from the package's expected directories to your custom locations. These settings are stored in the database and reused on reinstallation. +::: + +## Installation Flags + +### Force installation + +To force installation even if the package already exists, use the `--force` flag. + +```sh +soar add --force +``` + +Example: install the `bat` package even if it already exists. + +```sh +soar add bat --force +``` + +### Binary-only installation + +By default, Soar extracts all files from a package. The `--binary-only` flag skips extracting non-essential files to save disk space. + +```sh +soar add --binary-only +``` + +This flag excludes: + +- `*.png` and `*.svg` (icon files) +- `*.desktop` (desktop entry files) +- `LICENSE` (license files) +- `CHECKSUM` (checksum files) + +Example: install `ripgrep` without icons, desktop files, and license. + +```sh +soar add ripgrep --binary-only +``` + +::: info +This option is useful for minimal installations. However, excluding desktop files (`*.desktop`) means the package will not appear in your system's application menu. +::: + +### Suppress package notes + +Some packages display important information after installation. To suppress these notes, use the `--no-notes` flag. + +```sh +soar add --no-notes +``` + +Example: install `neovim` without displaying post-installation notes. + +```sh +soar add neovim --no-notes +``` + +::: warning +Package notes often contain critical setup instructions or configuration tips. Use this flag with caution. +::: + +### Interactive installation + +By default, Soar installs a package automatically once your query resolves to a single match. Use the `--ask` flag to force a confirmation prompt before installation. + +```sh +soar add --ask +``` + +`--ask` is the opposite of `--yes`: it always prompts for confirmation before proceeding. To interactively choose between multiple variants of a package, use [`--show`](#show-package-information) instead. + +### Non-interactive installation + +By default, Soar prompts for confirmation before installing packages if multiple packages are found for the given query. To skip this prompt, use the `--yes` flag. + +```sh +soar add --yes +``` + +Example: install the `cat` package without confirmation. + +```sh +soar add cat --yes +``` + +::: info +The `--yes` flag is useful for non-interactive installations, but it is generally recommended to use it with caution. It will install the first package if multiple packages are found. +::: + +### Skip signature verification + +By default, Soar verifies package signatures for security. To skip signature verification, use the `--no-verify` flag. + +```sh +soar add --no-verify +``` + +::: danger Security risk +Skipping signature verification exposes you to potentially compromised packages. Only use `--no-verify` with packages from trusted sources or during testing and development. +::: + +Example: install a package from a trusted development build. + +```sh +soar add https://internal.example.com/builds/myapp.appimage --no-verify +``` + +### Package ID override + +To explicitly specify the package ID, useful when multiple packages share the same name, use the `--pkg-id` flag. + +```sh +soar add --pkg-id +``` + +Example: install `cat` from a specific package ID. + +```sh +soar add cat --pkg-id git.busybox.net.busybox.standalone.glibc +``` + +This is equivalent to using the `cat#git.busybox.net.busybox.standalone.glibc` syntax but can be more readable in scripts. + +### Show package information + +To interactively browse and select package variants before installing, use the `--show` flag. + +```sh +soar add --show +``` + +This opens an interactive picker that displays: + +- All available versions and variants of the package +- `[installed]` marker next to already-installed versions +- Package details (name, version, repository, pkg_id) + +Example: browse all `bat` variants interactively. + +```sh +soar add bat --show +``` + +::: info +Unlike a non-interactive display, `--show` always presents an interactive selection menu. You can choose which variant to install or cancel without installing anything. +::: + +## Advanced Scenarios + +### Combining flags + +You can combine multiple installation options for complex scenarios. + +```sh +soar add bat --yes --no-notes +soar add ripgrep --yes --binary-only +``` + +### Self-contained portable setup + +For AppImage, FlatImage, RunImage, and Wrappe applications that need to be completely self-contained, for example on a USB drive: + +```sh +soar add obsidian.AppImage \ + --portable-home /media/usb/obsidian/home \ + --portable-config /media/usb/obsidian/config +``` + +## Troubleshooting + +### Package not found + +Check the package name spelling, sync repositories, or try installing from URL directly. + +```sh +soar search +soar sync +``` + +### Multiple packages found + +Use `--ask` to choose interactively, specify a repository with `:`, or use `--yes` for the first match. + +### Permission denied + +Verify profile permissions or use `sudo` with `--system` mode. + +### Portable mode not working + +Portable mode only works for AppImage, FlatImage, RunImage, and Wrappe packages. Static binaries and archives are not supported. + +For more troubleshooting, see [Health Check](./health.md). + +## Related Topics + +- [Removing Packages](./remove.md) +- [Updating Packages](./update.md) +- [Searching Packages](./search.md) diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 00000000..34810574 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,189 @@ +--- +title: Installation +description: Install Soar on any Linux distribution via the install script, pre-built binaries, Cargo, or source. +--- + +# Installation + +Install Soar on your Linux system using one of the methods below. + +::: info Prerequisites +Linux (any distribution), curl or wget, and basic shell access. +::: + +## System Requirements + +- **Architectures:** x86_64, aarch64, riscv64 +- **OS:** Any Linux distribution (kernel 4.0+ recommended) +- **Building from source:** Rust 1.88.0+ + +## Quick Installation + +### Install Script (Recommended) + +::: code-group + +```sh [curl] +curl -fsSL https://soar.qaidvoid.dev/install.sh | sh +``` + +```sh [wget] +wget -qO- https://soar.qaidvoid.dev/install.sh | sh +``` + +::: + +The script automatically detects your architecture, downloads the appropriate binary, and installs it to: + +- `/usr/local/bin` (if running as root) +- `$HOME/.local/bin` (user installation, default) + +#### Install Script Options + +| Variable | Purpose | Example | +|----------|---------|---------| +| `SOAR_VERSION` | Specify version | `latest`, `nightly`, `0.4.0` | +| `SOAR_INSTALL_DIR` | Custom directory | `/usr/local/bin`, `$HOME/.local/bin` | +| `DEBUG` | Enable debug output | Set to any value | + +**Examples:** + +```sh +# Install specific version +curl -fsSL https://soar.qaidvoid.dev/install.sh | SOAR_VERSION=0.4.0 sh + +# Install to custom directory +curl -fsSL https://soar.qaidvoid.dev/install.sh | SOAR_INSTALL_DIR=$HOME/.local/bin sh + +# Enable debug output +curl -fsSL https://soar.qaidvoid.dev/install.sh | DEBUG=1 sh +``` + +## Manual Installation + +### From Pre-built Binaries + +1. **Download from [releases](https://github.com/pkgforge/soar/releases)** + +2. **Choose your architecture:** + - `soar-x86_64-linux` (Intel/AMD) + - `soar-aarch64-linux` (ARM 64-bit) + - `soar-riscv64-linux` (RISC-V 64-bit) + +3. **Install:** + +```sh +chmod +x soar-x86_64-linux +sudo mv soar-x86_64-linux /usr/local/bin/soar +``` + +### From Cargo + +```sh +cargo install soar-cli +``` + +Requires the Rust toolchain. Takes longer due to compilation. + +### Building from Source + +```sh +git clone https://github.com/pkgforge/soar.git +cd soar +cargo install --path . +``` + +Requires Rust 1.88.0+. + +## PATH Configuration + +Two directories should be in your PATH: + +- `$HOME/.local/bin` where the `soar` binary is installed +- `$HOME/.local/share/soar/bin` where packages installed by Soar are symlinked + +::: code-group + +```sh [bash] +echo 'export PATH="$HOME/.local/share/soar/bin:$HOME/.local/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + +```sh [zsh] +echo 'export PATH="$HOME/.local/share/soar/bin:$HOME/.local/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` + +::: + +## Uninstallation + +### Remove Soar + +```sh +# User installation +rm ~/.local/bin/soar +rm -rf ~/.config/soar ~/.local/share/soar + +# System installation +sudo rm /usr/local/bin/soar +sudo rm -rf /etc/soar /opt/soar +``` + +Or use the self-uninstall command: + +```sh +soar self uninstall +``` + +### Remove Packages + +```sh +soar remove ffmpeg +soar remove --all +``` + +## Troubleshooting + +**"Command not found" after installation:** + +1. Verify binary exists: `ls -la ~/.local/bin/soar` +2. Check PATH: `echo $PATH` +3. Add to PATH (see [PATH Configuration](#path-configuration)) +4. Restart shell: `source ~/.bashrc` + +**"Permission denied" installing:** + +- Use user installation: `SOAR_INSTALL_DIR=$HOME/.local/bin` +- Or use sudo: `sudo curl -fsSL https://soar.qaidvoid.dev/install.sh | sh` + +**Download fails:** + +- Try alternative CDN: `curl -fsSL https://soar.pkgforge.dev/install.sh | sh` +- Use wget: `wget -qO- https://soar.qaidvoid.dev/install.sh | sh` +- Download manually from [GitHub releases](https://github.com/pkgforge/soar/releases) + +**Build from source fails:** + +- Check Rust version: `rustc --version` (requires 1.88.0+) +- Update Rust: `rustup update` +- Install dependencies: `sudo apt install build-essential pkg-config libssl-dev` + +For more help, run `soar health`, check the verbose output with `--verbose`, or visit [GitHub Issues](https://github.com/pkgforge/soar/issues). + +## Next Steps + +```sh +# Verify installation +soar --version + +# Sync repositories +soar sync + +# Install your first package +soar install ffmpeg +``` + +- **[Configuration](./configuration.md)** - Customize settings and repositories +- **[Package Management](./package-management.md)** - Install, update, and manage packages +- **[Profiles](./profiles.md)** - Set up installation profiles diff --git a/docs/list.md b/docs/list.md new file mode 100644 index 00000000..bd2a059a --- /dev/null +++ b/docs/list.md @@ -0,0 +1,203 @@ +--- +title: List Packages +description: List available packages with soar list and installed packages with soar info, including filters, counts, and output formats. +--- + +# List Packages + +Soar provides two complementary commands for listing packages: one for what is available to install and one for what is already installed. This guide covers both, along with their filters and output formats. + +::: info List vs Info +- `soar list` lists **available** packages from repositories, meaning what you *can* install. +- `soar info` lists **installed** packages on your system, meaning what you *have* installed. +::: + +## List Available Packages + +The `list` command shows all packages available across your configured repositories. + +### Basic Usage + +```sh +# List all available packages +soar list + +# Using the short alias +soar ls +``` + +### Filter by Repository + +To list packages from a specific repository only, pass its name: + +```sh +# List packages from the 'soarpkgs' repository +soar list soarpkgs + +# List packages from the 'myrepo' repository +soar ls myrepo +``` + +### Example Output + +```sh +$ soar list soarpkgs + +[-] 7z#e4d8:soarpkgs | 24.09 | archive +[+] bat#7a3c:soarpkgs | 0.24.0 | cli +[+] curl#9f2d:soarpkgs | 8.11.1 | web +[-] ffmpeg#1b5e:soarpkgs | 7.1 | multimedia +... + +┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ Total ┃ 4 ┃ +┃ ━━━━━━━━━━━━━━━━━━━━━━━┃ +┃ ✓ Installed ┃ 2 ┃ +┃ ○ Available ┃ 2 ┃ +┗━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛ +``` + +The output format is `[icon] name#pkg_id:repo | version | type`: + +- **icon**: `✓` (or `+`) means installed, `○` (or `-`) means available, depending on whether `display.icons` is enabled +- **name**: Package name (blue) +- **pkg_id**: Package identifier (cyan) +- **repo**: Repository name (cyan) +- **version**: Package version (light red) +- **type**: Package type (magenta, optional) + +## List Installed Packages + +The `info` command, aliased as `list-installed`, shows all packages currently installed on your system, including their size and installation status. It also reports partially installed packages as `Broken`. + +### Basic Usage + +```sh +# List all installed packages +soar info + +# Using the list-installed alias +soar list-installed +``` + +Each entry includes the total size used by the package. + +### Info Command Options + +| Option | Short | Description | +|--------|-------|-------------| +| `--repo-name` | `-r` | Filter installed packages by repository name | +| `--count` | - | Only show the total count of unique installed packages | + +### Filter Installed Packages by Repository + +To see only packages installed from a specific repository: + +```sh +# Show packages installed from 'soarpkgs' +soar info --repo-name soarpkgs + +# Using the short option +soar info -r soarpkgs +``` + +### Count Installed Packages + +To get a quick count of installed packages: + +```sh +# Show total count of unique packages +soar info --count + +# Count packages from a specific repository +soar info --repo-name soarpkgs --count +``` + +### Example Output + +```sh +$ soar info + +bat-0.24.0:soarpkgs (2025-01-15) (1.8 MB) +curl-8.11.1:soarpkgs (2025-01-15) (2.4 MB) +ffmpeg-7.1:soarpkgs (2025-01-14) (15.2 MB) +jq-1.7.1:soarpkgs (2025-01-10) (1.5 MB) ✗ Broken + +┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ ✓ Installed ┃ 3, 3 distinct (20.0 MB) ┃ +┃ ✗ Broken ┃ 1 (1.5 MB) ┃ +┃ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ +┃ Total ┃ 4 (21.5 MB) ┃ +┗━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +``` + +The output format is `name-version:repo (date) (size) [status]`: + +- **name**: Package name (blue) +- **version**: Package version (magenta) +- **repo**: Repository name (cyan) +- **date**: Installation date (green) +- **size**: Package size on disk (human-readable) +- **status**: Empty for installed packages, `✗ Broken` or `[Broken]` (red) for packages with missing or corrupted files + +```sh +$ soar info --count +4 +``` + +## Common Use Cases + +### Check Package Status + +Use `info` to verify installation status before performing operations: + +```sh +# Check if a package is installed +soar info | grep ripgrep + +# Check packages from a specific repository +soar info --repo-name soarpkgs | grep ffmpeg +``` + +### Compare Available vs Installed + +```sh +# See all available ffmpeg packages +soar list | grep ffmpeg + +# Check if ffmpeg is installed +soar info | grep ffmpeg +``` + +### Manage Repositories + +```sh +# List all packages in a repository before adding it +soar list new-repo + +# After installation, verify what was installed +soar info --repo-name new-repo + +# Get a quick count of packages from the repository +soar info --repo-name new-repo --count +``` + +### Clean Up the System + +```sh +# Check the total number of packages installed +soar info --count + +# Identify broken installations +soar info | grep "Broken" + +# Remove broken packages (see remove.md) +soar remove broken-package +``` + +## See Also + +- [Search Packages](./search.md) for searching available packages by query +- [Install Packages](./install.md) for installing packages from repositories +- [Remove Packages](./remove.md) for removing installed packages +- [Configuration](./configuration.md) for configuring repositories diff --git a/docs/maintenance.md b/docs/maintenance.md new file mode 100644 index 00000000..48026a5b --- /dev/null +++ b/docs/maintenance.md @@ -0,0 +1,296 @@ +--- +title: Maintenance +description: Manage Soar itself, keep your installation healthy, and automate routine maintenance with cron or systemd timers. +--- + +# Maintenance + +This section covers the features that keep Soar itself current and your +installation in good working order, from self updates to scheduled cleanups. + +## Self Management + +Soar provides commands to manage the package manager itself, including updating +to newer versions and complete uninstallation. + +### Update Soar + +```sh +soar self update +``` + +This updates Soar to the latest version by downloading pre-compiled binaries +from GitHub releases. + +You can control which release channel to use through environment variables: + +- `SOAR_NIGHTLY=1`: switches to the nightly (development) channel. +- `SOAR_RELEASE=1`: switches to the stable release channel. + +These environment variables take precedence over the currently installed +channel. For example: + +```sh +# Update within current channel +soar self update + +# Switch to and update from nightly channel +SOAR_NIGHTLY=1 soar self update + +# Switch to and update from stable channel +SOAR_RELEASE=1 soar self update +``` + +### Uninstall Soar + +```sh +soar self uninstall +``` + +This completely removes Soar from your system. The command will: + +- Remove the Soar binary from your system. +- Prompt for confirmation before proceeding. +- Preserve your configuration and packages by default. +- Offer options to remove user data if desired. + +::: danger Irreversible action +Uninstalling cannot be undone. Consider backing up your configuration +(`~/.config/soar/config.toml`) and packages (`~/.local/share/soar/packages`) +before you proceed. +::: + +#### Uninstall Options + +```sh +# Uninstall Soar but keep configuration and packages +soar self uninstall + +# After uninstallation, manually remove data if desired: +rm -rf ~/.config/soar +rm -rf ~/.local/share/soar +``` + +## Maintenance Best Practices + +### Regular Health Checks + +Run health checks periodically to confirm your installation stays in good +condition: + +```sh +# Weekly health check +soar health +``` + +**What to look for:** + +- PATH status: add Soar's binary directory to your `PATH` if it is not configured. +- Broken packages: incomplete installations that should be cleaned up. +- Broken symlinks: dangling symlinks from removed packages. Only `-soar` suffixed files are detected in the desktop and icons directories. + +See [Health](./health.md) for the full diagnostics reference. + +### Cache Management + +Package caches can grow large over time, so regular cleanup helps reclaim disk +space: + +```sh +# Clean everything (cache, broken packages, broken symlinks) +soar clean + +# Clean only the cache +soar clean --cache + +# Check cache size before cleaning +du -sh ~/.local/share/soar/cache +``` + +::: warning +The `--cache` flag deletes the entire cache directory. +::: + +**Recommended schedule:** + +- **Monthly**: if you install packages frequently. +- **Quarterly**: for moderate usage. +- **As needed**: when disk space is low. + +### Sync Repository Metadata + +Keep your package metadata up to date so you see the latest versions: + +```sh +# Sync before searching or installing +soar sync +``` + +**Recommended schedule:** + +- **Automatic**: let Soar sync based on each repository's `sync_interval` setting (default: 3 hours). +- **Manual**: before searching for new packages or running updates. + +::: info +Repositories configured with `sync_interval = "always"` sync every time +`soar sync` is run. +::: + +### Cleanup After Failed Installations + +Failed installations can leave broken packages and symlinks behind: + +```sh +# Check for issues +soar health + +# Clean up if issues found +soar clean --broken +soar clean --broken-symlinks +``` + +**When to run:** + +- After any installation failure. +- After system crashes during installations. +- Before major system updates. + +## Scheduling Recommendations + +You can automate routine maintenance with cron or systemd timers. + +### Weekly Health Check (cron) + +```bash +# Add to crontab with: crontab -e +# Run every Sunday at 2 AM +0 2 * * 0 /usr/bin/soar health > /tmp/soar-health.log 2>&1 +``` + +### Monthly Cache Cleanup (cron) + +```bash +# Add to crontab with: crontab -e +# Run on the 1st of every month at 3 AM +0 3 1 * * /usr/bin/soar clean --cache > /tmp/soar-clean.log 2>&1 +``` + +### Systemd Timer + +Create `/etc/systemd/system/soar-health.service`: + +```ini +[Unit] +Description=Soar Health Check +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/soar health +Nice=19 +IOSchedulingClass=idle +``` + +Create `/etc/systemd/system/soar-health.timer`: + +```ini +[Unit] +Description=Weekly Soar Health Check +Requires=soar-health.service + +[Timer] +OnCalendar=weekly +Persistent=true + +[Install] +WantedBy=timers.target +``` + +Enable the timer: + +```bash +sudo systemctl enable --now soar-health.timer +``` + +## Manual Maintenance Checklist + +Perform these tasks manually every one to three months. + +1. **Health check** + + ```sh + soar health + ``` + + Review any warnings or errors, then fix broken packages or symlinks if found. + +2. **Update Soar** + + ```sh + soar self update + ``` + + Keep Soar itself up to date and review the changelog for new features. + +3. **Clean cache** + + ```sh + soar clean --cache + ``` + + Free up disk space and ensure fresh downloads on the next install. + +4. **Review packages** + + ```sh + soar list-installed + ``` + + Identify unused packages and remove the ones you no longer need. + +5. **Update packages** + + ```sh + soar update + ``` + + Keep installed packages current and review changelogs for breaking changes. + +## Maintenance Schedule Summary + +| Task | Frequency | Command | Purpose | +|------|-----------|---------|---------| +| Health Check | Weekly | `soar health` | Identify issues early | +| Full Clean | Monthly | `soar clean` | Clean cache, broken packages, and symlinks | +| Sync Metadata | Automatic | `soar sync` | Get latest package info | +| Update Soar | Quarterly | `soar self update` | Get latest features | +| Broken Cleanup | As needed | `soar clean --broken --broken-symlinks` | Fix failed installs | +| Full Maintenance | Quarterly | All commands above | Complete system checkup | + +## Troubleshooting Maintenance Issues + +### Sync Failures + +If `soar sync` fails: + +1. Check network connectivity. +2. Verify repository URLs in `~/.config/soar/config.toml`. +3. Try syncing individual repositories. +4. Check whether the repository is temporarily unavailable. + +### Cache Won't Clear + +If `soar clean --cache` does not free space: + +1. Check whether other processes are using cached files. +2. Manually remove the cache directory: `rm -rf ~/.local/share/soar/cache/*`. +3. Verify that Soar has write permissions. + +### Persistent Broken Packages + +If `soar health` keeps reporting broken packages: + +1. Try reinstalling the broken package: `soar install --force `. +2. If that fails, remove and reinstall: `soar remove && soar install `. +3. Check whether the package version is available in your repositories. +4. Report the issue to the repository maintainer. diff --git a/docs/package-management.md b/docs/package-management.md new file mode 100644 index 00000000..e027aff9 --- /dev/null +++ b/docs/package-management.md @@ -0,0 +1,42 @@ +--- +title: Package Management +description: Overview of soar's package management commands for installing, removing, updating, searching, and inspecting packages. +--- + +# Package Management + +Soar provides a comprehensive set of commands for managing packages on your system. This section is the entry point for every package management operation, from installing and removing packages to searching repositories, switching variants, and running packages without installation. + +Each topic below has a dedicated page with full details, flags, and examples. + +## Core Operations + +- [Installing Packages](./install.md) installs packages from repositories, a `pkg_id`, a URL, or a local file, including portable installation for AppImages. +- [Removing Packages](./remove.md) removes one or more installed packages. +- [Updating Packages](./update.md) keeps all or selected packages up to date. + +## Package Discovery + +- [Searching Packages](./search.md) finds packages across repositories, with case-sensitive search and detailed lookups. +- [Listing Packages](./list.md) views available packages and inspects installed ones. + +## Package Inspection + +- [Inspection Commands](./inspection.md) views build logs, inspects build scripts, and queries package details. + +## Variants and Execution + +- [Using Package Variants](./use.md) switches between different variants of an installed package. +- [Running Packages](./run.md) executes a package without installing it. + +## Declarative Management + +- [Declarative Packages](./declarative.md) defines packages in `~/.config/soar/packages.toml` and applies them with `soar apply`. + +## System Maintenance + +- [Maintenance Commands](./maintenance.md) cleans the cache, syncs repositories, and views the environment. + +::: tip +New to soar? Start with [Installing Packages](./install.md), then explore [Searching](./search.md) and [Listing](./list.md) to discover what is available. +::: diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..0542ef80 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,16 @@ +{ + "name": "soar-docs", + "version": "0.1.0", + "private": true, + "description": "Documentation for Soar, a fast, modern, bloat-free package manager for Linux.", + "type": "module", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "devDependencies": { + "vitepress": "^1.6.3", + "vue": "^3.5.13" + } +} diff --git a/docs/profiles.md b/docs/profiles.md new file mode 100644 index 00000000..3a30b417 --- /dev/null +++ b/docs/profiles.md @@ -0,0 +1,166 @@ +--- +title: Profiles +description: Isolated package environments in soar, with path resolution, usage, and system mode. +--- + +# Profiles + +Profiles are isolated package environments that allow you to maintain separate package sets for different purposes. Each profile has its own root directory and package storage. + +## Profile Configuration + +Each profile is defined in your Soar configuration file (`~/.config/soar/config.toml` for user, `/etc/soar/config.toml` for system) under a `[profile.]` section. + +### Profile Structure + +```toml +[profile.] +root_path = "/path/to/profile/root" +packages_path = "/path/to/packages" # Optional +``` + +- **`root_path`** (required): Root directory for the profile. Defaults to `~/.local/share/soar` or `$SOAR_ROOT/soar` if not in system mode. +- **`packages_path`** (optional): Custom location for package storage. If not set, defaults to `/packages`. + +### Path Resolution Priority + +Soar resolves paths in this order (highest priority first): + +1. **Environment variables** (`SOAR_BIN`, `SOAR_DB`, `SOAR_CACHE`, `SOAR_PACKAGES`, `SOAR_REPOSITORIES`, `SOAR_PORTABLE_DIRS`) +2. **Global configuration overrides** (`bin_path`, `db_path`, `cache_path`, etc. in the root of `config.toml`) +3. **Profile-specific paths** (computed from `root_path`) + +::: warning Precedence +Global configuration paths and environment variables take precedence over profile-computed paths. If you set `bin_path` in the global config or the `SOAR_BIN` environment variable, it will be used instead of the profile's `/bin`. +::: + +### Computed Paths + +From the `root_path`, Soar automatically derives these paths (unless overridden): + +| Path | Computed As | Can Override With | +|------|-------------|-------------------| +| Packages | `/packages` (or `packages_path` if set) | `SOAR_PACKAGES` env var | +| Binaries | `/bin` | `bin_path` config or `SOAR_BIN` env var | +| Database | `/db` | `db_path` config or `SOAR_DB` env var | +| Cache | `/cache` | `cache_path` config or `SOAR_CACHE` env var | +| Repositories | `/repos` | `repositories_path` config or `SOAR_REPOSITORIES` env var | +| Portable Dirs | `/portable-dirs` | `portable_dirs` config or `SOAR_PORTABLE_DIRS` env var | + +### Minimal Configuration + +```toml +[profile.default] +root_path = "~/.local/share/soar" +``` + +This creates: + +- `~/.local/share/soar/packages/` - Installed packages +- `~/.local/share/soar/bin/` - Binary symlinks (unless overridden globally) +- `~/.local/share/soar/cache/` - Download cache (unless overridden globally) +- `~/.local/share/soar/db/` - Package database (unless overridden globally) + +### Custom Packages Path + +```toml +[profile.production] +root_path = "/opt/soar/production" +packages_path = "/opt/soar/production/packages" +``` + +## Using Profiles + +### Specifying a Profile + +Use the `--profile ` flag with any Soar command: + +```bash +# Install to specific profile +soar --profile dev install neovim +soar --profile testing install ripgrep + +# List packages in a profile +soar --profile dev list + +# Remove from a profile +soar --profile testing remove ripgrep + +# Update packages in a profile +soar --profile dev update +``` + +### Environment Variable Override + +The `SOAR_ROOT` environment variable overrides the `root_path` setting for any profile: + +```bash +SOAR_ROOT=/tmp/test-soar soar install neovim +``` + +### System Mode + +Use the `--system` flag (`-S`) to operate in system-wide mode. This changes the config location to `/etc/soar/config.toml` and typically requires root privileges: + +```bash +sudo soar --system install git +sudo soar --system --profile global add node +``` + +## Profile Examples + +### Development vs Production + +```toml +# ~/.config/soar/config.toml +[profile.dev] +root_path = "~/dev-soar" + +[profile.production] +root_path = "~/prod-soar" +``` + +```bash +# Install development tools +soar --profile dev install rustc cargo node + +# Install production-grade tools +soar --profile production install nginx postgresql +``` + +### System-Wide Profile + +```toml +# /etc/soar/config.toml +[profile.global] +root_path = "/opt/soar" +``` + +```bash +sudo soar --system --profile global install git +``` + +## Directory Structure + +Profile with `root_path = "~/.local/share/soar"`: + +``` +~/.local/share/soar/ +├── bin/ # Symlinks to package binaries +├── cache/ # Download cache +├── db/ # Package database +├── packages/ # Installed packages +├── repos/ # Repository metadata +└── portable-dirs/ # Portable app data +``` + +## Summary + +Profiles provide simple, file-based environment isolation: + +- **Configuration**: Define profiles in `config.toml` with `root_path` and optional `packages_path` +- **Usage**: Specify profiles with `--profile ` flag +- **Path Priority**: Environment variables > global config overrides > profile-computed paths +- **Computed Paths**: bin, db, cache, repos, portable-dirs are automatically derived from `root_path` unless overridden +- **System Mode**: Use `--system` flag for system-wide installations +- **Environment Override**: `SOAR_ROOT` overrides profile `root_path` at runtime diff --git a/docs/public/favicon.svg b/docs/public/favicon.svg new file mode 100644 index 00000000..471c7d98 --- /dev/null +++ b/docs/public/favicon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 00000000..cb16ec57 --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,162 @@ +--- +title: Quick Start +description: Install Soar, set up your PATH, and manage your first packages in under five minutes. +--- + +# Quick Start Guide + +Get Soar installed and managing packages in under five minutes. + +## First Time Setup + +### Step 1: Install Soar + +```sh +curl -fsSL https://soar.qaidvoid.dev/install.sh | sh +``` + +### Step 2: Verify Installation + +```sh +soar --version +``` + +### Step 3: Add to PATH + +::: code-group + +```sh [bash] +echo 'export PATH="$HOME/.local/bin:$HOME/.local/share/soar/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + +```sh [zsh] +echo 'export PATH="$HOME/.local/bin:$HOME/.local/share/soar/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` + +::: + +### Step 4: Install Your First Package + +```sh +soar sync +soar install neovim +``` + +::: tip Need more options? +See the [Installation Guide](./installation.md) for manual installs, custom directories, and version pinning. +::: + +## Daily Package Management + +### Search Packages + +```sh +soar search python +soar query neovim +``` + +### Install Packages + +```sh +soar install git +soar install git curl wget +soar install https://example.com/package.AppImage +``` + +### List Packages + +```sh +soar list +soar info +``` + +### Update Packages + +```sh +soar update +soar update neovim git +``` + +### Remove Packages + +```sh +soar remove neovim +``` + +### Run Without Installing + +```sh +soar run neovim +``` + +## Switching from Another Package Manager + +### From apt (Debian/Ubuntu) + +| Task | apt Command | Soar Equivalent | +|------|-------------|-----------------| +| Update cache | `sudo apt update` | `soar sync` | +| Install | `sudo apt install ` | `soar install ` | +| Remove | `sudo apt remove ` | `soar remove ` | +| Update | `sudo apt upgrade` | `soar update` | +| Search | `apt search ` | `soar search ` | +| List installed | `apt list --installed` | `soar info` | + +### From pacman (Arch Linux) + +| Task | pacman Command | Soar Equivalent | +|------|---------------|-----------------| +| Update database | `sudo pacman -Sy` | `soar sync` | +| Install | `sudo pacman -S ` | `soar install ` | +| Remove | `sudo pacman -R ` | `soar remove ` | +| Update system | `sudo pacman -Syu` | `soar update` | +| Search | `pacman -Ss ` | `soar search ` | +| List installed | `pacman -Qe` | `soar info` | + +## Managing Multiple Systems + +Profiles let you maintain separate package environments. + +### Create a Profile + +Edit `~/.config/soar/config.toml`: + +```toml +[profile.default] +root_path = "~/.local/share/soar" + +[profile.dev] +root_path = "~/dev-tools" +``` + +### Use Profiles + +```sh +soar --profile dev install neovim +soar --profile dev list +soar --profile dev update +``` + +### Set Default Profile + +```toml +default_profile = "dev" +``` + +## Troubleshooting + +Run diagnostics if something is not working: + +```sh +soar health +``` + +For comprehensive troubleshooting, see [Health & Diagnostics](./health.md). + +## What's Next? + +- **[Configuration](./configuration.md)** - Customize settings and repositories +- **[Package Management](./package-management.md)** - Install, update, and manage packages +- **[Profiles](./profiles.md)** - Set up installation profiles diff --git a/docs/releases.md b/docs/releases.md new file mode 100644 index 00000000..c9a76d3a --- /dev/null +++ b/docs/releases.md @@ -0,0 +1,12 @@ +--- +title: Release Notes +description: Release notes for Soar, documenting new features, breaking changes, and improvements across versions. +--- + +# Release Notes + +This section contains release notes for Soar versions, documenting new features, breaking changes, and improvements. + +- [Soar 0.12](./releases/v0.12.md): Repository management CLI, fuzzy search, repository consolidation (soarpkgs), inline public keys, and concurrent safety. +- [Soar 0.11](./releases/v0.11.md): Nest removal, custom desktop paths, and release notes on update. +- [Soar 0.10](./releases/v0.10.md): GitHub and GitLab sources, build from source, hooks, Landlock sandboxing, and system-wide installs. diff --git a/docs/releases/v0.10.md b/docs/releases/v0.10.md new file mode 100644 index 00000000..b82da416 --- /dev/null +++ b/docs/releases/v0.10.md @@ -0,0 +1,291 @@ +# Soar 0.10 + +## 0.10.3 + +### Glob Support in Binary Maps + +The `source` field in binary mappings now supports glob patterns, making it easier to select binaries from packages that contain multiple files: + +```toml +[packages] +my-tools = { + url = "https://example.com/tools.tar.gz", + binaries = [ + { source = "bin/tool-*" } + ] +} +``` + +When a glob matches multiple files, each matched file is symlinked using its original filename. The `link_as` field is now optional. If omitted, the symlink uses the source filename. When a glob matches a single file, `link_as` is used if specified. + +### Placeholder Support + +URL and path fields now support `{arch}`, `{os}`, and `{version}` placeholders that are automatically substituted with system metadata: + +```toml +[packages] +tool = { + url = "https://example.com/tool-{version}-{arch}-{os}.tar.gz", + version = "1.2.0" +} +``` + +### Removal of `update` Field + +The `update` field has been removed from `packages.toml`. GitHub and GitLab sources are now detected automatically from the `github`/`gitlab` fields, making the separate `update` configuration unnecessary. + +### Fallback Token Environment Variables + +GitHub and GitLab token detection now supports fallback environment variables: +- **GitHub**: `GITHUB_TOKEN` or `GH_TOKEN` +- **GitLab**: `GITLAB_TOKEN` or `GL_TOKEN` + +This improves compatibility with the GitHub CLI (`gh`) and other tools that use `GH_TOKEN`. + +### Bug Fixes + +- Fixed HTTP status code handling in download fallback logic +- Install script now automatically uses system-wide mode (`--system`) when run as root + +## 0.10.2 + +### Changes + +- System install path changed from `/usr/lib/soar` to `/opt/soar` for compatibility with atomic/immutable distros + +## 0.10.1 + +### Bug Fixes + +- Fixed sudo privilege escalation failing to find soar binary when installed in user directories not in sudo's `secure_path` + +## 0.10.0 + +Soar 0.10 brings **GitHub/GitLab release support**, **build-from-source**, **install hooks**, **Landlock sandboxing**, and **system-wide installs**. This release addresses some of the most requested features and lays the groundwork for more flexible package management. + +### Breaking Changes + +Before upgrading, note the following: + +**Database schema change**: The `with_pkg_id` field has been removed. After updating, run `soar sync` to migrate your database. + +**URL package versioning**: The versioning scheme for URL-based packages has changed. If you have URL packages in your `packages.toml`, run `soar apply` to update their tracking information. Note that if you didn't have `pkg_id` explicitly set, the package may be duplicated since the ID change is treated as a different package. You can remove the old entry manually if this happens. + +### System-Wide Installs + +Until now, Soar only supported per-user installations. This worked well for personal setups, but made it difficult to deploy packages across multi-user systems or manage packages via configuration management tools. + +Soar 0.10 adds the `-S` (or `--system`) flag for system-wide package management: + +```bash +soar -S install neovim +soar -S apply +soar -S update +``` + +Soar will automatically use `sudo` or `doas` for privilege escalation. System packages are installed to `/opt/soar`, with configuration stored at `/etc/soar/config.toml`. + +### GitHub/GitLab as Package Sources + +Previously, if a project didn't have a package in the registry, you had to either wait for someone to add it or manually manage the download URL and version tracking yourself. + +Now you can point Soar directly at any GitHub or GitLab repository: + +```toml +[packages] +neovim = { github = "neovim/neovim", asset_pattern = "*linux-x86_64.appimage" } +``` + +Soar will fetch the latest release and select the asset matching your pattern. Version tracking and updates work automatically. + +For rate-limited or private repositories, set `GITHUB_TOKEN` or `GITLAB_TOKEN` in your environment. + +#### Tag Filtering + +Not every release is suitable for production. You can filter releases by tag pattern: + +```toml +nvim-stable = { + github = "neovim/neovim", + asset_pattern = "*linux-x86_64.appimage", + tag_pattern = "v*.*.*" +} +``` + +This ensures you only receive tagged stable releases, ignoring prereleases or nightlies. + +#### Custom Version Detection + +For cases where standard release detection doesn't work (nightly builds, non-standard versioning), you can provide a custom `version_command`: + +```toml +nvim-nightly = { + github = "neovim/neovim", + asset_pattern = "*linux-x86_64.appimage", + version_command = "curl -s https://api.gh.pkgforge.dev/repos/neovim/neovim/releases/tags/nightly | jq -r '.published_at, (.assets[] | select(.name | endswith(\"linux-x86_64.appimage\")) | .browser_download_url, .size)'" +} +``` + +The command should output up to three newline-separated values: version identifier, download URL, and file size. + +### Hooks + +Some packages need post-install setup: setting permissions, running initialization scripts, or registering with system services. Previously, this had to be done manually after each install or update. + +Hooks let you automate these steps: + +```toml +[packages] +myapp = { + url = "https://example.com/app.tar.gz", + hooks = { + post_extract = "chmod +x bin/*", + post_install = "./setup.sh", + pre_remove = "./cleanup.sh" + } +} +``` + +Four hook points are available: `post_download`, `post_extract`, `post_install`, and `pre_remove`. + +Hooks receive several environment variables: +- `INSTALL_DIR`: the package installation directory +- `BIN_DIR`: Soar's bin directory +- `PKG_NAME`, `PKG_ID`, `PKG_VERSION`: package metadata + +### Build From Source + +Not everything ships prebuilt binaries. Some projects only distribute source tarballs, or you may need custom compile flags for your environment. + +Soar can now build packages from source: + +```toml +[packages] +lua = { + url = "https://www.lua.org/ftp/lua-5.4.7.tar.gz", + extract_root = "lua-5.4.7", + build = { + commands = [ + "make linux -j$NPROC", + "make install INSTALL_TOP=$INSTALL_DIR" + ], + dependencies = ["gcc", "make", "libreadline-dev"] + }, + binaries = [ + { source = "bin/lua", link_as = "lua" }, + { source = "bin/luac", link_as = "luac" } + ] +} +``` + +The `$NPROC` environment variable is set to your CPU core count for parallel compilation. The `dependencies` field documents build requirements; Soar doesn't install these automatically. + +### Landlock Sandboxing + +Running arbitrary build scripts and hooks from the internet is inherently risky. A malicious or buggy script could read sensitive files or modify system state. + +Soar 0.10 integrates Linux's Landlock LSM to sandbox hook and build command execution: + +```toml +[packages] +untrusted-pkg = { + url = "https://example.com/pkg.tar.gz", + sandbox = { + require = true, + fs_read = ["/opt/libs"], + fs_write = ["/var/tmp"] + }, + hooks = { + post_extract = "make build" + } +} +``` + +By default, sandboxed commands can: +- **Read**: `/usr`, `/lib`, `/bin`, `/etc/ssl/certs`, `/proc`, `/sys`, and other standard system paths +- **Write**: the package's install directory and `/tmp` + +Additional paths can be granted via `fs_read` and `fs_write`. + +Setting `require = true` makes Soar fail if Landlock is unavailable (older kernels or disabled). With `require = false`, Soar warns and proceeds unsandboxed. + +### Binary Symlink Configuration + +Soar's automatic binary discovery works well for simple packages, but sometimes you need more control: renaming binaries, creating multiple symlinks to the same executable, or selecting specific binaries from a package. + +The `entrypoint` field handles simple renaming: + +```toml +app = { + url = "https://example.com/app.tar.gz", + entrypoint = "bin/actual-binary-name" +} +``` + +For multiple symlinks, use `binaries`: + +```toml +neovim = { + github = "neovim/neovim", + asset_pattern = "*.appimage", + binaries = [ + { source = "neovim", link_as = "nvim" }, + { source = "neovim", link_as = "vi" } + ] +} +``` + +Note: Downloaded assets are renamed to match the package name, hence the source being `neovim` rather than the original filename. + +### GHCR Support + +GitHub Container Registry images can now be used as package sources: + +```toml +[packages] +tool = { url = "ghcr.io/owner/repo:v1.0.0", entrypoint = "app" } +``` + +Or install directly from the command line: + +```bash +soar install ghcr.io/pkgforge/tool:latest +``` + +### Full Example + +Here's a `packages.toml` demonstrating the new features together: + +```toml +[packages] +# Registry package +curl = "*" + +# GitHub release with asset pattern +ripgrep = { github = "BurntSushi/ripgrep", asset_pattern = "*x86_64*linux-musl*.gz" } + +# Full build configuration +my-tool = { + url = "https://example.com/tool-2.0.0.tar.gz", + version = "2.0.0", + extract_root = "tool-2.0.0", + + build = { + commands = ["make -j$NPROC", "make install PREFIX=$INSTALL_DIR"], + dependencies = ["gcc", "make"] + }, + + hooks = { post_install = "$INSTALL_DIR/bin/tool --setup" }, + + sandbox = { require = false, fs_read = ["/usr/include"] }, + + binaries = [ + { source = "bin/tool", link_as = "tool" }, + { source = "bin/toolctl", link_as = "toolctl" } + ] +} +``` + +### What Else? + +- `soar update` now properly tracks and updates URL-based and GitHub/GitLab packages when managed declaratively via `packages.toml`. Packages installed directly with `soar install` don't support updates for these sources, as there's not enough context to determine how to fetch newer versions diff --git a/docs/releases/v0.11.md b/docs/releases/v0.11.md new file mode 100644 index 00000000..eb127a74 --- /dev/null +++ b/docs/releases/v0.11.md @@ -0,0 +1,31 @@ +# Soar 0.11 + +## 0.11.0 + +Soar 0.11 focuses on simplification and improved user experience, removing deprecated features and adding quality-of-life improvements. + +### Breaking Changes + +**Nest functionality removed**: The `nest` feature has been removed. If you were using nests to manage custom repositories, migrate to the standard repository configuration in `config.toml`. See [Configuration](../configuration.md) for details on adding custom repositories. + +**`--external` flag removed**: The `--external` flag for `soar defconfig` has been removed. Previously this flag enabled non-core repositories in the generated config. Now, no external repositories are provided by default, so you'd need to add them manually in your config. + +### Custom Desktop File Path + +You can now configure where desktop files are installed. By default, Soar places `.desktop` files in `~/.local/share/applications` (user mode) or `/usr/local/share/applications` (system mode). If you need them elsewhere, set the `desktop_path` field in your config: + +```toml +desktop_path = "/path/to/custom/applications" +``` + +Alternatively, use the `SOAR_DESKTOP` environment variable. + +### Release Notes on Update + +When updating Soar itself, you'll now see release notes for the new version. This helps you stay informed about new features, breaking changes, and bug fixes without having to check the documentation manually. + +The update experience has also been improved with clearer progress indicators and status messages. + +### Bug Fixes + +- Fixed detection of default repositories when no config file exists diff --git a/docs/releases/v0.12.md b/docs/releases/v0.12.md new file mode 100644 index 00000000..7fab7b45 --- /dev/null +++ b/docs/releases/v0.12.md @@ -0,0 +1,125 @@ +# Soar 0.12 + +## 0.12.1 + +Soar 0.12.1 adds CLI-based repository management, custom architecture name mapping, and fuzzy search, along with download and update fixes. + +### Repository Management CLI + +You can now add, update, remove, and list repositories directly from the command line using `soar repo` (or `soar repository`), without manually editing `config.toml`: + +```sh +# List configured repositories +soar repo list + +# Add a new repository +soar repo add myrepo https://example.com/metadata.sdb.zstd \ + --pubkey "RWQ109..." --signature-verification true + +# Update repository settings +soar repo update myrepo --enabled false + +# Remove a repository and its cached data +soar repo remove myrepo +``` + +See [Repository Management](../repo.md) for full documentation. + +### Custom Architecture Mapping + +Packages in `packages.toml` can now define an `arch_map` to override the value substituted for the `{arch}` placeholder. The keys are the standard architecture names (`x86_64`, `aarch64`) and the values are the custom names expected by the package source. This is useful for upstreams that use non-standard architecture naming in their download URLs: + +```toml +[packages] +mytool = { url = "https://example.com/mytool-{arch}.tar.gz", arch_map = { x86_64 = "amd64", aarch64 = "arm64" } } +``` + +On an `x86_64` host this resolves the URL to `https://example.com/mytool-amd64.tar.gz`. Without `arch_map`, `{arch}` substitutes the host architecture as-is. + +### Fuzzy Search and "Did You Mean?" Suggestions + +`soar search` now uses fuzzy matching by default, so partial or slightly misspelled queries still surface relevant packages (it falls back to SQL `LIKE` for case-sensitive searches). When `soar install` can't find a package, soar suggests the closest matching names: + +``` +$ soar install ripgep +Package ripgep not found +Did you mean: ripgrep? +``` + +### Performance + +- Fixed mutex contention in parallel downloads and database access, improving throughput when installing or updating multiple packages at once + +### Bug Fixes + +- `soar update` now resolves `{arch}`, `{os}`, and `{version}` placeholders in package URLs, so update checks act on the resolved URL instead of one still containing literal placeholders + +## 0.12.0 + +Soar 0.12 consolidates the default repositories into a single unified source, changes how public keys are configured, introduces internal architecture improvements, and adds several quality-of-life features. + +### Breaking Changes + +**Repository consolidation**: The `bincache` and `pkgcache` repositories have been replaced with the unified [soarpkgs](https://github.com/pkgforge/soarpkgs) repository. The old repositories are no longer updated. + +If you have a custom `config.toml`, replace your existing repository entries: + +```toml +# Old (remove these) +[[repositories]] +name = "bincache" +url = "https://meta.pkgforge.dev/bincache/x86_64-Linux.sdb.zstd" + +[[repositories]] +name = "pkgcache" +url = "https://meta.pkgforge.dev/pkgcache/x86_64-Linux.sdb.zstd" + +# New (add this) +[[repositories]] +name = "soarpkgs" +url = "https://github.com/pkgforge/soarpkgs/releases/latest/download/metadata-x86_64-linux.sdb.zstd" +pubkey = "RWQ109gKujRqohsA7RERlXFfeJi23EcHN3Dz8TxyPAywa5mLw/fbcbU4" +desktop_integration = true +``` + +Not all packages have been ported to soarpkgs yet. If you need a package that hasn't been migrated: +- [Request it](https://github.com/pkgforge/soarpkgs/issues/new/choose) to be added to soarpkgs +- Or use an older version of soar that still supports the old repositories + +**Public key configuration**: The `pubkey` field now expects an inline key string instead of a URL. If you had `pubkey = "https://..."`, replace it with the actual key value. + +**Database schema change**: The `recurse_provides` field has been removed and `pkg_family` has been added. After updating, run `soar sync` to refresh your database. + +**pkgforge API proxy removed**: GitHub and GitLab release fetching previously used pkgforge proxy endpoints (`api.gh.pkgforge.dev`, `api.gl.pkgforge.dev`) as a fallback to avoid rate limits. These proxies have been removed, so soar now always calls the upstream GitHub and GitLab APIs directly. If you hit rate limits, set `GITHUB_TOKEN` or `GITLAB_TOKEN` in your environment. + +### @ Prefix for Provides + +Packages can now expose additional binaries through the `provides` field using the `@` prefix. When a package's provides list includes entries starting with `@` (e.g., `@age-keygen`), those binaries are symlinked directly from the package's install directory to your bin directory. + +This means packages that ship multiple binaries can make all of them available on your PATH without needing manual configuration. + +### Concurrent Process Safety + +Running multiple soar instances simultaneously (e.g., in parallel terminal sessions) is now safe. Soar uses file-based locking to prevent concurrent operations from corrupting the database or conflicting with each other. If another instance is running, soar will wait for it to finish before proceeding. + +### JSON to SQLite Conversion + +A new `json2db` subcommand converts JSON metadata files to SQLite databases. This is useful for repository maintainers who generate metadata in JSON format and need to produce the `.sdb` database files that soar consumes: + +```sh +soar json2db metadata.json output.sdb --repo myrepo +``` + +### Internal Improvements + +- **soar-operations crate**: Core package operations (install, remove, update, apply, etc.) have been extracted into a frontend-agnostic `soar-operations` crate, enabling future alternative frontends (GUI, TUI, etc.) +- **soar-events crate**: Event reporting has been extracted into a dedicated `soar-events` crate for structured progress and status reporting +- **Per-context system mode**: System mode configuration is now tracked per-context rather than relying solely on a global flag, improving reliability when mixing user and system operations + +### Bug Fixes + +- Fixed desktop entry `Exec` and `TryExec` fields losing flags and arguments during installation +- Fixed package version normalization during substitution +- Fixed `sync_interval` not being properly respected for repository updates +- Fixed health check using relative paths instead of absolute paths +- Fixed repository `enabled` flag not being respected diff --git a/docs/remove.md b/docs/remove.md new file mode 100644 index 00000000..97593951 --- /dev/null +++ b/docs/remove.md @@ -0,0 +1,252 @@ +--- +title: Removing Packages +description: Remove installed packages with soar, including specific pkg_ids, multiple packages at once, and cleanup of broken or partial installations. +--- + +# Remove Packages + +Soar provides straightforward commands for removing installed packages from your system. This guide covers the removal options, what happens during removal, and troubleshooting tips. + +## Usage + +To remove a package, use the `remove` command or one of its aliases. + +### Removing a single package + +::: code-group + +```sh [remove] +soar remove +``` + +```sh [r] +soar r +``` + +```sh [del] +soar del +``` + +::: + +Example: remove `7z`. + +```sh +soar remove 7z +``` + +### Command options + +The `remove` command supports the following options. + +| Option | Description | +|--------|-------------| +| `--yes` | Skip confirmation prompts. Automatically selects the first option when multiple packages match. | +| `--all` | Remove all installed variants of the specified package across different pkg_ids. | + +#### Using --yes + +Skip interactive prompts when removing packages. + +```sh +# Remove without confirmation +soar remove --yes 7z + +# Automatically select first match when multiple variants exist +soar remove --yes bat +``` + +#### Using --all + +Remove all installed variants of a package. + +```sh +# Remove all versions of bat from all pkg_ids +soar remove --all bat + +# Remove with --yes to skip bulk confirmation +soar remove --all --yes cat +``` + +::: warning Removes every variant +Using `--all` will remove ALL installed variants of the package, including those from different repositories and pkg_ids. Use with caution. +::: + +### Removing multiple packages + +Remove multiple packages in a single command. + +```sh +soar remove +``` + +Example: remove `7z` and `bat`. + +```sh +soar remove 7z bat +``` + +::: info +If you provide only the package name without a pkg_id and multiple packages match, you will be prompted to select ONE package to remove. Use `--all` to remove all variants. +::: + +### Removing a package from a specific pkg_id + +```sh +soar remove # +``` + +Example: remove `cat` from the `git.busybox.net.busybox.standalone.glibc` pkg_id. + +```sh +soar remove cat#git.busybox.net.busybox.standalone.glibc +``` + +### Removing all packages from a specific pkg_id + +```sh +soar remove '#all' +``` + +This searches for all pkg_ids that `cat` is in and prompts you to choose one. + +```sh +soar remove 'cat#all' +``` + +After you select a pkg_id, all packages from that pkg_id will be removed. + +## What Happens During Removal + +When you remove a package, Soar performs these cleanup operations. + +1. **Pre-Remove Hook** (if configured) +2. **Binary Symlink Removal** from `~/.local/share/soar/bin` +3. **Provides Symlink Cleanup** for alternative names +4. **Desktop Entry Removal** from `~/.local/share/applications` +5. **Icon Symlink Cleanup** from `~/.local/share/icons` +6. **Package Directory Removal** from `~/.local/share/soar/packages` +7. **Cache Handling**: download cache preserved (use `soar clean --cache` to reclaim) +8. **Database Cleanup**: removes the package record and portable entries + +Example output: + +``` +Removed 7z#upstream.release:official (24.08) + - Removed binary: ~/.local/share/soar/bin/7z + - Removed directory: ~/.local/share/soar/packages/7z-24.08 + - Reclaimed 2.3 MiB +``` + +## Partial vs Complete Removal + +### Complete removal + +A complete removal occurs when: + +- The package was successfully installed (`is_installed = true`) +- All files and symlinks are properly cleaned up +- The package is removed from the database + +This is the normal and expected removal process. + +### Partial removal (broken packages) + +A partial or incomplete installation can occur when: + +- The installation process was interrupted (network failure, system crash) +- Disk space ran out during installation +- The package was manually deleted from the filesystem + +These are marked as **broken packages** in Soar's database (`is_installed = false`). + +#### Identifying broken packages + +To check for broken or incomplete installations: + +```sh +soar health +``` + +Example output showing broken packages: + +``` +Broken Packages (1): + 7z#upstream.release:official /home/user/.local/share/soar/packages/7z-24.08 +``` + +#### Removing broken packages + +To remove all broken packages: + +```sh +soar clean --broken +``` + +This command: + +- Lists all broken packages in the database +- Removes their directories (if they still exist) +- Removes any leftover symlinks +- Cleans up database entries + +## Troubleshooting + +### Stuck or incomplete removals + +Check system health and fix broken symlinks. + +```sh +soar health +soar clean --broken-symlinks +``` + +### Package will not remove + +Check file permissions, ensure the package is not running, and use verbose mode. + +```sh +ls -la ~/.local/share/soar/packages/ +pgrep -a +soar --verbose remove +``` + +For more help, see [Health Check](./health.md). + +### Manual cleanup + +For manual cleanup of stuck packages: + +1. Find the package directory. + + ```sh + soar info | grep + ``` + +2. Remove the directory manually. + + ```sh + rm -rf ~/.local/share/soar/packages/ + ``` + +3. Remove symlinks manually. + + ```sh + rm -f ~/.local/share/soar/bin/ + ``` + +4. Run a health check. + + ```sh + soar health + ``` + +5. Clean up any remaining broken symlinks. + + ```sh + soar clean --broken-symlinks + ``` + +::: warning Destructive commands +The `rm -rf` and `rm -f` commands above permanently delete files. Double-check each path before running them, since there is no undo. +::: diff --git a/docs/repo.md b/docs/repo.md new file mode 100644 index 00000000..eb28e089 --- /dev/null +++ b/docs/repo.md @@ -0,0 +1,112 @@ +--- +title: Repository Management +description: Add, update, remove, and list Soar repositories from the command line without editing config.toml by hand. +--- + +# Repository Management + +Soar manages repositories directly from the command line through `soar repo` (or `soar repository`). You can add, update, remove, and list repositories without manually editing `config.toml`. + +## List Repositories + +View all configured repositories: + +```sh +soar repo list +``` + +This displays each repository's name, status (enabled or disabled), and URL. + +## Add a Repository + +```sh +soar repo add [options] +``` + +### Options + +| Option | Description | +|--------|-------------| +| `--pubkey ` | Base64-encoded public key for signature verification | +| `--enabled ` | Whether the repository is enabled (default: true) | +| `--desktop-integration ` | Enable desktop integration for packages | +| `--signature-verification ` | Enable signature verification | +| `--sync-interval ` | Sync interval (for example `"1h"`, `"12h"`, `"1d"`) | + +### Examples + +Add a basic repository: + +```sh +soar repo add myrepo https://example.com/metadata.sdb.zstd +``` + +Add a repository with signature verification: + +```sh +soar repo add myrepo https://example.com/metadata.sdb.zstd \ + --pubkey "RWQ109gKujRqohsA7RERlXFfeJi23EcHN3Dz8TxyPAywa5mLw/fbcbU4" \ + --signature-verification true +``` + +Add a disabled repository: + +```sh +soar repo add staging https://example.com/staging.sdb.zstd --enabled false +``` + +## Update a Repository + +Modify settings on an existing repository. Only the fields you specify are changed: + +```sh +soar repo update [options] +``` + +### Options + +| Option | Description | +|--------|-------------| +| `--url ` | New metadata URL | +| `--pubkey ` | New public key | +| `--enabled ` | Enable or disable the repository | +| `--desktop-integration ` | Enable or disable desktop integration | +| `--signature-verification ` | Enable or disable signature verification | +| `--sync-interval ` | New sync interval | + +### Examples + +Disable a repository: + +```sh +soar repo update myrepo --enabled false +``` + +Change the URL and sync interval: + +```sh +soar repo update myrepo --url https://new.example.com/metadata.sdb.zstd --sync-interval 6h +``` + +## Remove a Repository + +```sh +soar repo remove +``` + +This removes the repository from the configuration and cleans up its local data directory. + +### Example + +```sh +soar repo remove myrepo +``` + +::: warning +Removing a repository deletes its cached metadata. Packages already installed from the repository remain installed but will not receive updates until the repository is re-added. +::: + +## Related Topics + +- [Configuration](./configuration.md) for manual repository configuration in `config.toml` +- [Maintenance](./maintenance.md) for repository sync and maintenance diff --git a/docs/run.md b/docs/run.md new file mode 100644 index 00000000..2c995bc6 --- /dev/null +++ b/docs/run.md @@ -0,0 +1,200 @@ +--- +title: Run Packages +description: Run packages on demand without installing them into your PATH or desktop environment. +--- + +# Run Packages + +Soar lets you run packages without installing them permanently on your system. The package files are still downloaded and stored, but they are not integrated into your system PATH or desktop environment. This is ideal for trying out applications or running one-off tasks. + +## Run vs Install + +| Feature | `soar run` | `soar install` | +|---------|-----------|----------------| +| **PATH Integration** | ❌ Not added to PATH | ✅ Added to profile's bin directory | +| **Desktop Integration** | ❌ No desktop entries | ✅ Desktop entries created | +| **Persistence** | ✅ Files stored for reuse | ✅ Permanently installed | +| **Symlinks** | ❌ No symlinks created | ✅ Symlinks for `provides` entries | +| **Quick Access** | Must use full command | Available from anywhere | +| **Cleanup** | Manual removal from cache directory | Managed via `soar remove` | +| **Use Case** | Try before installing, one-off tasks | Daily use applications | + +::: tip When to use run +Reach for `run` when testing a new tool, running a security scanner occasionally, trying different versions, or when you do not want to clutter your PATH. +::: + +## Basic Usage + +The basic syntax for running a package is: + +```sh +soar run [command arguments...] +``` + +The first argument after `run` is the package name, followed by any arguments to pass to the package's binary. + +### Example: run feroxbuster + +```sh +soar run feroxbuster --url https://example.com --depth 2 +``` + +### Example: run a specific version + +```sh +soar run python@3.11 --version +``` + +## Command Options + +The `run` command supports several options to control package selection and behavior. + +### `--yes` / `-y` + +Skip all prompts and automatically select the first available package variant. + +```sh +soar run --yes feroxbuster +``` + +This is useful for scripting or when you are confident in the default selection. + +### `--pkg-id ` + +Specify the exact package ID to run. This is useful when multiple packages provide the same binary. + +```sh +soar run --pkg-id coreutils@9.5 ls --version +``` + +### `--repo-name ` / `-r ` + +Specify which repository to fetch the package from. + +```sh +soar run --repo-name main python +``` + +This is helpful when the same package exists in multiple repositories. + +## Command Passing + +Any arguments after the package name are passed directly to the package's binary: + +```sh +soar run feroxbuster --url https://example.com --depth 2 --threads 10 +``` + +In this example: + +- `feroxbuster` is the package name. +- `--url https://example.com --depth 2 --threads 10` are arguments passed to feroxbuster. + +::: info Argument parsing +The first non-option argument is treated as the package name. All subsequent arguments are passed to the package. +::: + +### Example: running with complex arguments + +```sh +soar run python -c "print('Hello from Soar!')" +``` + +```sh +soar run node --eval "console.log('Node.js via Soar')" +``` + +## Storage and Caching + +Soar caches run packages in `~/.local/share/soar/cache/bin` to avoid re-downloading. + +- **Downloads once.** The package is downloaded on first run. +- **Reuses cached binary.** Subsequent runs use the cached copy. +- **Validates checksums.** Soar validates checksums after download and prompts for confirmation on mismatch. +- **Separate from installed packages.** Run packages use the cache directory, not the packages directory. + +::: info Cached binaries persist +Cached binaries persist for faster subsequent execution. Clean them manually from `~/.local/share/soar/cache/bin` or use `soar clean --cache` when no longer needed. +::: + +## Practical Examples + +### Try before you install + +```sh +# Test a network scanner +soar run feroxbuster --help + +# If you like it, install it permanently +soar install feroxbuster +``` + +### Run specific versions + +```sh +# Run Python 3.11 for a specific script +soar run python@3.11 script.py + +# Run Node.js 20 for a project +soar run node@20 --version +``` + +### Run from a specific repository + +```sh +# Run from the 'testing' repository +soar run --repo-name testing experimental-tool + +# Run with a specific package ID +soar run --pkg-id neovim@0.10.1 nvim --version +``` + +### One-off tasks + +```sh +# Run a security audit without installing tools permanently +soar run semgrep --config auto /path/to/code + +# Process a file with a specialized tool +soar run jq '.filter | map(select(.value > 10))' data.json +``` + +### Scripting with --yes + +```sh +#!/bin/bash +# Automated security scan +soar run --yes feroxbuster --url "$TARGET" --output scan-results.txt +soar run --yes nuclei -u "$TARGET" -severity critical +``` + +## Cleanup + +Run packages are stored in the cache directory and are not tracked in the installed packages database. To remove them: + +```sh +# Clean all cached run packages +soar clean --cache + +# Or manually remove specific packages from cache directory +rm ~/.local/share/soar/cache/bin/ +``` + +::: warning Run packages are not tracked by soar remove +Use `soar clean --cache` to remove cached run packages, or delete them manually from `~/.local/share/soar/cache/bin`. +::: + +## Tips and Best Practices + +1. **Use `--yes` in scripts** to avoid interactive prompts. +2. **Specify `--pkg-id`** when you need exact version control. +3. **Use `--repo-name`** to select packages from specific repositories. +4. **Pass `--help`** to see package-specific options: `soar run package --help`. +5. **Combine with shell features** for powerful one-liners. + +::: tip Create aliases for frequently-run packages +```sh +alias py311='soar run python@3.11' +alias node20='soar run node@20' +``` +::: diff --git a/docs/search.md b/docs/search.md new file mode 100644 index 00000000..067bfc4f --- /dev/null +++ b/docs/search.md @@ -0,0 +1,270 @@ +--- +title: Search Packages +description: Find packages with soar search and inspect them in detail with soar query, including aliases, filters, and query syntax. +--- + +# Search Packages + +Soar helps you find packages across all of your configured repositories and inspect any of them in detail. This guide covers the `search` command, its filters, and the `query` command for detailed package information. + +## Basic Search + +Search for packages with the `soar search` command: + +```sh +soar search +``` + +The `search` command is also available through shorter aliases: + +```sh +# Short alias +soar s + +# Find alias +soar find +``` + +For example, search for packages containing `bat`: + +```sh +soar search bat +``` + +A search checks for a partial match in `pkg_id`, `pkg_name`, `pkg`, and the target from `provides`. + +## Search Filters + +### Case-Sensitive Search + +Match the query with exact case: + +```sh +soar search --case-sensitive +``` + +For example: + +```sh +soar search Bat --case-sensitive +``` + +### Exact Match Search + +Match the full name only, with no partial matches: + +```sh +soar search --exact +``` + +For example: + +```sh +soar search bat --exact +``` + +### Result Limit + +Limit the number of results returned: + +```sh +soar search --limit +``` + +For example, return only the top 10 results: + +```sh +soar search editor --limit 10 +``` + +## Cross-Repository Search + +By default, Soar searches across all configured repositories, and results show which repository each package comes from: + +```sh +soar search bat +``` + +Results may include packages from multiple repositories: + +``` +bat#official:soarpkgs +bat#official:official +``` + +To search within a specific repository, use the repository syntax: + +```sh +soar search bat:official +``` + +## Reading Search Results + +Each result is prefixed with a status indicator. The Unicode form is used when `display.icons` is enabled, and the ASCII form otherwise. + +| Indicator | Meaning | +|-----------|---------| +| `[✓]` or `[+]` | Package is installed | +| `[○]` or `[-]` | Package is not installed | + +Example output: + +``` +[✓] bat#official:official (0.24.0) +[○] bat#official:soarpkgs (0.23.0) +[○] code#official:flathub (latest) +``` + +## Search Patterns + +### Partial Matching + +A query matches any package that contains the query string: + +```sh +# Matches any package containing "fire" +soar search fire + +# Matches any package containing "code" +soar search code +``` + +Example results for `soar search fire`: + +``` +[-] firefox#mozilla:official (122.0) +[-] firewall#system:official (latest) +[+] firefoxpwa#third-party:flathub (1.0) +``` + +### Searching by pkg_id + +Search by package ID family: + +```sh +soar search git.busybox.net +``` + +### Searching by Provides + +Search by alternative binary names: + +```sh +soar search batcat +``` + +This finds `bat` because it provides `batcat` as an alternative name. + +## Query Command + +The `query` command provides detailed information about a package: + +```sh +soar query + +# Short alias +soar Q +``` + +For example: + +```sh +soar query bat +``` + +### Query Syntax + +The `query` command supports a detailed syntax for specific lookups: + +```sh +soar query #@: +``` + +The components are: + +- `` is the package name (required) +- `#` is the package ID, used for disambiguation (optional) +- `@` is a version constraint (optional) +- `:` is the repository name (optional) + +### Query Output + +The query command returns the following fields: + +| Field | Description | +|-------|-------------| +| Name | Package name | +| Version | Current or latest version | +| Repository | Source repository | +| pkg_id | Package ID or family | +| Size | Package size on disk | +| Install Date | When the package was installed | +| Last Updated | Last update timestamp | +| Provides | Alternative binary names | +| Description | Package description | + +Example output: + +```sh +soar query bat + +Output: +Name: bat +Version: 0.24.0 +Repository: official +pkg_id: catlike.tools.bat.official +Size: 2.3 MiB +Install Date: 2025-01-15 +Last Updated: 2025-01-20 +Provides: batcat +Description: A cat clone with syntax highlighting and Git integration +``` + +## Tips for Effective Searching + +Begin with simple queries before adding filters: + +```sh +soar search editor +``` + +Use case sensitivity to disambiguate between similar names: + +```sh +soar search Bat --case-sensitive +``` + +Follow a search with `query` for detailed information: + +```sh +soar search bat +soar query bat +``` + +Limit results for popular terms to keep output readable: + +```sh +soar search tool --limit 10 +``` + +Search for known aliases that a package provides: + +```sh +soar search batcat +``` + +Scope the search to a repository when you know it: + +```sh +soar search bat:official +``` + +## Configuration + +Search behavior can be configured in Soar's configuration file. See [Configuration](./configuration.md) for details on default search repositories, search result ordering, case sensitivity defaults, and result limit defaults. + +## Related Commands + +- [Installing Packages](./install.md) +- [Removing Packages](./remove.md) +- [Updating Packages](./update.md) diff --git a/docs/update.md b/docs/update.md new file mode 100644 index 00000000..e40b1a2a --- /dev/null +++ b/docs/update.md @@ -0,0 +1,281 @@ +--- +title: Update Packages +description: Keep installed packages current with soar update, including options, version determination, and recovery behavior. +--- + +# Update Packages + +Soar keeps your installed packages current with a single command family. This guide covers every update operation, the available options, and how Soar determines and applies new versions. + +## Quick Start + +Update all installed packages to their latest versions: + +```sh +soar update +``` + +Update specific packages by name: + +```sh +soar update +``` + +For example, update `7z` and `bat` together: + +```sh +soar update 7z bat +``` + +## Update Options + +The `update` command supports the following options: + +| Option | Description | +|--------|-------------| +| `--ask` | Prompt for confirmation before updating each package | +| `--keep` | Keep the current version (only refresh metadata) | +| `--no-verify` | Skip checksum and signature verification | + +### Ask for Confirmation + +Use `--ask` to review each package before it is updated: + +```sh +soar update --ask +soar update --ask +``` + +Soar prompts for each package update so you can approve or skip it. + +### Keep Current Version + +Use `--keep` to refresh package metadata without moving to a newer version: + +```sh +soar update --keep +``` + +This updates the package database entry but maintains the currently installed version. It is useful for refreshing package information, re-verifying installations, and testing without version changes. + +### Skip Verification + +Use `--no-verify` to skip signature and checksum verification during updates: + +```sh +soar update --no-verify +``` + +::: danger Security risk +Skipping verification exposes you to potentially compromised updates. Only use it with sources you trust. +::: + +## Version Determination + +### Repository Packages + +For packages installed from repositories, Soar determines the latest version from the package database: + +```sh +soar update bat +``` + +This updates `bat` to the latest version available in the repository it was installed from. + +### Local Packages + +Packages installed from URLs retain their installation specifications. Updates check for newer versions at the same URL or based on version detection: + +```sh +soar update https://example.com/app.AppImage +``` + +## Profile Handling + +The update process respects the original installation profile. If a package was installed with a specific profile, updates maintain that profile setting. + +::: warning +The profile flag has no effect on package installation path. Updates use the profile that was active at the time of installation. +::: + +## Cross-Repository Update Behavior + +A package always updates from the same repository it was installed from. Even if a newer version exists in a different repository, Soar will not use it. + +::: warning +The update process ignores updates from any repository other than the one the package was installed from. +::: + +To switch a package to a different repository, remove it and add it again from the new source: + +```sh +# Remove from the original repository +soar remove bat + +# Install from the new repository +soar add bat:soarpkgs +``` + +Future updates then follow the new repository: + +```sh +# Installed from 'official', so only 'official' is checked for updates +soar update bat +``` + +## Update Behavior + +### What Happens During an Update + +When you update a package, Soar: + +1. Checks for newer versions in the source repository +2. Verifies signatures and checksums (unless `--no-verify` is used) +3. Downloads the new version +4. Backs up the current installation +5. Extracts the new version +6. Updates symlinks and database entries +7. Removes the old version (if successful) + +If installation fails at any step, soar restores the previous version from the backup, as described below. + +### Backup and Recovery + +Soar maintains a backup during each update. If an update fails, the previous version remains intact: + +```sh +soar update bat +``` + +### Batch Updates + +Update multiple packages in one command, optionally with confirmation: + +```sh +soar update bat ripgrep fd +soar update --ask bat ripgrep fd +``` + +## Best Practices + +Keep packages up to date for security fixes and new features: + +```sh +soar update +``` + +Review updates before they apply with `--ask`: + +```sh +soar update --ask +``` + +Verify package sources before updating: + +```sh +soar info +``` + +For critical applications, back up your data before updating: + +```sh +soar update --ask +``` + +Update specific packages when you are concerned about compatibility: + +```sh +soar update +``` + +## Scenarios + +### Update All Packages + +```sh +soar update +``` + +Updates all installed packages to their latest versions from their original repositories. + +### Update with Confirmation + +```sh +soar update --ask +``` + +Review each package update before proceeding. + +### Update a Specific Package + +```sh +soar update ripgrep +``` + +Updates only the `ripgrep` package. + +### Refresh Metadata Without Updating + +```sh +soar update --keep +``` + +Updates package metadata in the database without changing installed versions. + +### Move a Package to a Different Repository + +```sh +# Current setup uses the 'official' repository +soar remove bat + +# Switch to the 'soarpkgs' repository +soar add bat:soarpkgs + +# Future updates use 'soarpkgs' +soar update bat +``` + +## Troubleshooting + +### Update Fails with a Signature Error + +Verify the package source is trusted, and only skip verification when you are certain: + +```sh +soar info +soar update --no-verify # Only if the source is trusted +``` + +### Update Is Stuck or Slow + +Check your network connection and repository status: + +```sh +soar sync +soar update +``` + +### Version Did Not Change + +Confirm the package actually has a newer version available: + +```sh +soar query +``` + +### Cannot Update from a Different Repository + +This is by design. Remove the package and reinstall it from the new repository: + +```sh +soar remove +soar add : +``` + +For more help, see [Health Check](./health.md). + +## Related Commands + +- [Installing Packages](./install.md) +- [Removing Packages](./remove.md) +- [Searching Packages](./search.md) diff --git a/docs/use.md b/docs/use.md new file mode 100644 index 00000000..8b726115 --- /dev/null +++ b/docs/use.md @@ -0,0 +1,296 @@ +--- +title: Use a Package Variant +description: Switch between installed variants of the same package without uninstalling any of them. +--- + +# Use Package From Different Family + +Soar lets you switch between different variants of an installed package without uninstalling any of them. This is useful when you need to move between versions, implementations, or repository sources of the same package. + +## Understanding Package Families + +A **package family** is the set of installed variants that share the same package name. These variants can differ in several ways. + +| Variant Type | Example | Description | +|--------------|---------|-------------| +| **Version** | `python@3.11` vs `python@3.12` | Different versions of the same package | +| **Implementation** | `cat` (GNU) vs `cat` (BusyBox) | Different implementations providing the same binary | +| **Repository** | `neovim` from `main` vs `testing` | Same package from different repositories | +| **Package ID** | `coreutils` vs `coreutils-ucr` | Different package IDs providing similar functionality | + +### Example Package Families + +``` +Package: python +├── python#python@3.11 (from main repo) +├── python#python@3.12 (from main repo) +└── python#pypy@3.11 (from testing repo) + +Package: cat +├── cat#coreutils@9.5 (provides: cat, ls, etc.) +├── cat#busybox@1.36 (provides: cat, ls, etc.) +└── cat#uutils-coreutils@0.0.23 (provides: cat, ls, etc.) +``` + +## When to Switch Packages + +Common reasons to switch between variants include the following. + +1. **Version testing** + ```sh + # Switch to Python 3.12 to test new features + soar use python + # Select python@3.12 from the list + python --version + ``` + +2. **Compatibility requirements** + ```sh + # Switch to older Node.js for a legacy project + soar use node + # Select node@18 from the list + ``` + +3. **Alternative implementations** + ```sh + # Switch to BusyBox variants for embedded systems + soar use cat + # Select busybox@1.36 for smaller footprint + ``` + +4. **Testing repository versions** + ```sh + # Try a package from the testing repository + soar use neovim + # Select neovim from testing repo + ``` + +## How the Use Command Works + +When you run `soar use `, soar: + +1. Checks whether multiple variants are installed. If only one is installed, there is nothing to switch and soar exits. +2. Displays the installed variants and prompts you to select one. +3. Overwrites the primary binary symlink to point at the selected variant. +4. Overwrites every provides symlink (for example `cat`, `ls`, `chmod`). +5. Marks the selected variant active in the database and the others inactive. + +The steps below walk through the interactive selection. + +### Step 1: List installed variants + +When you run `soar use `, Soar displays all installed variants. + +```sh +$ soar use python + +[1] python#python:3.11.5-main (15MB) * +[2] python#python:3.12.0-main (16MB) +[3] python#pypy:3.11.0-testing (12MB) + +Select a variant [1-3]: +``` + +### Step 2: Select a variant + +Select the number corresponding to your desired variant. Soar then does the following. + +1. **Overwrites symlinks** for the package and its `provides` entries. Existing symlinks are replaced, not removed separately. +2. **Marks the selected variant as active** in the database. +3. **Marks other variants as inactive.** They remain installed but unlinked. + +### Step 3: Verify the switch + +```sh +$ python --version +Python 3.12.0 +``` + +## Command Syntax + +```sh +soar use +``` + +- ``: the **base package name only**, for example `python`, `cat`, or `node`. + - Do not use version suffixes. Use `python`, not `python@3.12`. + - Do not use pkg_id prefixes. Use `python`, not `python#pypy`. +- No additional flags or options are supported. +- The command is interactive when multiple variants are installed. +- If only one variant is installed, the command exits without prompting because there is nothing to switch. + +## What Gets Switched + +When you switch packages, Soar manages both the primary binary and every binary the package provides. + +### Primary binary + +The main binary name: + +```sh +# Switching 'python' affects: +~/.local/share/soar/bin/python -> /path/to/python@3.12/bin/python +``` + +### Provided binaries + +All binaries listed in the package's `provides` field: + +```sh +# Switching 'coreutils' affects all its provides: +~/.local/share/soar/bin/cat -> /path/to/coreutils/bin/cat +~/.local/share/soar/bin/ls -> /path/to/coreutils/bin/ls +~/.local/share/soar/bin/chmod -> /path/to/coreutils/bin/chmod +# ... and more +``` + +::: warning Switching affects every provided binary +Switching a package affects ALL binaries it provides. If you switch `coreutils`, you switch `cat`, `ls`, `chmod`, and all other core utilities simultaneously. +::: + +## Practical Examples + +### Python version management + +```sh +soar install python@3.11 python@3.12 +soar use python # Select python@3.12 +python --version # Python 3.12.0 +``` + +### Alternative implementations + +```sh +soar install coreutils uutils-coreutils +soar use cat # Select uutils-coreutils +ls --version # uutils-coreutils 0.0.23 +``` + +## Managing Multiple Variants + +### Viewing all installed variants + +To see all installed packages and their variants: + +```sh +soar info + +# Output: +# Installed packages: +# python@3.11.5 (main) +# python@3.12.0 (main) +# node@18.0.0 (main) +# node@20.0.0 (main) +# coreutils@9.5 (main) +# busybox@1.36 (main) +``` + +### Removing unwanted variants + +If you no longer need a variant: + +```sh +# Remove a specific variant +soar remove python@3.11 + +# Remove all variants +soar remove --all python +``` + +## Limitations and Considerations + +### Must be installed first + +You can only switch between installed variants. If no variants are installed: + +```sh +$ soar use python +Package is not installed +``` + +The command displays this message and exits gracefully with no error code. + +### No automatic rollback + +There is no automatic undo. You must manually switch back: + +```sh +soar use python +# Select different variant +``` + +### Affects all provides + +Switching affects all binaries the package provides: + +```sh +soar use coreutils +# This switches cat, ls, chmod, mkdir, etc. all at once +``` + +## Best Practices + +- **Install multiple versions** that you might need for development. +- **Document requirements** by noting required versions in the project README. +- **Use profiles** for different project requirements. +- **Test first** with `soar run` before switching in production. + +## Comparison with Other Tools + +| Feature | `soar use` | `update-alternatives` | `nvm` | `pyenv` | +|---------|-----------|----------------------|-------|---------| +| **Multiple Versions** | ✅ | ✅ | ✅ | ✅ | +| **Package Agnostic** | ✅ | ✅ | ❌ | ❌ | +| **Repository Support** | ✅ | ❌ | ❌ | ❌ | + +## Troubleshooting + +### Command not found after switch + +```sh +soar use python +python: command not found +``` + +This means Soar's bin directory is not in your PATH. Add it permanently: + +```sh +# Add to your ~/.bashrc, ~/.zshrc, or equivalent +export PATH="$HOME/.local/share/soar/bin:$PATH" +``` + +Then reload your shell: + +```sh +source ~/.bashrc # or source ~/.zshrc +``` + +### Old version still showing + +```sh +soar use python +python --version # Still shows old version +``` + +Check for cached paths: + +```sh +hash -r # Clear command hash table +python --version # Should show new version +``` + +### No variants listed + +If you do not see any variants when running `soar use`: + +```sh +$ soar use python +Package is not installed +``` + +Install at least one variant of the package first: + +```sh +soar install python +soar use python # Now shows installed variants +```