jkunz 5465d2875c
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Canceled after 0s
Default (tags) / metadata (push) Canceled after 0s
v6.13.2
2026-09-11 09:36:56 +00:00
2024-06-21 19:48:43 +02:00
2026-09-11 09:36:56 +00:00
2026-09-11 09:36:56 +00:00
2024-06-21 19:48:43 +02:00
2024-06-21 19:48:43 +02:00
2024-06-21 19:48:43 +02:00
2026-09-11 09:36:56 +00:00

@git.zone/cli 🚀

@git.zone/cli is the development workflow CLI behind the gitzone and gzone commands. It helps TypeScript-heavy teams keep projects tidy, create semantic source commits, manage local Docker-backed services, scaffold new modules, and release software through explicit, target-based release configuration.

It is opinionated where that saves time: source commits and releases are separate, changelog entries flow through a standard Pending section, project config lives in .smartconfig.json, and release targets make side effects visible before they happen.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Install

pnpm add -g @git.zone/cli

After installation, both binaries point to the same CLI:

gitzone --help
gzone --help

The Big Idea

gitzone commit handles source history.

gitzone release handles release transactions.

That split is intentional. A commit should not unexpectedly publish npm packages, push Docker images, or trigger remote release pipelines. A release should clearly show which targets it will publish to.

Quick Start

# Preview project standardization work
gitzone format

# Apply formatting changes
gitzone format --write

# Create a semantic source commit
gitzone commit

# Preview the configured release transaction
gitzone release --plan

# Release pending changelog entries to configured targets
gitzone release

Commands

Command Purpose
commit Analyze changes and create one semantic source commit
release Turn pending changelog entries into a versioned release and publish targets
format Plan or apply project formatting and standardization
config Inspect, update, and migrate .smartconfig.json
services Manage local MongoDB, ObjectStorage, and Elasticsearch containers
tools Manage the global @git.zone toolchain
template Scaffold projects from built-in templates
meta Manage multi-repository workspaces
open Open repository assets like CI pages
docker Report and reclaim Docker resources created by git.zone tooling
deprecate Deprecate npm packages across registries
start Prepare an existing project for local work
helpers Run small helper utilities

Global flags include --help, --json, --plain, --agent, --no-interactive, and --no-check-updates.

Toolchain Management

gitzone tools replaces the former gtools command from @git.zone/tools. It manages globally installed @git.zone development tools through pnpm.

# Check installed @git.zone tools and update outdated packages
gitzone tools update

# Update without prompts
gitzone tools update -y

# Install missing managed @git.zone tools
gitzone tools install

gitzone tools update checks @git.zone/cli first. If the CLI itself needs an update, it updates @git.zone/cli and asks you to rerun the command before updating the rest of the toolchain.

Commit Workflow

gitzone commit creates one semantic source commit. It does not bump versions, create tags, publish packages, or push Docker images.

# Interactive semantic commit
gitzone commit

# Read-only AI recommendation
gitzone commit recommend --json

# Auto-accept safe recommendations
gitzone commit -y

# Auto-accept a breaking recommendation explicitly
gitzone commit -y --allow-breaking

# Auto-accept, test, build, and push
gitzone commit -ytbp

# Show the resolved workflow without mutating anything
gitzone commit --plan

# Supply a message and changelog entry without AI
gitzone commit -y --message 'fix(cache): expire stale entries' --changelog 'Expired entries are removed before lookup.'

# Preserve a multiline message and custom Pending Markdown
gitzone commit -y --message-file /tmp/commit.txt --changelog-file /tmp/pending.md

The commit flow:

  1. Analyze the working tree.
  2. Suggest commit type, scope, and message.
  3. Write a human-readable entry into changelog.md under ## Pending.
  4. Stage and create one semantic source commit.
  5. Optionally run formatting, tests, build, and push based on flags or config.

Commit flags:

Flag Meaning
-y, --yes Auto-accept safe recommendations
--allow-breaking Allow -y/--yes to accept BREAKING CHANGE recommendations
-t, --test Add test step
-b, --build Add build step
-p, --push Push after the source commit
-f, --format Run gitzone format --write before commit
--plan Show resolved workflow only
-m, --message <text> Use a complete semantic commit message without AI
--message-file <path> Read the complete message from a UTF-8 file
--changelog <text> Supply custom Pending text with a manual message
--changelog-file <path> Read custom Pending text from a UTF-8 file

Manual messages start with type(scope): description; the scope is optional. Conventional ! subjects and BREAKING CHANGE: footers are supported. The entire message, including its body, is passed literally to Git. File inputs preserve multiline text; CRLF becomes LF and terminal newlines are normalized. Each input is limited to 128 KiB. Use --message or --message-file once, and at most one changelog option. Changelog overrides require a manual message.

Without a changelog override, GitZone derives the Pending entry from the semantic subject and body. Custom text becomes an entry in the message's semantic bucket. For complete Markdown, supply a Pending fragment such as:

### Fixes

- Remove expired entries before lookup.
  - Preserve entries whose validity has not expired.

Fragments may contain ### Breaking Changes, ### Features, ### Fixes, ### Documentation, and ### Maintenance. Omit the document title, ## Pending, and version headings. GitZone merges entries into the existing Pending buckets and preserves previous entries and release history. Pending headings continue to determine the release bump; a breaking message requires a Breaking Changes entry, and either a breaking message or new breaking changelog text requires the usual interactive confirmation or -y --allow-breaking.

Manual mode replaces the AI analysis step with manual. It keeps the configured format, test, build, staging and push behavior. --plan validates and displays the message and changelog without mutation or AI access. A clean repository remains unchanged. Input is validated before workflow steps run; it never falls back to AI after an input error. Place input files outside the repository if they should not be included by the existing stage-all workflow.

-r is intentionally not part of commit anymore. Use gitzone release.

Release Workflow

gitzone release releases from main. Running it on another branch fails before release metadata or ref mutation unless the bare --merge flag is explicitly supplied.

--merge is intentionally strict: the source and existing main worktree must be clean, the source must be linearly rebased onto current remote main, and the Git target must push both the branch and tag. GitZone pins the single configured push URL, compare-and-swap fast-forwards local main, updates its verified worktree, and lease-pushes that exact source commit before creating release metadata. It rejects diverged or merged history, local replacement refs or grafts, stale worktrees, incomplete shallow history, changed destinations, and remote races. If the pre-release push fails, GitZone restores local main only when doing so cannot overwrite concurrent work. This plumbing-level integration intentionally does not run merge hooks or write ORIG_HEAD.

gitzone release performs the release core once, then publishes to configured targets. When Docker is active, its immutable candidate must qualify before any Git, npm, or OCI destination publication. An active Git target must then succeed and be verified before npm or OCI publication can start.

Before interactive confirmation or source mutation, a Docker release verifies the project-local tSDocker capabilities and validates the deterministic request against the source commit. After the release commit and configured build, GitZone validates the final request against the release commit immediately before atomically installing the schema-2 journal.

The release core is not configurable plumbing. It always follows the same professional release transaction:

  1. Verify the release branch, clean state, and main worktree ownership.
  2. Read changelog.md ## Pending entries and infer or accept a semver bump.
  3. Run configured tests.
  4. With --merge, fast-forward and lease-push main before release metadata is created.
  5. Update version files and baked commit info.
  6. Move pending changelog entries into the new version section.
  7. Create the local release commit and tag on main.
  8. Run the configured release build, require a clean tree, and revalidate the release checkout.
  9. When npm is selected, pack it once into an exact tarball.
  10. Atomically install a durable journal before final publication. Root npm releases use journal schema 1; Docker releases use schema 2; tspublish component releases use schema 3 in the same storage tree.
  11. For schema 2, run the project-local tSDocker qualification build and configured image tests, then durably record the candidate digest graph and complete ordered promotion set.
  12. Publish and verify Git, then each npm registry, then each Docker destination. Remove only the exact qualified candidate after every destination is verified, or after a terminal qualification destination conflict before Git/npm publication.

Targets decide what happens after that:

Target What it does
git Atomically pushes the exact main release commit and new tag, often triggering remote CI release builds
npm Publishes the same journaled tarball to every configured registry and verifies its bytes anonymously
docker Qualifies immutable OCI digest graphs with project-local tSDocker, promotes each journaled destination under single-writer alias fencing, verifies exact digests, then cleans the candidate; a terminal qualification conflict permits cleanup only
# Preview the resolved release plan
gitzone release --plan

# Release to configured targets
gitzone release

# From a clean feature branch already rebased onto current main
gitzone release --merge

# Release only to npm
gitzone release --target npm

# Remove npm and Docker from the resolved targets; Git remains only if configured
gitzone release --no-publish

# Override inferred semver level
gitzone release --minor

Release flags:

Flag Meaning
-y, --yes Run without interactive confirmation
-t, --test Enable preflight tests
-b, --build Enable the release build after local release metadata is created
-p, --push Explicitly select the git target; combine with other target flags as needed
--target <csv> Select git, giteaAssets, npm, and/or docker; npm cannot omit a configured enabled Gitea asset target
--npm Explicitly select the npm target; combine with other target flags as needed
--docker Explicitly select digest-qualified Docker publication; requires project-local @git.zone/tsdocker >= 3.5.1 with protocol v1
--no-publish Remove Gitea assets, npm and Docker from the resolved target set without implicitly enabling Git
--no-build Disable the separate post-metadata project build; Docker qualification still performs its required image build
--merge Fast-forward and lease-push a cleanly rebased feature branch into main, then release from main; incompatible with Docker or Gitea assets
--major, --minor, --patch Override inferred semver level
--plan Show the resolved workflow without fetching or mutating refs, files, the index, or worktrees
inspect [version] Read one or all durable release journals; add --json for machine-readable output
resume <version> Resume journaled Git, npm, qualification, promotion, or cleanup work; fresh-release overrides are rejected, and --json remains inspect-only
--recover-attempt <id> Recover the exact 32-character lowercase hexadecimal attempt.id shown by inspect --json, after independently proving its publisher stopped

Exact artifacts and release journals

Journal schema 1 supports Git and public npm publication. Schema 2 adds Docker qualification, promotion, and cleanup evidence without changing the storage path or schema-1 parsing and resume behavior. Fresh and resumed npm publication dynamically qualifies the active stable pnpm version; there is no version allowlist. GitZone reads minimum-release-age and minimum-release-age-exclude through that exact pnpm invocation in the release directory, so project configuration and global policy retain pnpm's normal precedence. It verifies the selected version's publication time through the configured registry unless the effective policy disables the age delay or excludes that version. Missing timestamps follow minimum-release-age-ignore-missing-time, including pnpm's default of true; malformed policy, metadata failures, immature versions, and prerelease versions stop qualification. GitZone also verifies the required pack/publish command contract and keeps every subsequent command bound to the qualified exact version. A new pnpm version with the same capabilities needs no GitZone update once it satisfies the policy. Registries must be unique canonical credential-free HTTP(S) URLs, and release.targets.npm.accessLevel must be public so verification does not depend on publisher credentials.

GitZone keeps the selected pnpm version for help checks, packing, and publication through pnpm with <version>, including release recovery and resume. This avoids mixing a launcher's help output with a project-selected package-manager version. Use a standalone pnpm installation; Corepack launchers cannot run pnpm with. The normal release-age policy also applies when pnpm provisions that version.

The pnpm release tests cover known command dialects and dynamic version qualification and qualify actual packaging and script-free tarball publication with the active version. Run testUnit with each maturity-eligible standalone version and a matching project pin in an isolated checkout. For a focused matrix, invoke the project-local tstest on test.pnpmrelease.node.ts from a disposable directory whose package.json pins that row. Do not wrap these invocations in another pnpm with: pnpm rejects nested use. Keep the normal release-age policy for every row.

For a repository's first release, run from clean local main against an empty remote. GitZone verifies that no remote refs exist, records Git's zero object ID as the expected absent main, and atomically creates main and the release tag with an exact absent-ref lease. Concurrent creation of main rejects the push. A nonempty remote missing main, an unreachable remote, and first-release --merge are rejected. The normal release journal retains this initial identity for inspect/resume if publication is interrupted.

A selected Git target requires a canonical remote name and exactly one resolved push URL. Before any remote contact, including during --plan, GitZone rejects HTTP(S) usernames or passwords, embedded passwords, query strings, fragments, and unsupported protocols. Canonical local paths and SSH destinations may retain their required SSH username.

Every release that reaches final publication stores journal.json under the repository's Git common directory. Root npm releases additionally run pnpm pack once and store the resulting package.tgz beside it. The v1 path names the storage format and contains all supported journal schemas:

<git-common-dir>/gitzone/releases/v1/v<version>/package.tgz
<git-common-dir>/gitzone/releases/v1/v<version>/journal.json

The canonical journal binds the release commit, annotated tag object, hashed Git destination, npm registries, per-target attempt states, and, when npm is selected, the package identity, tarball size, SHA-1, SHA-256, and SHA-512 integrity. Schema 2 also binds the exact tSDocker request, candidate identity, qualification result, ordered destination promotions, probe or promotion evidence, and terminal cleanup result. Journal updates use revision compare-and-swap under an interprocess lock. Release identity and destinations cannot change after journal creation. Qualification and promotion evidence is append-only, destination conflicts are terminal, and completed Docker state cannot regress. Inspect and resume reject malformed, future, noncanonical, duplicate-key, or merely reformatted journal JSON rather than repairing or normalizing it.

Packing must leave the release tree clean. Each registry receives that exact stored tarball through pnpm publish <tarball> --ignore-scripts, so publish lifecycle scripts do not run. Success is recorded only after anonymous no-redirect probes verify version metadata, SHA-1 and integrity fields, the downloaded tarball bytes, and the latest dist-tag. A matching pre-existing version follows release.targets.npm.alreadyPublished; conflicting bytes always stop the release, while transient responses and dist-tag propagation remain retryable.

Publishing independently installable components

Set release.targets.npm.packageSource to "tspublish" to release the named ts*/tspublish.json modules in one repository. The default "root" continues to publish the root package. A tspublish repository can use a private root manifest as the shared dependency/version catalog. Each module must declare "registries": ["useBase"]; GitZone owns the destinations and access settings. Explicit, empty, and extendBase module registry declarations are rejected.

{
  "@git.zone/cli": {
    "release": {
      "targets": {
        "npm": {
          "enabled": true,
          "packageSource": "tspublish",
          "registries": ["https://registry.npmjs.org"],
          "accessLevel": "public"
        }
      }
    }
  }
}

gitzone release --plan reads and validates the component plans and prints their dependency order. It does not build, prepare, or publish packages. The normal build must generate every component's compiled folders. GitZone then uses tspublish's prepare() API to isolate those outputs, packs each component once, and removes the disposable preparation directories.

Schema 3 records the ordered package set and every package/registry target. Each retained tarball uses the canonical filename package.<sha256-of-package-name>.tgz beside journal.json. Every package uses the release version, and sibling dependencies use that exact version. Git is published before any npm package. All stored hashes are checked before publication; completion requires every package at every registry to verify. If publication fails partway through, release resume <version> -y verifies the completed targets and continues using the retained tarballs. Resume never reruns component discovery, preparation, builds, or packing.

npm can hold accepted uploads for publish-time scanning before they become installable. Component releases submit the package set in dependency order, then wait for availability across the submitted set so scans can overlap. An accepted upload whose verification is pending retains the journal's failed / verification-inconclusive state; it is never reported as verified or sent again during resume. Command failures and artifact conflicts still stop submission immediately. Availability verification allows approximately 15 minutes per pending target, and a later resume can continue if a registry takes longer. Every package, tarball and latest tag must verify before the release is complete. Root npm and Docker release ordering is unchanged.

See npm's publish-time scanning announcement for the registry's availability behavior.

This component release mode supports Git and npm targets. A combined Docker target is rejected before release mutation. Root-package Docker releases continue to use schema 2.

Gitea release attachments before npm

Enable release.targets.giteaAssets when public source archives, native executables, or other versioned artifacts must be available before npm packages. This works with root packages and ordered tspublish modules. The Git branch and tag target must be active; integrate main before releasing. Docker and --merge cannot be combined with this target.

{
  "@git.zone/cli": {
    "release": {
      "targets": {
        "git": { "enabled": true, "remote": "origin", "pushBranch": true, "pushTags": true },
        "giteaAssets": {
          "enabled": true,
          "apiOrigin": "https://code.example.org",
          "owner": "example",
          "repository": "native-cli",
          "tokenEnv": "GITZONE_RELEASE_GITEA_TOKEN",
          "manifestPath": "dist/release-assets.json"
        },
        "npm": { "enabled": true, "registries": ["https://registry.npmjs.org"], "accessLevel": "public" }
      }
    }
  }
}

The configured HTTPS origin must match the resolved SSH/HTTPS Git host and exact owner/repository path. SSH aliases cannot establish that identity. tokenEnv is the environment variable's name; credentials are never stored in the journal. Before Git publication, authenticated and anonymous repository checks require a public repository, repository-admin authority, and a PAT with write:repository scope (or an existing all scope). Code-push permission alone is insufficient because Gitea grants code and release-unit permissions separately. Configure an existing appropriate credential; the CLI does not acquire or broaden tokens.

The normal release build generates a strict manifest for the new release version:

{
  "schemaVersion": 1,
  "version": "1.2.3",
  "assets": [
    { "name": "source.tar.gz", "path": "dist/source.tar.gz", "size": 12345, "sha256": "<64 lowercase hexadecimal characters>" },
    { "name": "native-linux-x64", "path": "dist/native-linux-x64", "size": 23456, "sha256": "<64 lowercase hexadecimal characters>" }
  ]
}

Replace the example sizes and hashes with the actual file identities. Names and paths must be canonical and unique. Regular files and their ancestor directories must not be symlinks; credential/runtime paths, traversal and globs are rejected. Assets are uploaded in manifest order. Put corresponding source and relinking materials before native executables, since public Gitea attachments also distribute those binaries.

Publication runs build → freeze every artifact → write schema-4 journal → Git → Gitea assets → npm. Stored assets use asset.<sha256-of-name>.bin filenames next to the retained npm archives. The CLI verifies local hashes before Git, then inspects or creates the exact public, non-draft, non-prerelease tag release. Every upload has a revisioned journal attempt. Each accepted attachment must download anonymously with the expected size and SHA256; authenticated redirects are rejected and anonymous downloads never carry the token. Transfers and hashing stream with bounded memory and timeouts.

The complete remote attachment set must equal the manifest. Extra names, duplicates, changed release identity, or conflicting bytes stop publication; the CLI has no deletion or replacement path. It verifies the complete set again before npm. An inconclusive or rejected upload leaves npm unpublished and retains the journal for gitzone release resume <version> -y. Resume uses the recorded destination and retained bytes without rebuilding or repacking, and re-verifies public assets even for completed journals. An unresolved active attempt requires the exact --recover-attempt identifier after its publisher has stopped.

Gitea's general attachment-enabled switch is checked. Its issue-attachment size setting is distinct from repository.release.FILE_MAX_SIZE; confirm the actual release and proxy upload limits for the largest planned artifact. A size rejection blocks npm and retains the original artifact; archives are never split or replaced automatically. The manifest and journal provide exact sizes for this check.

Artifact immutability here means conflict refusal by the publisher. Administrators can still change server state. Distributors must retain the exact public corresponding-source and relinking artifacts while distributing the binaries and include those artifacts in their operational retention and backup policy. Independent CI publishers must not rebuild, upload, delete, or publish these same release assets or packages; keep tag jobs limited to verification.

Independent tag-triggered npm publishers are incompatible with this transaction. GitZone rejects a release while .gitea/workflows/default_tags.yaml or .gitlab-ci.yml still contains the legacy npmci npm publish command. Apply the v6 Gitea workflow template or remove the legacy GitLab job and commit that change first.

Inspect and resume without regenerating release identity:

# List journals or inspect one exact version
gitzone release inspect
gitzone release inspect 6.0.0 --json

# Reconcile remote state, then continue only unfinished targets
gitzone release resume 6.0.0 -y

# Only after proving the recorded publisher process has stopped
gitzone release resume 6.0.0 -y --recover-attempt="$ATTEMPT_ID"

Resume requires the local main commit, annotated release tag, and each journaled destination setting to remain exact. The Git remote must still match when Git is journaled; npm registry, access, and already-published settings must still match when npm is journaled. Before any recovery or publication work, a nonterminal schema-2 resume canonical-compares the current Docker request with the journal, verifies every required project-local tSDocker protocol capability, and validates the journaled request; additive future capabilities are accepted. A completed schema-2 journal trusts its terminal cleanup evidence and does not require candidate state or current Docker configuration. Non-journaled target configuration is ignored, so releases created with a target subset remain resumable. Fresh-release overrides such as targets, integration, build, test, and version flags are rejected even in negated forms such as --no-git, --no-publish, and --no-build; JSON output is available only through inspect --json.

Resume probes remotely observable targets before acting. Exact state is accepted without republishing; positive byte, metadata, ref, or digest conflicts fail closed, while inconclusive results do not overwrite a previously verified state. A Git, npm, Docker qualification, promotion, or cleanup target left in publishing state retains authority until the exact recorded 32-character lowercase hexadecimal attempt.id is supplied after independently proving its publisher stopped. An interrupted tSDocker preparing record has no qualification evidence and cannot be promoted; when tSDocker reports RECOVERY_REQUIRED, the exact recovered qualification owner removes only that incomplete deterministic preparation before claiming a fresh qualification attempt. Promotion recovery first reclaims the retired owner's request files and probes the journaled destination; an exact qualified digest is accepted, pending state retires the old attempt and claims a fresh owner before retry, an inconclusive probe retains the old journal owner, and conflicts halt permanently. Final cleanup of a qualified candidate starts only after every promotion is verified and is itself idempotently recoverable. A terminal qualification destination conflict has no promotions, blocks Git/npm, and permits only exact qualified-candidate cleanup.

Schema 1 resumes final Git release-ref and npm publication after the journal is atomically installed. Schema 2 additionally resumes Docker qualification, ordered promotion, and cleanup. Schema 3 resumes the complete npm package set. --merge remains available only for non-Docker releases because its pre-release Git push would violate qualification-before-publication ordering.

For a Git release with root npm and/or Docker targets whose local release commit and annotated tag already exist, but whose build or pack failed before journal installation, use:

gitzone release recover 6.0.0 --plan
gitzone release recover 6.0.0 -y

Recovery supports configured Git with root npm and/or Docker targets. It requires clean main, the exact annotated tag at that commit, matching package and completed changelog versions, and no pending changes. The metadata commit must not change release configuration. It also checks remote ancestry, requires the release tag to be absent remotely, and requires an anonymous HTTP 404 for the version at every npm registry when npm is selected. Published or uncertain Git/npm state cannot be adopted without its original journal. Tspublish and Gitea asset preparation recovery are not supported.

The first attempt records the exact refs, destination and resolved workflow under the common Git directory in gitzone/releases/v1/v<version>.preparation.json. For Docker, this binding also includes the exact canonical qualification request. Retries must match that binding. Recovery creates a disposable detached worktree from the tagged commit, runs pnpm install --frozen-lockfile, and runs the configured tests and build before packing. Ignored runtime data and local project secrets are not copied. A build that depends on those files must be made reproducible through the project's normal configuration before it can recover.

Prepared npm artifacts are installed through the normal journal API. Docker recovery verifies the project-local tSDocker capabilities and configuration before preparation and validates again before installing a schema-2 journal. Its complete qualification, including a fresh build and configured image tests, runs from the unchanged canonical checkout before Git or npm publication. Candidate state stays at that stable project identity for later resume; images from the disposable preflight build are not adopted. Docker destinations retain the normal qualified digest, observed alias predecessor, probe and conflict checks.

Recovery never creates another version or moves refs. Once the journal exists, another recover call uses resume without repeating preparation. Any unfinished Docker qualification remains part of the normal resume workflow. Use resume --recover-attempt for an interrupted publisher that still owns a journaled attempt, after proving that process stopped.

Concurrent preparations are excluded by v<version>.prepare.lock. A process crash can leave that lock behind; inspect its owner and prove the process has stopped before manually removing that specific lock. Failed build or pack attempts retain their preparation binding and remove only their disposable worktree. --plan validates and describes the local identity without installing dependencies, building, fetching, writing a binding, or publishing; it does not certify registry absence. When the current remote commit is unavailable locally, the plan reports deferred ancestry; execution fetches and verifies that history before writing the preparation binding. Earlier version, changelog, commit or tag failures still require explicit operator reconciliation.

Standard Changelog

The changelog is convention-based and intentionally not configured.

gitzone commit appends entries to:

## Pending

gitzone release moves those pending entries into a dated version section:

## 2026-05-10 - 2.15.0

The standard buckets are Breaking Changes, Features, Fixes, Documentation, and Maintenance.

Configuration

CLI workflow config lives under @git.zone/cli in .smartconfig.json. Docker release selection lives under @git.zone/cli.release.targets.docker; canonical registries, repository mappings, and platforms remain owned by @git.zone/tsdocker.

{
  "@git.zone/cli": {
    "schemaVersion": 2,
    "projectType": "npm",
    "commit": {
      "confirmation": "prompt",
      "steps": ["analyze", "test", "build", "changelog", "commit", "push"]
    },
    "release": {
      "confirmation": "prompt",
      "preflight": {
        "test": false,
        "build": true
      },
      "targets": {
        "git": {
          "enabled": true,
          "remote": "origin",
          "pushBranch": true,
          "pushTags": true
        },
        "npm": {
          "enabled": true,
          "registries": ["https://registry.npmjs.org"],
          "accessLevel": "public",
          "alreadyPublished": "success"
        },
        "docker": {
          "enabled": false,
          "engine": "tsdocker",
          "registry": "registry.gitlab.com",
          "buildRegistries": ["registry.gitlab.com"],
          "test": true,
          "patterns": [],
          "cached": true,
          "parallel": true
        }
      }
    }
  },
  "@git.zone/tsdocker": {
    "registries": ["registry.gitlab.com"],
    "registryRepoMap": {
      "registry.gitlab.com": "myorg/myproject"
    },
    "platforms": ["linux/amd64", "linux/arm64"]
  }
}

NPM registries belong only here:

@git.zone/cli.release.targets.npm.registries

Canonical Docker destinations and repository mappings belong here. Registry values should be hosts without http:// or https://:

@git.zone/tsdocker.registries

Docker release configuration uses the project's absolute project-local node_modules/.bin/tsdocker. Install tSDocker 3.5.1 or newer in each Docker-producing project; fresh release and nonterminal resume verify matching package and binary versions plus the required protocol-v1 capabilities before use. Additional future protocol capabilities are accepted:

pnpm add --save-dev @git.zone/tsdocker@3.5.2

release.targets.docker.registry, buildRegistries, test, patterns, cached, parallel, and context become part of the immutable qualification request. noBuild must remain false or absent because digest qualification always builds. The separate release --no-build flag only disables the normal project build step and does not bypass Docker qualification.

Useful config commands:

# Show current @git.zone/cli config
gitzone config show --json

# Configure project basics, CLI behavior, and release targets interactively
gitzone config project
gitzone config cli
gitzone config release

# Validate schema, legacy keys, release targets, registries, and npm auth
gitzone config doctor

# Use opencode to repair configuration issues found by doctor
gitzone config fix

# Read the npm release target registries
gitzone config get release.targets.npm.registries

# Add an npm release target registry
gitzone config add https://registry.npmjs.org

# Set npm target access level
gitzone config access public

# Run schema migration to v2
gitzone config migrate 2

Managed Assets

Projects can opt into generated, updateable repository assets through @git.zone/cli.assets. The first supported kind is denoBinaryCli, which manages installer scripts, npm binary wrappers, postinstall downloaders, and Gitea release workflows for Deno-compiled CLI binaries.

{
  "@git.zone/cli": {
    "schemaVersion": 2,
    "assets": {
      "schemaVersion": 1,
      "kind": "denoBinaryCli",
      "cliName": "onebox",
      "displayName": "Onebox",
      "repository": {
        "host": "code.foss.global",
        "path": "serve.zone/onebox",
        "branch": "main"
      },
      "installer": {
        "enabled": true,
        "installDir": "/opt/onebox",
        "binDir": "/usr/local/bin",
        "modes": {
          "default": "binary",
          "source": {
            "enabled": true,
            "commands": ["pnpm install --frozen-lockfile", "pnpm run build"],
            "executable": "cli.js",
            "executableFiles": ["cli.js", "cli.ts.js", "cli.child.js"],
            "validate": "node cli.js --version"
          }
        },
        "service": {
          "detectNames": ["onebox"],
          "refreshCommand": "onebox systemd enable",
          "startHint": "onebox systemd start"
        },
        "ensureDirs": ["/var/lib/onebox", "/var/www/certbot"],
        "preservePaths": ["/var/lib/onebox"]
      },
      "npmWrapper": {
        "enabled": false
      },
      "releaseWorkflow": {
        "compileCommand": "pnpm run build:binary",
        "packNpmArtifact": true,
        "assetGlobs": ["dist/binaries/*", "dist/package/*"]
      }
    }
  },
  "@git.zone/tsdeno": {
    "compileTargets": [
      {
        "name": "onebox-linux-x64",
        "entryPoint": "binary/onebox.ts",
        "outDir": "dist/binaries",
        "target": "x86_64-unknown-linux-gnu",
        "permissions": ["--allow-all"],
        "noCheck": true,
        "selfExtracting": true
      },
      {
        "name": "onebox-linux-arm64",
        "entryPoint": "binary/onebox.ts",
        "outDir": "dist/binaries",
        "target": "aarch64-unknown-linux-gnu",
        "permissions": ["--allow-all"],
        "noCheck": true,
        "selfExtracting": true
      }
    ]
  }
}

@git.zone/cli.schemaVersion remains the CLI config schema. @git.zone/cli.assets.schemaVersion is scoped to the managed asset model.

Managed assets are applied through the existing formatter workflow:

gitzone format plan --only assets --json
gitzone format check --only assets
gitzone format --only assets --write --yes

If npmWrapper.enabled is set, gitzone format --only packagejson --write also keeps package.json bin, scripts.postinstall, and npm package files entries in sync.

Set installer.distribution to "releaseAsset" when the installer itself should be published and documented as a Gitea release asset instead of a raw-branch file. That mode automatically stages install.sh into the release artifact directory unless releaseWorkflow.includeInstallerAsset is set explicitly.

Set installer.service.removeLegacyUnits to a list of systemd unit names when an installer must disable and remove older service units during upgrades.

Sealed TsPack releases on Gitea

For a component that already builds and packages with @git.zone/tspack, select assets.kind: "tspackRelease". GitZone manages the tag-triggered workflow and its release scripts. Compilation stays in the component's command, and TsPack owns archive creation and verification. The project must install @git.zone/tspack 1.1.0 or later and ignore both configured output and dist_gitzone_retained/ in Git. Pin pnpm 11 or later in package.json using packageManager. The workflow installs that version directly with the pinned official pnpm/setup action before the explicit frozen dependency install. This avoids an older container-provided pnpm launcher rewriting the lockfile while selecting the project's package manager. The image's Deno CLI installs sealedRelease.denoVersion with deno upgrade --force. The next command verifies the effective compiler version before dependency installation; this setup does not require a separate Deno action.

{
  "@git.zone/cli": {
    "assets": {
      "schemaVersion": 1,
      "kind": "tspackRelease",
      "sealedRelease": {
        "denoVersion": "2.9.4",
        "outputDirectory": "dist_control_release",
        "prepareCommand": ["node", "scripts/release-control.mjs"],
        "verifyCommand": ["node", "scripts/package-control.mjs", "--release", "--reuse"]
      }
    }
  }
}

Both commands return exactly one JSON object on stdout with directory and manifestSha256. Preparation creates a clean tagged release directly beneath the configured output root and saves every input descriptor needed for reuse. Verification restores that same result without compiling or repacking. Commands are explicit executable/argument arrays; GitZone does not interpolate a shell. Run gitzone format --only assets --write --yes and commit the generated files. The normal authorized gitzone release -y pushes the tag that triggers this CI flow.

The runner must support Gitea's v4 artifact protocol through the stock artifact actions: use Gitea Runner 3.3.2 or later with its cache/results service enabled and reachable from job containers, and keep runner.patch_actions enabled. The pinned actions run on Node.js 24. Follow the Gitea runner upgrade guide when upgrading an older runner; legacy v3 artifacts are absent from Gitea's REST artifact inventory and cannot satisfy this workflow's retention check.

Before any release mutation, the workflow retains the complete output root for 90 days using Gitea's v4 Actions artifact protocol, downloads it into a fresh directory, checks the component's reuse result, and verifies every archive through TsPack. The remote tag must match the sealed source commit. Publication creates a draft, downloads and checks existing attachments, uploads only missing files, and publishes after complete readback. It never replaces an attachment or deletes a release. HTTPS object-store redirects do not receive the Gitea job token.

Retry the original Gitea run after an interruption. A retained set from another run identifies the run to resume. Expired or missing retention, conflicting attachments, unexpected API responses, and changed source identities stop before publication. Keep the original artifact until publication is verified; if its retention has expired, recover its exact bytes before retrying. Rerunning an already published release only verifies its existing attachments.

Formatting

gitzone format is dry-run by default. That makes it safe to run in any repo.

# Preview changes
gitzone format

# Emit a machine-readable plan
gitzone format plan --json

# Fail when formatting changes or validator errors remain
gitzone format check

# Run a subset of formatters
gitzone format --only prettier,packagejson

# Apply changes
gitzone format --write

# Apply without prompt
gitzone format --write --yes

# Apply deterministic fixes, then use opencode for remaining issues
gitzone format fix

Formatters include cleanup, smartconfig normalization, dependency license checks, package metadata normalization, template updates, .gitignore, TypeScript config, Prettier, README existence checks, and configured copy operations.

gitzone format fix intentionally lives outside the default format path. Normal format runs stay deterministic; the fix command uses opencode only after deterministic formatters have done what they can.

Development Services

gitzone services manages local Docker-backed services for development projects.

Supported services:

Service Lifecycle/log aliases
MongoDB mongo, mongodb
ObjectStorage (S3-compatible) objectstorage, s3
Elasticsearch elasticsearch, es

Service-selection commands such as set, enable, and disable also accept elastic; lifecycle and log commands do not.

# Start configured services
gitzone services start

# Enable specific services non-interactively
gitzone services set mongodb,objectstorage

# Check status
gitzone services status

# Machine-readable status, including connection strings and data sizes
gitzone services status --json

# Print MongoDB Compass connection string
gitzone services compass

# Show logs
gitzone services logs mongo 50

Service config is stored in .nogit/env.json. Newly created config files use owner-only permissions; writes are atomic and reject a stale in-memory snapshot rather than overwriting a concurrent change. MongoDB, ObjectStorage, and Elasticsearch data is stored in .nogit/mongodata, .nogit/objectstoragedata, and .nogit/esdata, so it stays out of Git.

ObjectStorage uses S3_PORT for its local S3 API and S3_UI_PORT for its management UI. S3_REGION defaults to us-east-1; S3_ADMIN_PASSWORD is a separate randomly generated password for the UI's admin user. Startup rejects empty credentials, admin/admin S3 defaults, the default admin password, and an admin password reused as either S3 credential. gitzone services config --json replaces those three ObjectStorage credential values with "***". Other fields are unchanged, including MongoDB and Elasticsearch passwords and credential-bearing URLs, so the complete output must still be treated as sensitive.

GitZone runs a digest-pinned ObjectStorage image with both the S3 API and management UI published on loopback. S3_HOST, S3_ENDPOINT, S3_USESSL, and the other generic S3 consumer fields remain user-controlled; service startup always reconciles the local managed instance through 127.0.0.1 and its configured local ports.

Before creating or recreating an ObjectStorage container, or starting an owned stopped container, GitZone uses one fenced root helper to restore recursive ownership and set .nogit/objectstoragedata itself to mode 0700. An exact container caught in Docker's restart loop is stopped by immutable ID before that hardening and restart; if hardening fails, it remains safely stopped. An already-running canonical container is not modified.

GitZone derives new bucket names from the project name using S3 naming rules. When loading older configuration it repairs only the exact generated <project>-documents value if that value is invalid; custom bucket names are never rewritten. services start s3 validates the bucket and credentials, recreates an owned container when its pinned image, ports, data bind, controlled product environment, restart policy, command, entrypoint, user, or health check drifted, waits for management readiness, then creates and verifies the bucket through an authenticated S3 client. A GitZone-label mismatch is an ownership conflict and blocks mutation rather than being treated as repairable drift. Container setup, management readiness, and the S3 operations share one deadline; SmartBucket cleanup has its own bounded close. Docker mutations use the container's immutable ID after exact-name discovery. Outside the explicit restart-loop recovery above, GitZone stops a pre-existing container on failure only after that invocation's start returned successfully. A newly created ID remains invocation-owned across an uncertain start and can be stopped safely; an uncertain pre-existing start is left adoptable rather than risking stopping another concurrent invocation. A canonical container created but not yet started remains stopped for a safe retry.

Migrating legacy MinIO state

Persisted minio and s3 service selections are rewritten to the canonical objectstorage value. S3_CONSOLE_PORT is migrated to S3_UI_PORT when the values do not conflict. The runtime migration also adds the separate admin password and region fields and repairs only the exact invalid bucket name that older GitZone versions generated. Legacy registry and data-marker entries are retained as preserved migration evidence, not converted into active ObjectStorage ownership. Every selected migration store is preflighted before the first write. Closed-schema service selection, marker, and registry stores reject malformed, conflicting, foreign, or future state without rewriting it. Runtime config validates and migrates its known fields while preserving unknown application fields.

If <project>-minio, a registry-retained alternate legacy container name, or .nogit/miniodata still exists, ObjectStorage startup stops before mutating the ObjectStorage container. In an untargeted services start, an earlier enabled service such as MongoDB may already have started. GitZone never reuses, removes, cleans, or prunes legacy MinIO state because its disk layout is not compatible with ObjectStorage. Recovery is explicit:

  1. Export every required bucket with the existing MinIO tooling.
  2. Stop and rename the legacy container, then move .nogit/miniodata to a preserved backup location.
  3. Run gitzone services start s3 to create the canonical service.
  4. Import through an external S3 client and verify the required objects before disposing of the backup.

An existing .nogit/objectstoragedata directory without a valid ownership marker blocks creation of a new container and direct cleanup. One exception is an existing container whose immutable identity and exact canonical GitZone labels prove that directory belongs to this project; startup or removal repairs the missing marker before proceeding. An invalid or foreign marker always blocks mutation. Without that exact container proof, preserve or move the directory, verify its provenance outside GitZone, start a fresh canonical service, and import required objects through S3. Do not synthesize a marker for unverified data.

Consuming a service programmatically

gitzone services status --json emits only JSON on stdout, so a test suite or script can read a live connection string without parsing human output:

gitzone services status --json | jq -r '.services.mongodb.connectionString'

The ObjectStorage status key is .services.objectstorage; the former .services.minio key no longer exists. Preserved predecessor evidence is reported separately under .legacy. minioDataDirectory and minioDataExists are always emitted; minioContainer is present only when container evidence exists. Consumers must treat this as a breaking response-schema change rather than interpreting legacy evidence as an active service.

Cleanup levels

Cleanup is tiered, from fully resumable to irreversible:

Command Containers Data Notes
gitzone services stop kept (stopped) kept fully resumable
gitzone services remove removed kept resumable; --yes to skip the prompt
gitzone services clean removed removed irreversible; needs a typed yes or --yes
gitzone services prune see below see below machine-wide; dry run unless --apply

clean and prune first persist an exact deletion intent, then atomically rename the canonical directory to a tokenized sibling quarantine before deleting any contents. Native deletion is attempted there. If container-owned files remain, GitZone uses a short-lived root container scoped to that quarantine; Docker's --privileged mode is not used. The helper reserves one deterministic name per bind target, carries a random invocation label, is created stopped, and is inspected by immutable ID before execution or cleanup. Old stopped helpers can be recovered only after their complete runtime envelope, bind target, age, and immutable ID are proven; running, fresh, or noncanonical occupants block the operation. If interruption or helper failure leaves bytes, the persisted intent lets the next clean or prune --apply resume the same quarantine. A partial failure therefore never leaves a corrupt directory at the canonical service path. Startup refuses to create fresh service data while such an intent remains.

Service start, stop, container removal, and data removal share one interprocess lock per project and service. Startup refreshes runtime config and project activity inside that lock, while prune rechecks activity and stopped as well as running service containers after acquiring it. Concurrent lifecycle commands therefore serialize rather than deleting a directory or container while another command prepares, mounts, starts, or stops it.

Reclaiming space across projects

Service data is per project and survives container removal, so it accumulates. gitzone services prune reports what every registered project holds and what can be reclaimed. It is read-only unless --apply is passed:

# Report only: what exists, what is reclaimable, and why
gitzone services prune

# Change the inactivity threshold (default 30 days)
gitzone services prune --stale-days 90

# Actually reclaim, non-interactively
gitzone services prune --apply --yes

A project is only a candidate when there is positive evidence it is finished with: its directory is gone, or it has been inactive past the threshold with no container running. Anything ambiguous — an unlabeled container claimed by more than one project, an unreachable Docker daemon, a directory still mounted by a running container — is reported and skipped rather than reclaimed. Containers are identified by an exact canonical GitZone label envelope. An unambiguous registry claim is used only for older MongoDB and Elasticsearch containers with no git.zone.* labels at all. ObjectStorage has no unlabeled predecessor fallback; partial, missing, or conflicting GitZone labels fail closed. Removal revalidates and uses the container's immutable ID, never its mutable name, so pruning cannot touch a same-name replacement. If Docker becomes unavailable, registry claims are preserved as well as containers and data.

Legacy MinIO containers and registry references are reported as preserved migration resources and are never prune candidates. .nogit/miniodata is deliberately outside the prune allowlist; current-project status reports its presence, while machine-wide prune leaves it untouched.

MongoDB authentication

MongoDB runs as a single-node replica set with authentication enabled, so multi-document transactions work. The managed container also uses a 65,536 soft/hard nofile limit so persistent, collection-heavy test suites do not hit Docker's low default. services start reconciles legacy containers to this limit by recreating only the container while preserving the bind-mounted data directory. Authentication can be disabled per project for runtimes whose node:crypto cannot complete a SCRAM handshake (notably Deno):

gitzone services auth mongodb off
gitzone services start mongo

This is opt-in and never implicit. With authentication disabled the database is published on 127.0.0.1 only, and the combination of no authentication with a non-local MONGODB_HOST is refused outright. Transactions continue to work, and gitzone services status reports the mode. Re-enabling authentication over data created without it bootstraps the configured root user through MongoDB's localhost exception.

The setting is recorded in .smartconfig.json, so it is committed and a fresh clone or CI run reproduces it without any manual step:

{
  "@git.zone/cli": {
    "services": ["mongodb"],
    "serviceOptions": {
      "mongodb": { "auth": false }
    }
  }
}

serviceOptions is a sibling of services, never a richer services value. services must stay a flat array of canonical lowercase strings because @git.zone/tsdeploy derives a workload's requiredCapabilities from it and rejects any other shape.

A committed declaration takes precedence over .nogit/env.json, so a stale local file cannot silently diverge from what the repository declares. When nothing is declared, an existing local value is preserved. When neither exists, authentication is enabled. Because a declaration affects everyone who clones the repository, services status states where the setting came from:

⚠️  Auth: DISABLED (loopback only), declared in .smartconfig.json (applies to every checkout)

An older CLI that predates serviceOptions ignores the key and starts MongoDB with authentication enabled — it degrades to the secure default, never the insecure one.

Checking which version is running

gitzone --version prints the bare version on the first line, followed by the path it resolved from. A stale copy in a legacy pnpm global root can otherwise make it look like an older version is installed when it is not:

gitzone --version
# 3.2.1
# resolved from: /home/you/.local/share/pnpm/store/v11/links/@git.zone/cli/3.2.1/…

gitzone --version --json
# {"version":"3.2.1","resolvedFrom":"…"}

gitzone tools update also removes inert copies of managed packages left behind in legacy global roots, provided the active root already supplies them and no command shim still points there.

Approved Testing Domains

gitzone testing uses the testing API in dcrouter 19.1.1 or later. An operator first enables an explicit testing-zone policy, provisions a machine registration, and approves each exact hostname requested by that registration. Approved grants survive credential rotation. Wildcards, parent domains, arbitrary TXT records, and production routes are outside this command's authority.

Inject GITZONE_TESTING_BASE_URL and GITZONE_TESTING_TOKEN from your environment or secret manager. Admin commands select GITZONE_TESTING_ADMIN_TOKEN instead. The URL must be an HTTPS origin; plain HTTP is accepted only on loopback for isolated tests. Credentials are never accepted as command arguments or saved to project/global configuration. --token-stdin reads at most 8192 bytes from a non-terminal stdin and requires the selected environment credential to be absent.

gitzone testing --help
gitzone help testing --json
gitzone testing whoami --json
gitzone testing zone list --limit 25 --json
gitzone testing grant request --zone ZONE_ID --hostname alice.testing.example.com --idempotency-key grant-alice-1 --json
gitzone testing grant status --grant GRANT_ID --json
gitzone testing cert ensure --grant GRANT_ID --idempotency-key cert-alice-1 --wait --json
gitzone testing cert status --job JOB_ID --json

Mutation keys are supplied explicitly. Repeat the same key and payload after a lost response; use a new key only for a new operation. Certificate requests reuse usable cached material. --wait follows queued/running/retry-wait jobs while respecting their polling and retry times. --timeout-ms bounds acquisition and requests (default five minutes, maximum one hour). A local deadline or signal does not cancel durable server work. Poll the returned operation ID or repeat the original idempotency key to find its outcome. Unknown or abandoned outcomes require operator recovery and never trigger automatic mutation resubmission.

Run a development server with disposable certificate files:

gitzone testing cert run --grant GRANT_ID --idempotency-key cert-alice-1 -- node server.js --port 8443

The child receives GITZONE_TESTING_CERTIFICATE_FILE, GITZONE_TESTING_PRIVATE_KEY_FILE, and GITZONE_TESTING_HOSTNAME. Its environment excludes the parent's GITZONE_TESTING_* values, including both credentials. The directory has mode 0700 and both files have mode 0600. GitZone invokes the program directly, preserves every argument after --, returns its exit status, and removes the directory after exit or termination. SIGINT/SIGTERM are forwarded to the child; a child that does not stop is killed after five seconds. JSON output is rejected for cert run because child stdout is inherited. Certificate renewal is on demand: this command obtains material once; restart it to obtain renewed material when due. It does not save a permanent certificate cache.

DNS operations are restricted to records owned by the approved grant. Use new for creation and the current record revision for replacement/deletion:

gitzone testing dns upsert --grant GRANT_ID --record-key web-v4 --revision new --type A --value 192.0.2.10 --ttl 60 --idempotency-key dns-web-1 --wait --json
gitzone testing dns list --grant GRANT_ID --json
gitzone testing dns delete --grant GRANT_ID --record-key web-v4 --revision 1 --idempotency-key dns-delete-1 --wait --json
gitzone testing dns status --mutation MUTATION_ID --json

Admin enrollment and rotation require a caller-preopened writable non-terminal descriptor of at least 3. Supply it through the parent secret-manager integration; GitZone writes exactly the new token plus a newline to that descriptor, and only registration metadata to ordinary output. No credential can be retrieved again after a lost delivery; list registrations and rotate the relevant credential.

# Descriptor 3 must already be connected to the caller's secret store.
gitzone testing admin registration create --name developer-alice --expires-at 2027-01-01T00:00:00Z --idempotency-key enroll-alice-1 --secret-fd 3 --json
gitzone testing admin registration list --json
gitzone testing admin registration rotate --registration REGISTRATION_ID --generation 1 --expires-at 2027-01-01T00:00:00Z --secret-fd 3 --json
gitzone testing admin zone put --domain DOMAIN_ID --revision new --enabled true --record-types A,AAAA,CNAME --min-ttl 60 --max-ttl 3600 --max-grants 25 --json
gitzone testing admin grant list --state pending --json
gitzone testing admin grant review --grant GRANT_ID --revision 1 --action approve --reason 'Approved development hostname' --json

admin registration revoke and admin grant review --action revoke require a revision and reason. Revocation blocks future access and schedules cleanup of proven-owned DNS records; already delivered keys cannot be recalled. Operator recovery remains revision checked and audited:

gitzone testing admin recovery list --kind certificate --state indeterminate --json
gitzone testing admin recovery status --kind certificate --operation JOB_ID --json
gitzone testing admin recovery action --kind certificate --operation JOB_ID --revision 3 --action recheck --reason 'Inspect interrupted issuance' --idempotency-key recovery-1 --json

For DNS recovery, --operation may identify a mutation or a grant's retained cleanup operation. Only actions listed by the server are supported. Abandonment retains unknown effects and their reservations; it does not make them safe to repeat. Lists accept --after and --limit (25 by default, at most 100) and return nextAfterId. Exit codes are 0 for success/admitted work, 1 for failure or an unresolved terminal operation, 2 for invalid input, and 130/143 for interruption.

Templates

Start new projects with built-in scaffolds:

gitzone template npm
gitzone template service
gitzone template website
gitzone template wcc

Templates are rendered through SmartScaf and then can be normalized with gitzone format.

Meta Repositories

Use gitzone meta when one workspace coordinates multiple repositories.

gitzone meta init
gitzone meta add frontend https://example.com/org/frontend.git
gitzone meta update
gitzone meta remove frontend

Other Utilities

Docker resources

gitzone docker prune reports Docker containers and volumes created by git.zone tooling, and reclaims them only when asked:

gitzone docker prune                    # report only
gitzone docker prune --apply            # remove stopped tool-owned containers
gitzone docker prune --volumes          # include tool-owned volumes in the report
gitzone docker prune --volumes --apply --yes

Scope is an allowlist: only resources labeled git.zone.tool=<tool> and git.zone.safe-to-prune=true are ever considered. Anything unlabeled is invisible to the command. Running containers and attached volumes are never removed, and images are never removed at all. Volumes hold persisted data, so they are excluded unless --volumes is passed and require a typed yes or --yes on top of --apply.

This command deliberately cannot prune the whole machine. To do that, run docker directly so the blast radius is explicit and yours.

Other utilities

# Open GitLab CI settings or pipelines for the current repo
gitzone open ci
gitzone open pipelines

# Deprecate an old npm package interactively
gitzone deprecate

# Preview an explicit deprecation across both registries
gitzone deprecate --package @example/old --replacement @example/new --registries https://registry.npmjs.org,https://mirror.example.test --plan

# Prepare a project for local work
gitzone start

# Generate a short unique ID
gitzone helpers shortid

For explicit deprecation, replace --plan with -y to apply the reviewed operation. --message supplies migration instructions; otherwise the message names the replacement. Deprecation applies to every version. GitZone verifies an active replacement on all registries before issuing any change, invokes pnpm deprecate with literal arguments, and verifies the old versions' metadata after each registry operation. Verification uses up to five fresh metadata reads, one second apart, to allow registry propagation. A rerun skips any registry where every version already has the exact requested message, so accepted deprecations are not submitted again. --json prints the plan without changing it.

Troubleshooting

Format only previews changes:

gitzone format --write

Release says there is nothing to release:

# Make sure commits have populated the Pending changelog section
gitzone commit

Packing fails while reading an excluded local service-data directory:

Use a clean release checkout with dependencies installed from the committed lockfile. pnpm's packlist traversal can visit local data before applying the package's files list; .npmignore does not prevent that traversal when files is present. Keep service data and its permissions intact.

Inspect the release journal before retrying. An installed journal must be resumed with its original artifacts. A failure before journal installation has not started final publication and cannot use release resume; reconcile the local release commit and tag explicitly, preserving their identities. A later source correction can be released as a new version from the clean checkout.

Docker services fail to start:

docker info
gitzone services status
gitzone services reconfigure

Config looks outdated:

gitzone config migrate 2
gitzone config show --json

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license file.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

S
Description
the main git.zone cli
Readme
7.8 MiB
Languages
TypeScript 97.5%
JavaScript 1.4%
Shell 0.8%
HTML 0.2%