Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<a href="ls/docs/PLATFORM_REGISTRY.md"><img src="https://img.shields.io/badge/platforms-cursor%20%7C%20claude--code%20%7C%20codex%20%7C%20openclaw%20%7C%20kilo%20%7C%20opencode-1f6feb" alt="Supported platforms"></a>
</p>

**Version:** 4.44.2<br>
**Version:** 4.44.3<br>

**LocalSetup gives coding agents a repo-local operating layer.**

Expand All @@ -25,14 +25,15 @@ LocalSetup provides capability skills, executable workflow packages, explicit ad
Start with the [quickstart](ls/docs/QUICKSTART.md) or browse the [documentation](ls/docs/README.md). The [latest published release](https://github.com/CruxExperts/localsetup/releases/latest) provides release notes and downloads.

<!-- release-summary:start -->
## What's new in 4.44.2
## What's new in 4.44.3

LocalSetup 4.44.2 improves release-documentation completion capacity for maintainers and aligns the release arithmetic with the verified published 4.44.1 anchor. The 4.x major-line lock and historical release evidence remain in force.
LocalSetup 4.44.3 includes the approved release-documentation QC budget updates and corrects the framework version recorded and checked in CycloneDX SBOMs. Release SBOMs use the completed archive's VERSION; source and installed SBOMs use the repository VERSION when present and fall back to the installed framework distribution version when it is absent. It follows the published v4.44.1 baseline after two sequential patch slices; the pushed v4.44.2 tag and its draft assets remain unchanged and unpublished.

- **Longer release-docs QC sessions:** Preparation defaults to 800 completion calls and a 9,000-second (150-minute) whole-session budget. The hosted publish job allows 165 minutes total, with a 15-minute grace period; individual provider requests use a separate 180-second fallback timeout.
- **Corrected 4.x release arithmetic:** Published v4.44.1 was the first release under corrected arithmetic and is the baseline for this patch. The v5.6.2 and v4.22.9 tags and assets remain unchanged, and major-version increments remain locked.
- **Framework-versioned SBOMs:** Release SBOMs use the framework VERSION stored in the completed archive. Source and installed SBOMs use the repository VERSION when present and fall back to the installed distribution version when it is absent. `verify-release` rejects missing, malformed, or stale release SBOM application versions. The separate pack-format value in artifact metadata remains `3`.
- **Corrected 4.x release arithmetic:** v4.44.1 is the published baseline. Sequential patch arithmetic maps the QC and SBOM fixes to 4.44.2 and 4.44.3. The pushed v4.44.2 tag and its draft assets remain unchanged and unpublished; the 4.x major-line lock and historical release evidence remain in force.

See the [4.44.2 release guide](ls/docs/releases/4.44.2.md) for compatibility, updating, and verification.
See the [4.44.3 release guide](ls/docs/releases/4.44.3.md) for compatibility, updating, and verification.
<!-- release-summary:end -->

The [4.4.0 guide](ls/docs/releases/4.4.0.md) remains available as release history.
Expand Down Expand Up @@ -83,7 +84,7 @@ Start with the [workflow packages guide](ls/docs/WORKFLOW_PACKAGES.md) for usage
<!-- facts-block:start -->
| Fact | Value |
|---|---|
| Current version | `4.44.2` |
| Current version | `4.44.3` |
| Supported platforms | `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli` |
| Shipped skills | `105` |
| Workflow packages | `18` |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.44.2
4.44.3
4 changes: 2 additions & 2 deletions ls/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# LocalSetup Framework Engine

**Version:** 4.44.2<br>
**Version:** 4.44.3<br>

`ls/` is the engine that makes the public LocalSetup promise real. It stores the framework code, shipped skills, workflow packages, platform templates, docs, tests, and install manifests that turn a repository into a portable agent workspace.

Expand All @@ -26,7 +26,7 @@ For the public product overview, start with the [root README](../README.md). Thi
LocalSetup-managed entries in consuming repositories are install output. Adapter directories may also contain project-owned skills, files, and symlinks; preserve that content in place. See [adapter ownership](docs/ADAPTER_OWNERSHIP.md).

<!-- release-link:start -->
Read the [current release guide](docs/releases/4.44.2.md) for LocalSetup 4.44.2, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
Read the [current release guide](docs/releases/4.44.3.md) for LocalSetup 4.44.3, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
<!-- release-link:end -->

## Install flow
Expand Down
20 changes: 18 additions & 2 deletions ls/config/branding.json
Original file line number Diff line number Diff line change
Expand Up @@ -1307,11 +1307,11 @@
},
{
"path": "ls/core/package.py",
"line_sha256": "dba45bec4f8271be61ed1e7e8bee453380675b3ac3d0462b74b44f2c7b753d6b",
"line_sha256": "6b656a31bda137a48a392f5ed8377de3fb0c13faef997c7b95065502b8f04410",
"token": "localsetup",
"count": 1,
"kind": "compatibility_identifier",
"reason": "Established package/plugin ID, migration alias pattern, temporary-path prefix or protocol identifier at this source location; not a product display label."
"reason": "Stable internal installed SBOM component identifier; technical metadata rather than user-facing product text."
},
{
"path": "ls/core/package_surface.py",
Expand Down Expand Up @@ -4832,6 +4832,22 @@
"count": 3,
"kind": "compatibility_identifier",
"reason": "Launcher fixture checks the established framework command path."
},
{
"count": 1,
"kind": "compatibility_identifier",
"line_sha256": "3413ba2788cb308eb131957ea2433f1aa0b5e326c296a45527b2f7413ff308e2",
"path": "ls/tests/test_install_flow_docs_package_a.py",
"reason": "CycloneDX verification fixture uses the established pack ID to check metadata parsing; technical compatibility data rather than display text.",
"token": "localsetup"
},
{
"count": 1,
"kind": "compatibility_identifier",
"line_sha256": "5b562a0ad13ff0f7b9f6c9b2ebd04280f3742a7f27e55f5ff33ff36d4418b10c",
"path": "ls/tests/test_install_flow_package_version_provenance.py",
"reason": "Test supplies the canonical Python distribution key to exercise installed-version metadata lookup; technical compatibility data rather than display text.",
"token": "localsetup"
}
],
"visual_reviews": [
Expand Down
47 changes: 44 additions & 3 deletions ls/core/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@
from typing import Any

from .boundary import scan_tar_for_leaks
from .framework_version import framework_version
from .manifests import load_pack_config
from .paths import repo_path
from .source import source_commit, source_tag
from .versioning import read_version
from .versioning_models import SemVer
from .sdk_payload.integrity import verify as verify_sdk
from .sdk_payload.artifacts import inspect_artifact as inspect_sdk_artifact
from .sdk_payload.sbom import components as sdk_components


ARTIFACT_METADATA_PATH = "ls/artifact-metadata.json"
MAX_FRAMEWORK_VERSION_BYTES = 128


def _framework_version_for_repo(repo_root: Path) -> str:
if (repo_root / "VERSION").is_file():
return str(read_version(repo_root))
return framework_version()


def _load_toml(path: Path) -> dict[str, Any]:
Expand Down Expand Up @@ -111,6 +121,32 @@ def _components_for_sbom(repo_root: Path) -> list[dict[str, Any]]:
return result


def _framework_version_from_artifact(artifact_path: Path) -> str:
with tarfile.open(artifact_path, "r:*") as tar:
members = [member for member in tar.getmembers() if member.name == "VERSION"]
if not members:
raise ValueError("framework VERSION not found in artifact")
if len(members) != 1:
raise ValueError("artifact must contain exactly one framework VERSION entry")
member = members[0]
if not member.isfile():
raise ValueError("framework VERSION entry in artifact must be a regular file")
if member.size < 0 or member.size > MAX_FRAMEWORK_VERSION_BYTES:
raise ValueError(
f"framework VERSION entry exceeds the {MAX_FRAMEWORK_VERSION_BYTES}-byte limit"
)
handle = tar.extractfile(member)
if handle is None:
raise ValueError("framework VERSION could not be read from artifact")
data = handle.read(MAX_FRAMEWORK_VERSION_BYTES + 1)
if len(data) != member.size:
raise ValueError("framework VERSION entry is truncated in artifact")
try:
return str(SemVer.parse(data.decode("utf-8").strip()))
except (UnicodeDecodeError, ValueError) as exc:
raise ValueError(f"invalid framework VERSION in artifact: {exc}") from exc


def _expected_components_from_artifact(artifact_path: Path) -> list[dict[str, str]]:
with tarfile.open(artifact_path, "r:*") as tar:
try:
Expand Down Expand Up @@ -155,7 +191,7 @@ def write_cyclonedx_sbom(repo_root: Path, artifact_path: Path, metadata: dict[st
"component": {
"type": "application",
"name": metadata["pack_id"],
"version": str(metadata["version"]),
"version": _framework_version_from_artifact(artifact_path),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add VERSION to the existing SBOM fixture

When the full suite reaches test_public_sbom_checks_full_vendor_metadata_and_manifest_binding, that test constructs an archive containing only the vendored files and uv.lock, then calls write_cyclonedx_sbom; this new unconditional lookup therefore raises ValueError("framework VERSION not found in artifact") before the existing assertions. Add a valid VERSION member to that fixture so the required release-validation suite remains green.

AGENTS.md reference: AGENTS.md:L114-L118

Useful? React with 👍 / 👎.

"bom-ref": metadata["pack_id"],
},
"properties": [
Expand All @@ -175,7 +211,7 @@ def write_source_sbom(repo_root: Path, output_path: Path) -> dict[str, Any]:
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {"component": {"type": "application", "name": pack.pack_id, "version": str(pack.version)}},
"metadata": {"component": {"type": "application", "name": pack.pack_id, "version": _framework_version_for_repo(repo_root)}},
"components": _components_for_sbom(repo_root),
}
output_path.parent.mkdir(parents=True, exist_ok=True)
Expand All @@ -198,7 +234,7 @@ def write_installed_sbom(repo_root: Path, target_root: Path, output_path: Path)
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {"component": {"type": "application", "name": "localsetup-installed", "version": str(pack.version)}},
"metadata": {"component": {"type": "application", "name": "localsetup-installed", "version": _framework_version_for_repo(repo_root)}},
"components": components,
}
output_path.parent.mkdir(parents=True, exist_ok=True)
Expand Down Expand Up @@ -331,8 +367,10 @@ def verify_cyclonedx_sbom(sbom_path: Path, artifact_path: Path, metadata: dict[s
if isinstance(item, dict)
}
component = payload.get("metadata", {}).get("component", {})
component = component if isinstance(component, dict) else {}
components = payload.get("components", [])
try:
expected_framework_version = _framework_version_from_artifact(artifact_path)
expected_components = _expected_components_from_artifact(artifact_path)
sdk = inspect_sdk_artifact(artifact_path, required=False, expected_digest=metadata.get("sdk_manifest_sha256"))
vendored = sdk_components(sdk["manifest"]) if sdk else []
Expand All @@ -348,6 +386,7 @@ def verify_cyclonedx_sbom(sbom_path: Path, artifact_path: Path, metadata: dict[s
payload.get("specVersion") == "1.6",
isinstance(components, list),
component.get("name") == metadata.get("pack_id"),
component.get("version") == expected_framework_version,
properties.get("localsetup:artifact") == artifact_path.name,
properties.get("localsetup:source_commit") == metadata.get("source_commit"),
not missing,
Expand All @@ -361,6 +400,8 @@ def verify_cyclonedx_sbom(sbom_path: Path, artifact_path: Path, metadata: dict[s
"path": str(sbom_path),
"bomFormat": payload.get("bomFormat"),
"component": component.get("name"),
"component_version": component.get("version"),
"expected_framework_version": expected_framework_version,
"artifact": properties.get("localsetup:artifact"),
"source_commit": properties.get("localsetup:source_commit"),
"component_count": len(components) if isinstance(components, list) else None,
Expand Down
2 changes: 1 addition & 1 deletion ls/docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This is the full public capability catalog for LocalSetup. The [root README](../
## Generated Facts

<!-- facts-block:start -->
- Current version: `4.44.2`
- Current version: `4.44.3`
- Supported platforms: `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli`
- Shipped skills: `105`
- Workflow packages: `18`
Expand Down
4 changes: 2 additions & 2 deletions ls/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This is the public documentation map for LocalSetup. Start here when you want th
## Generated Facts

<!-- facts-block:start -->
- Current version: `4.44.2`
- Current version: `4.44.3`
- Supported platforms: `codex, claude-code, cursor, kilo, opencode, openclaw, github-copilot-cli, github-copilot-vscode, cline-cli, cline-vscode, amp-cli, goose-cli, pi-cli, hermes-agent, qwen-code-cli, kimi-cli, factory-droid, antigravity-app, gemini-cli, omp-cli`
- Shipped skills: `105`
- Workflow packages: `18`
Expand Down Expand Up @@ -51,7 +51,7 @@ This is the public documentation map for LocalSetup. Start here when you want th
| [Harness automation](HARNESS_AUTOMATION.md) | Opt-in heartbeat activation, typed LSCli profiles, reserved actions/controller accounting, runtime artifacts, cron gating and command-policy boundaries. |

<!-- release-link:start -->
Read the [current release guide](releases/4.44.2.md) for LocalSetup 4.44.2, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
Read the [current release guide](releases/4.44.3.md) for LocalSetup 4.44.3, including compatibility, updating, and verification. Find downloads in the [latest published release](https://github.com/CruxExperts/localsetup/releases/latest).
<!-- release-link:end -->

The [4.4.0 guide](releases/4.4.0.md) covers the earlier context and package consolidation.
Expand Down
6 changes: 3 additions & 3 deletions ls/docs/SKILLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ version: 4.44
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
source_provenance_hash: 6f5c26907e30347f7d8258fe7ff29b10992aca9cf0d71f73f979e3e7a1311b67
source_provenance_hash: d772a3cbe049ca55d4bdb809c8f6982b9250f0b64c5db8dce2f9a80def1ee5fe
emitter: generate-docs
framework_version: 4.44.2
source_commit: ac1e60dfd89c519b5b32cd32d4f4e0a3784000fe
framework_version: 4.44.3
source_commit: 213176b18d5683d0354d6de307692589e2879185
artifact_sha256: 73c1afab3e2ac3b53857cd025f86bd7ca57a0668c3093542ff2c9b4faf16ed88
---
# Shipped skills catalog
Expand Down
2 changes: 1 addition & 1 deletion ls/docs/VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LocalSetup uses the root `VERSION` file as the source of truth for the framework
## Current Version

- Source of truth: [`../../VERSION`](../../VERSION)
- Current value: `4.44.2`
- Current value: `4.44.3`
- Generated facts: [`_generated/facts.json`](_generated/facts.json)

## 4.x major-line lock and one-time numbering reconciliation
Expand Down
6 changes: 3 additions & 3 deletions ls/docs/WORKFLOW_QUICK_REF.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ version: 4.44
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
source_provenance_hash: 6f5c26907e30347f7d8258fe7ff29b10992aca9cf0d71f73f979e3e7a1311b67
source_provenance_hash: d772a3cbe049ca55d4bdb809c8f6982b9250f0b64c5db8dce2f9a80def1ee5fe
emitter: generate-docs
framework_version: 4.44.2
source_commit: ac1e60dfd89c519b5b32cd32d4f4e0a3784000fe
framework_version: 4.44.3
source_commit: 213176b18d5683d0354d6de307692589e2879185
artifact_sha256: 393552d58b8412c44afc9fbbd0aff0975a19010d587d5779e0346ef5ff2e05a7
---
# Workflow quick reference
Expand Down
6 changes: 3 additions & 3 deletions ls/docs/WORKFLOW_REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ version: 4.44
owner_package: generate-docs
localsetup_provenance:
schema_version: 1
source_provenance_hash: 6f5c26907e30347f7d8258fe7ff29b10992aca9cf0d71f73f979e3e7a1311b67
source_provenance_hash: d772a3cbe049ca55d4bdb809c8f6982b9250f0b64c5db8dce2f9a80def1ee5fe
emitter: generate-docs
framework_version: 4.44.2
source_commit: ac1e60dfd89c519b5b32cd32d4f4e0a3784000fe
framework_version: 4.44.3
source_commit: 213176b18d5683d0354d6de307692589e2879185
artifact_sha256: 0407568324660bae06808812eb701709399b3cff93d4d8903dddf688487a6745
---
# Workflow and module registry (LocalSetup)
Expand Down
Loading
Loading