Lockfile
Lockfile Format
Section titled “Lockfile Format”The lockfile records the state of all installed packages at a given scope. It enables deterministic environment reproduction and team sharing.
Location
Section titled “Location”| Scope | Lockfile Path |
|---|---|
| User | ~/.ccpkg/ccpkg-lock.json |
| Project | {project-root}/.ccpkg/ccpkg-lock.json |
Schema
Section titled “Schema”{ "lockfile_version": 1, "packages": { "api-testing": { "version": "1.0.0", "spec_version": "2026-02-14", "checksum": "sha256:a1b2c3d4...", "installed_at": "2026-02-14T12:00:00Z", "scope": "project", "source": "https://example.com/api-testing-1.0.0.ccpkg", "config_hash": "sha256:f7e8d9c0...", "linked": false, "generated_plugin_manifest": true, "host_registration_key": "api-testing@ccpkg", "installed_files": [ "plugin-manifest.json", "manifest.json", "skills/openapi-validator/SKILL.md", "skills/request-generator/SKILL.md", "commands/run-tests.md", "hooks/hooks.json", "mcp/.mcp.json" ], "merged_mcp_servers": ["api-testing-server"], "config_keys": ["API_BASE_URL", "API_KEY"], "components": { "skills": ["skills/openapi-validator", "skills/request-generator"], "commands": ["commands/run-tests.md"], "hooks": "hooks/hooks.json", "mcp": "mcp/.mcp.json" }, "remote_sources": { "skills/cloud-helper": { "url": "https://example.com/skills/cloud-helper/SKILL.md", "checksum": "sha256:b2c3d4e5...", "fetched_at": "2026-02-14T12:00:00Z", "cache_ttl": 86400 } } }, "my-dev-plugin": { "version": "0.1.0", "spec_version": "2026-02-14", "checksum": null, "installed_at": "2026-02-14T14:30:00Z", "scope": "user", "source": "link:/Users/me/Projects/my-dev-plugin", "config_hash": "sha256:e5d4c3b2...", "linked": true, "generated_plugin_manifest": true, "host_registration_key": "my-dev-plugin@ccpkg", "installed_files": [], "merged_mcp_servers": [], "config_keys": ["DEBUG_MODE"], "components": { "skills": ["skills/dev-helper"] } } }, "shared_mcp_servers": { "context7": { "origin": "command::npx -y @anthropic/context7-mcp", "version": "1.3.0", "declared_by": ["plugin-a", "plugin-b"], "active_source": "plugin-b", "dedup": true, "installed_at": "2026-02-15T12:00:00Z" } }}Lockfile fields:
| Field | Type | Description |
|---|---|---|
lockfile_version | number | The lockfile schema version. Currently 1. |
packages | object | Map of package name to install record. |
Install record fields:
| Field | Type | Description |
|---|---|---|
version | string | Installed package version. |
spec_version | string | The ccpkg spec version the package was built for. |
checksum | string | null | SHA-256 hash of the installed archive. null for linked packages. |
installed_at | string | ISO 8601 timestamp of installation. |
scope | string | Install scope ("user" or "project"). |
source | string | The URL or path from which the package was installed. Prefixed with link: for dev-mode linked packages (e.g., link:/Users/me/my-plugin). |
config_hash | string | SHA-256 hash of the resolved config values (excluding secrets). Used to detect config drift. |
linked | boolean | Whether this is a dev-linked package (symlink to source directory). |
generated_plugin_manifest | boolean | Whether the host plugin manifest was generated by ccpkg during install/link. Controls cleanup on uninstall/unlink — if true, the generated manifest is removed; if false, it is left in place. |
host_registration_key | string | The key written to the host’s registration system (e.g., "api-testing@ccpkg"). Used for clean deregistration on uninstall. |
installed_files | string[] | List of all files written during install, relative to the package directory. Enables deterministic uninstall. Empty for linked packages. |
merged_mcp_servers | string[] | MCP server names merged into the host’s .mcp.json during install. Superseded by shared_mcp_servers for dedup-aware uninstall tracking. Retained for packages that do not participate in dedup (single-server packages with no shared MCP servers). |
config_keys | string[] | Config variable names stored in the host’s settings. Used for clean removal on uninstall. |
components | object | Mirror of the manifest components object for quick reference. |
remote_sources | object | Map of component path to remote source metadata. Only present for packages with remote component references. Keys are component identifiers; values are objects with url, checksum, fetched_at, and cache_ttl. |
Remote source entry fields:
| Field | Type | Description |
|---|---|---|
url | string | The URL from which the component was fetched |
checksum | string | SHA-256 checksum of the fetched content |
fetched_at | string | ISO 8601 timestamp of last successful fetch |
cache_ttl | number | Cache duration in seconds from the manifest declaration |
Shared MCP server fields:
The shared_mcp_servers top-level field tracks MCP servers that are declared by multiple packages. Keys are MCP server key names.
| Field | Type | Description |
|---|---|---|
origin | string | Identity origin string derived from server mode (see Server Deduplication in Component Types). |
version | string | null | Resolved winning version. null if the server version cannot be determined. |
declared_by | string[] | Package names that bundle this server. |
active_source | string | Name of the package whose MCP template is currently rendered in the host config. |
dedup | boolean | Whether deduplication is active for this server. Defaults to true. When false, each package installs its own independent copy. |
installed_at | string | ISO 8601 timestamp of the last resolution event. |
- Project lockfiles (
{project-root}/.ccpkg/ccpkg-lock.json) SHOULD be committed to version control. This allows team members to reproduce the same package environment. - User lockfiles (
~/.ccpkg/ccpkg-lock.json) are personal and SHOULD NOT be shared. - An installer MAY provide a
ccpkg restorecommand that reads the lockfile and installs all listed packages at their recorded versions.
Remote Component References
Section titled “Remote Component References”Components declared in a manifest MAY reference remote sources instead of local archive paths. This enables lightweight distribution of individual components without requiring a full .ccpkg archive.
Remote Component Declaration
Section titled “Remote Component Declaration”A component path that begins with https:// is a remote reference. The installer MUST fetch the component from the URL and cache it locally before registration.
In the structured component form (see Components Object), a remote component uses the url field instead of path:
{ "components": { "skills": [ "skills/local-skill", { "url": "https://example.com/skills/remote-skill/SKILL.md", "checksum": "sha256:a1b2c3d4...", "cache_ttl": 86400 } ] }}Remote Component Fields
Section titled “Remote Component Fields”| Field | Required | Type | Description |
|---|---|---|---|
url | REQUIRED | string | HTTPS URL to the component file or directory |
checksum | REQUIRED | string | SHA-256 checksum of the remote content. Format: sha256:<hex> |
cache_ttl | OPTIONAL | number | Cache duration in seconds. Default: 86400 (24 hours). 0 means always fetch. |
hosts | OPTIONAL | string[] | Host scoping (same semantics as local components) |
Security Requirements
Section titled “Security Requirements”- URLs MUST use HTTPS (see Transport Security).
- The
checksumfield is REQUIRED. Installers MUST verify it after fetching and MUST reject mismatches. - Authors publishing at mutable URLs MUST update the checksum when remote content changes.
Caching
Section titled “Caching”Installers MUST cache fetched remote components locally. When the cache is valid (within cache_ttl), the installer MUST use the cached copy without network access. When the cache is expired, the installer SHOULD attempt to refresh and MUST fall back to the cached copy if the network is unavailable.
Lockfile Integration
Section titled “Lockfile Integration”Remote components are recorded in the lockfile with their resolved URL, checksum, and fetch timestamp. See Lockfile Format for the remote_sources field.
Direct URL Installation
Section titled “Direct URL Installation”An installer MAY support installing a single component directly from a URL without a manifest. The behavior and syntax are implementation concerns not specified here.