Commit 43cbb229f4359944ef3d106752f7ac004b2d6649

Commits
[COMMIT BEGIN]
commit 43cbb229f4359944ef3d106752f7ac004b2d6649
Author: 0x4248 <[email protected]>
Date:   Fri Mar 6 21:59:49 2026 +0000

    npkg: redo package system again

diff --git a/.gitignore b/.gitignore
index 9d37de3..2da91e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -63,9 +63,12 @@ COMMIT_MSG.old
 # C
 !*.c
 !*.h
+!*.C
+!*.H
 
 # C++
 !*.cpp
+!*.CPP
 !*.c++
 !*.hpp
 !*.h++
diff --git a/npkg-testing/README.md b/npkg-testing/README.md
index 2ea743a..8009e69 100644
--- a/npkg-testing/README.md
+++ b/npkg-testing/README.md
@@ -18,7 +18,7 @@ Code and package folders live directly here so development stays simple.
 
 ## Demo Package
 
-`bin/hello_world` builds a C binary and packages it as `/bin/hello-world`.
+`bin/hello_world` builds a C binary and packages it as `/usr/bin/hello-world`.
 
 ## Commands
 
@@ -28,11 +28,16 @@ From repository root:
 ./npkg list
 ./npkg installed
 ./npkg build hello-world
+./npkg package hello-world
 ./npkg install hello-world
-./npkg install-prebuilt --file ./npkg-build/packages/hello-world-0.1.0.tar.gz
+./npkg clean hello-world
 ./npkg uninstall hello-world
 ```
 
+`build` compiles package sources only.
+`package` creates `npkg-build/packages/<name>-<version>.tar.gz`.
+
+Default install root is `/opt/npkg`, so installs land under `/opt/npkg/usr/...`.
 If `/opt/npkg` is not writable for your user, run install/uninstall with `sudo`.
 
 To run as `npkg ...` directly, symlink once:
diff --git a/npkg-testing/bin/hello_python/Makefile b/npkg-testing/bin/hello_python/Makefile
new file mode 100644
index 0000000..73f85e7
--- /dev/null
+++ b/npkg-testing/bin/hello_python/Makefile
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-3.0
+
+BIN = hello-python
+DESTDIR ?=
+INSTALL_PATH ?= /usr/bin/
+
+.PHONY: all install clean
+
+all:
+	chmod +x $(BIN)
+
+install: all
+	install -d $(DESTDIR)$(INSTALL_PATH)
+	install -m 0755 $(BIN) $(DESTDIR)$(INSTALL_PATH)$(BIN)
+
+clean:
+	true
diff --git a/npkg-testing/bin/hello_python/npkg.conf b/npkg-testing/bin/hello_python/npkg.conf
new file mode 100644
index 0000000..4fe9e16
--- /dev/null
+++ b/npkg-testing/bin/hello_python/npkg.conf
@@ -0,0 +1,13 @@
+name = "hello-python"
+version = "0.1.0"
+description = "Tiny demo Python package that installs /usr/bin/hello-python"
+install_path = "/usr/bin/"
+
+[build]
+command = "make -C {package_dir} all"
+
+[package]
+command = "make -C {package_dir} install DESTDIR={stage_dir} INSTALL_PATH={install_path}"
+
+[clean]
+command = "make -C {package_dir} clean"
diff --git a/npkg-testing/bin/hello_world/Makefile b/npkg-testing/bin/hello_world/Makefile
index f674546..4d4fd08 100644
--- a/npkg-testing/bin/hello_world/Makefile
+++ b/npkg-testing/bin/hello_world/Makefile
@@ -6,8 +6,8 @@ CFLAGS ?= -O2 -Wall
 PKG_NAME = hello-world
 PKG_VERSION = 0.1.0
 
-PREFIX ?= /usr
 DESTDIR ?=
+INSTALL_PATH ?= /usr/bin/
 
 SRC = src/hello_world.c
 BUILD_DIR = build
@@ -22,8 +22,8 @@ $(BUILD_DIR)/$(BIN): $(SRC)
 	$(CC) $(CFLAGS) $(SRC) -o $(BUILD_DIR)/$(BIN)
 
 install: all
-	install -d $(DESTDIR)$(PREFIX)/bin
-	install -m 0755 $(BUILD_DIR)/$(BIN) $(DESTDIR)$(PREFIX)/bin/$(BIN)
+	install -d $(DESTDIR)$(INSTALL_PATH)
+	install -m 0755 $(BUILD_DIR)/$(BIN) $(DESTDIR)$(INSTALL_PATH)$(BIN)
 
 clean:
 	rm -rf $(BUILD_DIR)
diff --git a/npkg-testing/bin/hello_world/npkg.conf b/npkg-testing/bin/hello_world/npkg.conf
index 5412258..f60733f 100644
--- a/npkg-testing/bin/hello_world/npkg.conf
+++ b/npkg-testing/bin/hello_world/npkg.conf
@@ -1,16 +1,13 @@
 name = "hello-world"
 version = "0.1.0"
-description = "Tiny demo C package that installs /bin/hello-world"
+description = "Tiny demo C package that installs /usr/bin/hello-world"
+install_path = "/usr/bin/"
 
 [build]
 command = "make -C {package_dir} all"
 
-[stage]
-command = "make -C {package_dir} install DESTDIR={stage_dir} PREFIX={prefix}"
+[package]
+command = "make -C {package_dir} install DESTDIR={stage_dir} INSTALL_PATH={install_path}"
 
 [clean]
-command = "make -C {package_dir} clean"
-
-[capabilities]
-installable = true
-cleanable = true
\ No newline at end of file
+command = "make -C {package_dir} clean"
\ No newline at end of file
diff --git a/npkg-testing/npkg-build/README.md b/npkg-testing/npkg-build/README.md
deleted file mode 100644
index a382c82..0000000
--- a/npkg-testing/npkg-build/README.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# NPKG tools
-
-Package tooling lives here.
-
-Implementation modules are in `tools/npkg/*.py` and loaded by the root `./npkg` entrypoint.
-
-- `../npkg` - CLI entrypoint (`list`, `build`, `install`, `uninstall`)
-- `work/` - staging work dirs
-- `packages/` - built package archives
-
-## Quick start
-
-```bash
-./npkg list
-./npkg installed
-./npkg build hello-world
-./npkg install hello-world
-./npkg install-prebuilt --file ./npkg-build/packages/hello-world-0.1.0.tar.gz
-./npkg uninstall hello-world
-```
-
-Default install root is `/opt/npkg` and default prefix is `/` (so binaries land under `/opt/npkg/bin`, etc).
-If `/opt/npkg` is not writable for your user, run install/uninstall with `sudo`.
-
-## Package metadata
-
-Packages are discovered by scanning these directories for one metadata file per package directory:
-
-- `npkg.conf` (preferred)
-- `npkg.ini`
-- `npkg.toml` (compatibility)
-- `npkg.json` (legacy compatibility)
-
-If more than one metadata file exists in a package directory, `npkg` errors to avoid ambiguity.
-
-Scan roots:
-
-- `bin/`
-- `sbin/`
-- `toolkits/`
-- `lib/public/`
-- `lib/private/`
-- `lab/`
-- `systems/`
-
-Minimal `npkg.conf` example:
-
-```toml
-name = "hello-world"
-version = "0.1.0"
-description = "Tiny demo C package"
-
-[build]
-command = "make -C {package_dir} all"
-
-[stage]
-command = "make -C {package_dir} install DESTDIR={stage_dir} PREFIX={prefix}"
-
-[capabilities]
-installable = true
-```
-
-INI equivalent:
-
-```ini
-[package]
-name = hello-world
-version = 0.1.0
-description = Tiny demo C package
-
-[build]
-command = make -C {package_dir} all
-
-[stage]
-command = make -C {package_dir} install DESTDIR={stage_dir} PREFIX={prefix}
-
-[capabilities]
-installable = true
-```
-
-Notes:
-
-- Optional defaults:
-  - `name` defaults to folder name (with `_` converted to `-`)
-  - `version` defaults to `0.1.0`
-  - `description` defaults to empty
-  - `capabilities.installable` defaults to `true` if `stage.command` is set, else `false`
-- `build.command` remains optional.
-- `stage.command` is required only for installable packages.
diff --git a/npkg-testing/tools/npkg/archive.py b/npkg-testing/tools/npkg/archive.py
index 12c4dc6..88a34b6 100644
--- a/npkg-testing/tools/npkg/archive.py
+++ b/npkg-testing/tools/npkg/archive.py
@@ -1,4 +1,3 @@
-import re
 import shutil
 import subprocess
 import tarfile
@@ -16,6 +15,7 @@ def command_context(pkg: Package, stage_dir: Optional[Path] = None) -> Dict[str,
         "npkg_root": str(workspace_root()),
         "npkg_build_root": str(workspace_root() / "npkg-build"),
         "package_dir": str(pkg.package_dir),
+        "install_path": pkg.install_path,
     }
     if stage_dir is not None:
         context["stage_dir"] = str(stage_dir)
@@ -32,11 +32,9 @@ def run_shell(command: str, cwd: Path) -> None:
         raise RuntimeError(f"Command failed with exit code {result.returncode}: {command}")
 
 
-def ensure_package_archive(pkg: Package, prefix: str) -> Path:
-    if not pkg.installable:
-        raise RuntimeError(f"Package '{pkg.name}' is not installable")
-    if not pkg.stage_command:
-        raise RuntimeError(f"Package '{pkg.name}' does not define stage.command")
+def ensure_package_archive(pkg: Package) -> Path:
+    if not pkg.package_command:
+        raise RuntimeError(f"Package '{pkg.name}' does not define package.command")
 
     stage_dir = package_stage_dir(pkg)
     archive_path = package_archive_path(pkg)
@@ -45,11 +43,10 @@ def ensure_package_archive(pkg: Package, prefix: str) -> Path:
     stage_dir.mkdir(parents=True, exist_ok=True)
 
     context = command_context(pkg, stage_dir=stage_dir)
-    context["prefix"] = prefix
-    stage_command = render_command(pkg.stage_command, context)
+    package_command = render_command(pkg.package_command, context)
 
-    info(f"staging {pkg.name} with: {stage_command}")
-    run_shell(stage_command, cwd=workspace_root())
+    info(f"staging {pkg.name} with: {package_command}")
+    run_shell(package_command, cwd=workspace_root())
 
     archive_path.parent.mkdir(parents=True, exist_ok=True)
     with tarfile.open(archive_path, "w:gz") as tar:
@@ -71,19 +68,3 @@ def extract_archive_into_root(archive_path: Path, install_root: Path) -> List[st
     except (tarfile.TarError, OSError) as error:
         raise RuntimeError(f"failed to install archive: {error}") from error
     return member_names
-
-
-def infer_package_from_archive(archive_path: Path) -> tuple[str, str]:
-    base = archive_path.name
-    if base.endswith(".tar.gz"):
-        base = base[:-7]
-    elif base.endswith(".tgz"):
-        base = base[:-4]
-    else:
-        base = archive_path.stem
-
-    match = re.match(r"^(?P<name>.+)-(?P<version>\d+\.\d+\.\d+.*)$", base)
-    if match:
-        return match.group("name"), match.group("version")
-
-    return base, "prebuilt"
diff --git a/npkg-testing/tools/npkg/cli.py b/npkg-testing/tools/npkg/cli.py
index f472665..81d513c 100644
--- a/npkg-testing/tools/npkg/cli.py
+++ b/npkg-testing/tools/npkg/cli.py
@@ -2,10 +2,11 @@ import argparse
 
 from .commands import (
     cmd_build,
+    cmd_clean,
     cmd_install,
-    cmd_install_prebuilt,
     cmd_installed,
     cmd_list,
+    cmd_package,
     cmd_uninstall,
 )
 from .console import fail
@@ -14,15 +15,17 @@ from .console import fail
 def build_parser() -> argparse.ArgumentParser:
     parser = argparse.ArgumentParser(
         prog="npkg",
-        description="Nexus package helper",
+        description="Simple package helper for the Nexus monorepo",
         formatter_class=argparse.RawDescriptionHelpFormatter,
         epilog=(
             "Examples:\n"
             "  npkg list\n"
-            "  npkg installed\n"
             "  npkg build hello-world\n"
+            "  npkg build '*'\n"
+            "  npkg package hello-world\n"
             "  npkg install hello-world\n"
-            "  npkg install-prebuilt --file ./npkg-build/packages/hello-world-0.1.0.tar.gz\n"
+            "  npkg clean '*'\n"
+            "  npkg installed\n"
             "  npkg uninstall hello-world"
         ),
     )
@@ -32,18 +35,22 @@ def build_parser() -> argparse.ArgumentParser:
     list_parser = sub.add_parser("list", help="List available packages")
     list_parser.set_defaults(func=cmd_list)
 
-    installed_parser = sub.add_parser("installed", help="List installed packages from manifest database")
-    installed_parser.add_argument(
-        "--root",
-        default="/opt/npkg",
-        help="Installation root directory (default: /opt/npkg)",
+    build_parser = sub.add_parser("build", help="Build package(s) (supports wildcards)")
+    build_parser.add_argument(
+        "packages",
+        nargs="+",
+        help="Package selectors (name/path or wildcards like '*', 'hello-*', 'bin/*')",
     )
-    installed_parser.set_defaults(func=cmd_installed)
-
-    build_parser = sub.add_parser("build", help="Build a package")
-    build_parser.add_argument("package", help="Package name or package directory path")
     build_parser.set_defaults(func=cmd_build)
 
+    package_parser = sub.add_parser("package", help="Create package archive(s) (.tar.gz, supports wildcards)")
+    package_parser.add_argument(
+        "packages",
+        nargs="+",
+        help="Package selectors (name/path or wildcards like '*', 'hello-*', 'bin/*')",
+    )
+    package_parser.set_defaults(func=cmd_package)
+
     install_parser = sub.add_parser("install", help="Install a package")
     install_parser.add_argument("package", help="Package name or package directory path")
     install_parser.add_argument(
@@ -51,29 +58,23 @@ def build_parser() -> argparse.ArgumentParser:
         default="/opt/npkg",
         help="Installation root directory (default: /opt/npkg)",
     )
-    install_parser.add_argument(
-        "--prefix",
-        default="/",
-        help="Prefix passed to package stage command (default: /)",
-    )
     install_parser.set_defaults(func=cmd_install)
 
-    install_prebuilt_parser = sub.add_parser("install-prebuilt", help="Install from a prebuilt tarball")
-    install_prebuilt_parser.add_argument(
-        "--file",
-        required=True,
-        help="Path to .tar.gz or .tgz package archive",
-    )
-    install_prebuilt_parser.add_argument(
-        "--package",
-        help="Package name override (defaults to name inferred from archive filename)",
+    clean_parser = sub.add_parser("clean", help="Run package clean command (supports wildcards)")
+    clean_parser.add_argument(
+        "packages",
+        nargs="+",
+        help="Package selectors (name/path or wildcards like '*', 'hello-*', 'bin/*')",
     )
-    install_prebuilt_parser.add_argument(
+    clean_parser.set_defaults(func=cmd_clean)
+
+    installed_parser = sub.add_parser("installed", help="List installed packages from manifest database")
+    installed_parser.add_argument(
         "--root",
         default="/opt/npkg",
         help="Installation root directory (default: /opt/npkg)",
     )
-    install_prebuilt_parser.set_defaults(func=cmd_install_prebuilt)
+    installed_parser.set_defaults(func=cmd_installed)
 
     uninstall_parser = sub.add_parser("uninstall", help="Uninstall a package")
     uninstall_parser.add_argument("package", help="Package name")
diff --git a/npkg-testing/tools/npkg/commands.py b/npkg-testing/tools/npkg/commands.py
index dd09ed2..4b9d742 100644
--- a/npkg-testing/tools/npkg/commands.py
+++ b/npkg-testing/tools/npkg/commands.py
@@ -1,12 +1,59 @@
 from pathlib import Path
+import fnmatch
 
-from .archive import command_context, ensure_package_archive, extract_archive_into_root, infer_package_from_archive, render_command, run_shell
+from .archive import command_context, ensure_package_archive, extract_archive_into_root, render_command, run_shell
 from .console import fail, info, ok, style, warn
-from .install_db import load_installed_rows, uninstall_from_manifest, write_install_manifest, write_prebuilt_manifest
+from .install_db import load_installed_rows, uninstall_from_manifest, write_install_manifest
 from .metadata import discover_packages, select_package
 from .paths import workspace_root
 
 
+def resolve_package_selectors(packages, selectors):
+    root = workspace_root()
+    matched: list = []
+    seen = set()
+    had_selector_miss = False
+
+    for selector in selectors:
+        selector = selector.strip()
+        if not selector:
+            continue
+
+        wildcard = any(token in selector for token in "*?[")
+        local_matches = []
+
+        if wildcard:
+            for pkg in packages.values():
+                rel_dir = str(pkg.package_dir.relative_to(root))
+                if fnmatch.fnmatch(pkg.name, selector) or fnmatch.fnmatch(rel_dir, selector):
+                    local_matches.append(pkg)
+        else:
+            try:
+                local_matches.append(select_package(packages, selector))
+            except KeyError:
+                normalized_selector = selector.strip().strip("/")
+                for pkg in packages.values():
+                    rel_dir = str(pkg.package_dir.relative_to(root))
+                    if rel_dir == normalized_selector or rel_dir.startswith(f"{normalized_selector}/"):
+                        local_matches.append(pkg)
+
+        if not local_matches:
+            normalized_selector = selector.strip().strip("/")
+            selector_exists = (root / normalized_selector).exists() if normalized_selector else False
+            if wildcard or not selector_exists:
+                warn(f"no packages matched selector: {selector}")
+                had_selector_miss = True
+            continue
+
+        for pkg in local_matches:
+            if pkg.name in seen:
+                continue
+            seen.add(pkg.name)
+            matched.append(pkg)
+
+    return matched, had_selector_miss
+
+
 def cmd_list(_args) -> int:
     packages = discover_packages()
     print(style("NPKG packages", bold=True))
@@ -16,13 +63,14 @@ def cmd_list(_args) -> int:
 
     for pkg in packages.values():
         flags = []
-        flags.append("build" if pkg.build_command else "no-build")
-        if pkg.installable and pkg.stage_command:
+        if pkg.build_command:
+            flags.append("build")
+        if pkg.package_command:
             flags.append("install")
-        elif pkg.installable and not pkg.stage_command:
-            flags.append("no-stage")
-        else:
-            flags.append("build-only")
+        if pkg.clean_command:
+            flags.append("clean")
+        if not flags:
+            flags.append("meta-only")
 
         rel_dir = pkg.package_dir.relative_to(workspace_root())
         print(
@@ -37,26 +85,49 @@ def cmd_list(_args) -> int:
 
 def cmd_build(args) -> int:
     packages = discover_packages()
-    try:
-        pkg = select_package(packages, args.package)
-    except KeyError:
-        fail(f"package not found: {args.package}")
+    matched, had_selector_miss = resolve_package_selectors(packages, args.packages)
+    if not matched:
         return 2
 
-    if not pkg.build_command:
-        fail(f"package '{pkg.name}' does not define build.command")
+    had_failures = False
+    for pkg in matched:
+        if not pkg.build_command:
+            warn(f"skipping {pkg.name}: build.command is not defined")
+            had_failures = True
+            continue
+
+        command = render_command(pkg.build_command, command_context(pkg))
+        info(f"building {pkg.name} with: {command}")
+        try:
+            run_shell(command, cwd=workspace_root())
+        except RuntimeError as error:
+            warn(f"failed to build {pkg.name}: {error}")
+            had_failures = True
+            continue
+
+        ok(f"built {pkg.name}")
+
+    return 1 if (had_failures or had_selector_miss) else 0
+
+
+def cmd_package(args) -> int:
+    packages = discover_packages()
+    matched, had_selector_miss = resolve_package_selectors(packages, args.packages)
+    if not matched:
         return 2
 
-    command = render_command(pkg.build_command, command_context(pkg))
-    info(f"building {pkg.name} with: {command}")
-    try:
-        run_shell(command, cwd=workspace_root())
-    except RuntimeError as error:
-        fail(str(error))
-        return 1
+    had_failures = False
+    for pkg in matched:
+        try:
+            archive_path = ensure_package_archive(pkg)
+        except RuntimeError as error:
+            warn(f"failed to package {pkg.name}: {error}")
+            had_failures = True
+            continue
 
-    ok(f"built {pkg.name}")
-    return 0
+        ok(f"package archive ready: {archive_path}")
+
+    return 1 if (had_failures or had_selector_miss) else 0
 
 
 def cmd_install(args) -> int:
@@ -68,10 +139,8 @@ def cmd_install(args) -> int:
         return 2
 
     install_root = Path(args.root).expanduser().resolve()
-    prefix = args.prefix
-
     try:
-        archive_path = ensure_package_archive(pkg, prefix=prefix)
+        archive_path = ensure_package_archive(pkg)
     except RuntimeError as error:
         fail(str(error))
         return 2
@@ -85,45 +154,36 @@ def cmd_install(args) -> int:
         return 1
 
     write_install_manifest(pkg, install_root, member_names)
-
     ok(f"installed {pkg.name} -> {install_root}")
     return 0
 
 
-def cmd_install_prebuilt(args) -> int:
-    archive_path = Path(args.file).expanduser().resolve()
-    if not archive_path.exists() or not archive_path.is_file():
-        fail(f"archive not found: {archive_path}")
+def cmd_clean(args) -> int:
+    packages = discover_packages()
+    root = workspace_root()
+    matched, had_selector_miss = resolve_package_selectors(packages, args.packages)
+    if not matched:
         return 2
 
-    install_root = Path(args.root).expanduser().resolve()
-    install_root.mkdir(parents=True, exist_ok=True)
-
-    inferred_name, inferred_version = infer_package_from_archive(archive_path)
-    package_name = (args.package or inferred_name).strip()
-    package_version = inferred_version
-
-    if not package_name:
-        fail("unable to determine package name; pass --package")
-        return 2
+    had_failures = False
+    for pkg in matched:
+        if not pkg.clean_command:
+            warn(f"skipping {pkg.name}: clean.command is not defined")
+            had_failures = True
+            continue
 
-    info(f"installing prebuilt {package_name} from {archive_path} into {install_root}")
-    try:
-        member_names = extract_archive_into_root(archive_path, install_root)
-    except RuntimeError as error:
-        fail(str(error))
-        return 1
+        command = render_command(pkg.clean_command, command_context(pkg))
+        info(f"cleaning {pkg.name} with: {command}")
+        try:
+            run_shell(command, cwd=root)
+        except RuntimeError as error:
+            warn(f"failed to clean {pkg.name}: {error}")
+            had_failures = True
+            continue
 
-    write_prebuilt_manifest(
-        package_name=package_name,
-        version=package_version,
-        install_root=install_root,
-        members=member_names,
-        source_archive=archive_path,
-    )
+        ok(f"cleaned {pkg.name}")
 
-    ok(f"installed prebuilt {package_name} -> {install_root}")
-    return 0
+    return 1 if (had_failures or had_selector_miss) else 0
 
 
 def cmd_uninstall(args) -> int:
diff --git a/npkg-testing/tools/npkg/install_db.py b/npkg-testing/tools/npkg/install_db.py
index e9be84b..0434a7a 100644
--- a/npkg-testing/tools/npkg/install_db.py
+++ b/npkg-testing/tools/npkg/install_db.py
@@ -20,27 +20,6 @@ def write_install_manifest(pkg: Package, install_root: Path, members: List[str])
         json.dump(manifest, handle, indent=2)
 
 
-def write_prebuilt_manifest(
-    package_name: str,
-    version: str,
-    install_root: Path,
-    members: List[str],
-    source_archive: Path,
-) -> None:
-    db_dir = manifest_root(install_root)
-    db_dir.mkdir(parents=True, exist_ok=True)
-    manifest = {
-        "package": package_name,
-        "version": version,
-        "install_root": str(install_root),
-        "source_archive": str(source_archive),
-        "paths": members,
-    }
-    manifest_path = package_manifest_path(package_name, install_root)
-    with manifest_path.open("w", encoding="utf-8") as handle:
-        json.dump(manifest, handle, indent=2)
-
-
 def read_install_manifest(pkg_name: str, install_root: Path) -> Dict[str, Any]:
     manifest_path = package_manifest_path(pkg_name, install_root)
     if not manifest_path.exists():
diff --git a/npkg-testing/tools/npkg/metadata.py b/npkg-testing/tools/npkg/metadata.py
index f5cc75b..ed048cd 100644
--- a/npkg-testing/tools/npkg/metadata.py
+++ b/npkg-testing/tools/npkg/metadata.py
@@ -1,12 +1,10 @@
-import configparser
-import json
 import os
 from pathlib import Path
 from typing import Any, Dict, Optional
 
 try:
     import tomllib
-except ModuleNotFoundError:
+except ModuleNotFoundError:  # pragma: no cover
     tomllib = None
 
 from .paths import workspace_root
@@ -17,36 +15,14 @@ def normalize_command(raw: Optional[str]) -> Optional[str]:
     if raw is None:
         return None
     command = raw.strip()
-    if not command:
-        return None
-    return command
+    return command or None
 
 
 def as_dict(value: Any) -> Dict[str, Any]:
     return value if isinstance(value, dict) else {}
 
 
-def parse_bool(value: Any, default: bool) -> bool:
-    if value is None:
-        return default
-    if isinstance(value, bool):
-        return value
-    if isinstance(value, (int, float)):
-        return bool(value)
-    raw = str(value).strip().lower()
-    if raw in {"1", "true", "yes", "on"}:
-        return True
-    if raw in {"0", "false", "no", "off"}:
-        return False
-    return default
-
-
-def load_json_package(meta_path: Path) -> Dict[str, Any]:
-    with meta_path.open("r", encoding="utf-8") as handle:
-        return json.load(handle)
-
-
-def load_toml_package(meta_path: Path) -> Dict[str, Any]:
+def load_raw_package(meta_path: Path) -> Dict[str, Any]:
     if tomllib is None:
         raise ValueError("TOML metadata requires Python 3.11+ (tomllib not available)")
     with meta_path.open("rb") as handle:
@@ -56,61 +32,6 @@ def load_toml_package(meta_path: Path) -> Dict[str, Any]:
     return parsed
 
 
-def load_ini_package(meta_path: Path) -> Dict[str, Any]:
-    parser = configparser.ConfigParser()
-    parser.optionxform = str
-    read_ok = parser.read(meta_path, encoding="utf-8")
-    if not read_ok:
-        raise ValueError(f"Unable to read metadata: {meta_path}")
-
-    package: Dict[str, Any] = {}
-    build: Dict[str, Any] = {}
-    stage: Dict[str, Any] = {}
-    capabilities: Dict[str, Any] = {}
-
-    if parser.has_section("package"):
-        section = parser["package"]
-        package["name"] = section.get("name")
-        package["version"] = section.get("version")
-        package["description"] = section.get("description")
-
-    if parser.has_section("build"):
-        build["command"] = parser["build"].get("command")
-
-    if parser.has_section("stage"):
-        stage["command"] = parser["stage"].get("command")
-
-    if parser.has_section("capabilities"):
-        capabilities["installable"] = parser["capabilities"].get("installable")
-
-    package["build"] = build
-    package["stage"] = stage
-    package["capabilities"] = capabilities
-    return package
-
-
-def load_raw_package(meta_path: Path) -> Dict[str, Any]:
-    name = meta_path.name.lower()
-    suffix = meta_path.suffix.lower()
-    if name == "npkg.conf":
-        try:
-            data = load_toml_package(meta_path)
-        except ValueError:
-            data = load_ini_package(meta_path)
-    elif suffix == ".json":
-        data = load_json_package(meta_path)
-    elif suffix == ".toml":
-        data = load_toml_package(meta_path)
-    elif suffix == ".ini":
-        data = load_ini_package(meta_path)
-    else:
-        raise ValueError(f"Unsupported metadata format: {meta_path.name}")
-
-    if not isinstance(data, dict):
-        raise ValueError(f"Invalid metadata in {meta_path}: expected object/table")
-    return data
-
-
 def load_package(meta_path: Path) -> Package:
     data = load_raw_package(meta_path)
 
@@ -118,41 +39,33 @@ def load_package(meta_path: Path) -> Package:
     name = str(data.get("name") or default_name).strip()
     version = str(data.get("version") or "0.1.0").strip()
     description = str(data.get("description") or "").strip()
+    install_path = str(data.get("install_path") or "/usr/bin/").strip()
+
     build = as_dict(data.get("build", {}))
-    stage = as_dict(data.get("stage", {}))
-    capabilities = as_dict(data.get("capabilities", {}))
+    package_section = as_dict(data.get("package", {}))
+    clean = as_dict(data.get("clean", {}))
 
     if not name or not version:
         raise ValueError(f"Invalid metadata in {meta_path}: missing name/version")
 
-    build_command = normalize_command(build.get("command"))
-    stage_command = normalize_command(stage.get("command"))
-    installable_default = stage_command is not None
-    installable = parse_bool(capabilities.get("installable"), default=installable_default)
+    if install_path and not install_path.startswith("/"):
+        install_path = f"/{install_path}"
 
     return Package(
         name=name,
         version=version,
         description=description,
         package_dir=meta_path.parent,
-        build_command=build_command,
-        stage_command=stage_command,
-        installable=installable,
+        install_path=install_path,
+        build_command=normalize_command(build.get("command")),
+        package_command=normalize_command(package_section.get("command")),
+        clean_command=normalize_command(clean.get("command")),
     )
 
 
 def metadata_file_in_dir(package_dir: Path) -> Optional[Path]:
-    candidates = [
-        package_dir / "npkg.conf",
-        package_dir / "npkg.toml",
-        package_dir / "npkg.ini",
-        package_dir / "npkg.json",
-    ]
-    found = [path for path in candidates if path.exists()]
-    if len(found) > 1:
-        names = ", ".join(path.name for path in found)
-        raise ValueError(f"Multiple metadata files in {package_dir}: {names}")
-    return found[0] if found else None
+    meta = package_dir / "npkg.conf"
+    return meta if meta.exists() else None
 
 
 def discover_packages() -> Dict[str, Package]:
@@ -172,8 +85,7 @@ def discover_packages() -> Dict[str, Package]:
         if not top.exists():
             continue
         for dirpath, _, filenames in os.walk(top):
-            filename_set = set(filenames)
-            if not ({"npkg.conf", "npkg.toml", "npkg.ini", "npkg.json"} & filename_set):
+            if "npkg.conf" not in set(filenames):
                 continue
             package_dir = Path(dirpath)
             meta = metadata_file_in_dir(package_dir)
diff --git a/npkg-testing/tools/npkg/types.py b/npkg-testing/tools/npkg/types.py
index 3d31325..b43c8a2 100644
--- a/npkg-testing/tools/npkg/types.py
+++ b/npkg-testing/tools/npkg/types.py
@@ -9,6 +9,7 @@ class Package:
     version: str
     description: str
     package_dir: Path
+    install_path: str
     build_command: Optional[str]
-    stage_command: Optional[str]
-    installable: bool
+    package_command: Optional[str]
+    clean_command: Optional[str]
[COMMIT END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.