diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4936cf1d..0a9a5b36 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,32 @@ -* @z-shell/tsc +# CODEOWNERS — zi +# +# GitHub evaluates rules top-to-bottom; the LAST matching rule wins. +# Sections are ordered from broadest to most specific so that narrower +# rules can override the default without removing coverage elsewhere. +# +# Team: @z-shell/tsc — Technical Steering Committee (final sign-off) +# Owner: @ss-o — Primary maintainer (day-to-day reviews) + +# ── Default ────────────────────────────────────────────────────────────────── +# Catch-all: everything not matched by a more specific rule below. +* @ss-o + +# ── Core Zsh runtime ───────────────────────────────────────────────────────── +# Changes here affect every Zi user; require TSC review. +/zi.zsh @z-shell/tsc +/lib/ @z-shell/tsc + +# ── CI / Workflows ─────────────────────────────────────────────────────────── +# Workflow changes reviewed by primary maintainer; no TSC sign-off required. +/.github/workflows/ @ss-o +/.github/dependabot.yml @ss-o + +# ── Documentation & templates ──────────────────────────────────────────────── +/docs/ @ss-o +/.github/ISSUE_TEMPLATE/ @ss-o +/.github/PULL_REQUEST_TEMPLATE.md @ss-o +/.github/copilot-instructions.md @ss-o + +# ── Governance (must be last — highest specificity) ─────────────────────────── +# CODEOWNERS itself requires TSC approval to change. +/.github/CODEOWNERS @z-shell/tsc diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index dc09aad9..85c9019f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,43 +1,46 @@ - + - -## Motivation and Context + Branch model: + • Create your branch FROM next: git checkout -b fix/my-fix next + • Open this PR TARGETING next — never target main directly + • main is only updated from next via a release PR - - + Commit messages must follow Conventional Commits: + type(scope): short description (≤72 chars, imperative mood) + Types: feat fix perf refactor docs test ci chore revert + Example: fix(self-update): correctly propagate exit code on failure -## How Has This Been Tested? + See .github/copilot-instructions.md for full guidelines. +--> - - - - -## Screenshots (if appropriate): +## Description -## Types of changes + - +## Related issues -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to change) -- [ ] Documentation update (if none of the other choices apply) -- [ ] Chore (general maintenance, refactoring, or code style update) + -## Checklist: +## Type of change - - + -- [ ] My code follows the code style of this project. -- [ ] I have read the **CONTRIBUTING** document. -- [ ] I have added tests to cover my changes. -- [ ] All new and existing tests passed. -- [ ] I have updated the documentation accordingly. +- [ ] `fix` — bug fix (non-breaking) +- [ ] `feat` — new feature (non-breaking) +- [ ] `feat!` / `fix!` — breaking change +- [ ] `perf` — performance improvement +- [ ] `refactor` — code change with no functional impact +- [ ] `docs` — documentation only +- [ ] `ci` — CI/workflow change +- [ ] `chore` — maintenance / dependency bump -## Other information (if applicable) +## Checklist - +- [ ] My branch was created from `next` (not `main`) +- [ ] This PR targets the `next` branch +- [ ] Commit messages follow Conventional Commits format +- [ ] No AI co-author trailers in commit messages +- [ ] I have read [CONTRIBUTING.md](docs/CONTRIBUTING.md) +- [ ] Existing tests pass (`zsh -n zi.zsh` / Trunk checks) +- [ ] Documentation updated if needed diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..557fad46 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,70 @@ +# Project Context + +## Architecture + + + +## Conventions + + + +## Key Commands + + + +## Out of Scope + + + +## Commit messages + +- Use **Conventional Commits** format: `type(scope): short description` +- Allowed types: `feat`, `fix`, `perf`, `refactor`, `docs`, `test`, `ci`, `chore`, `revert` +- Subject line: imperative mood, ≤72 characters, no trailing period +- Body: wrap at 72 characters, explain _what_ and _why_ (not _how_) +- **Never add AI co-author trailers** — do not append `Co-authored-by: Copilot`, `Co-authored-by: Claude`, `Co-authored-by: GitHub Copilot`, or any AI-generated attribution to commit messages +- Breaking changes: add `!` after the type (`feat!:`) and include `BREAKING CHANGE:` in the footer + +Examples: + +````text +feat(loader): add lazy-loading for completions + +Defer completion setup until first TAB press to cut startup time +for users with large fpath trees. + +BREAKING CHANGE: ZI_COMPLETION_LAZY must be set before zi is sourced. +```text + +```text +fix(self-update): correctly set exit code on network failure +```text + +## Branch model + +```text +main ← production releases (tags only, squash-merged from next) +next ← integration branch (PR target for all work) + └─ feat/ feature branches + └─ fix/ bug-fix branches + └─ perf/ performance improvements + └─ docs/ documentation updates + └─ ci/ CI/workflow changes + └─ chore/ maintenance, refactors +```text + +- **All branches must be created from `next`**, not `main` +- Open PRs **targeting `next`**, never `main` directly +- `next` → `main` is the only path to production; it requires all CI checks to pass + +## AI-generated files + +- Do **not** suggest adding `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.aider*`, or similar AI-specific config files to this repository +- Copilot configuration lives **only** in `.github/copilot-instructions.md` + +## Code style + +- Zsh files: 2-space indent, `# vim: ft=zsh sw=2 ts=2 et` modeline, LF endings +- Every plugin entry file must resolve `$0` via the ZERO pattern +- Follow the [Z-Shell Plugin Standard](https://wiki.zshell.dev/community/zsh_plugin_standard) +```` diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 914813e4..09179bc1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,4 +5,5 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" + interval: "weekly" + target-branch: "next" diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index deee3c15..00000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,22 +0,0 @@ -documentation 📝: - - changed-files: - - any-glob-to-any-file: - - "docs/*.md" - - "docs/man/*" -enhancement ✨: - - changed-files: - - any-glob-to-any-file: - - "*.zsh" - - "lib/**" -maintenance 📈: - - changed-files: - - any-glob-to-any-file: - - ".github/CODEOWNERS" - - ".github/*.yml" - - ".github/*.json" - - ".vscode/*" - - ".trunk/**" -ci 🤖: - - changed-files: - - any-glob-to-any-file: - - ".github/workflows/*.yml" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..66f4e3df --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,45 @@ +--- +name: CodeQL + +on: + push: + branches: [main, next] + pull_request: + branches: [main, next] + schedule: + - cron: "28 15 * * 5" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml new file mode 100644 index 00000000..efd2e49e --- /dev/null +++ b/.github/workflows/commit-lint.yml @@ -0,0 +1,101 @@ +--- +name: "📝 Commit Lint" + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + branches: + - main + - next + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + pull-requests: read + contents: read + +jobs: + commit-lint: + name: "📝 Validate Commits" + runs-on: ubuntu-latest + steps: + - name: "⤵️ Check out code from GitHub" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: "📝 Lint commit messages" + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + DISALLOWED_TRAILER_PATTERN: ${{ secrets.DISALLOWED_TRAILER_PATTERN }} + run: | + set -euo pipefail + + CONVENTIONAL_PATTERN='^(feat|fix|perf|refactor|docs|test|ci|chore|revert)(\([^)]+\))?!?: .{1,72}$' + + errors=0 + checked=0 + + while IFS= read -r sha; do + parent_count=$(git cat-file -p "$sha" | grep -c '^parent' || true) + [ "$parent_count" -gt 1 ] && continue + + subject=$(git show -s --format='%s' "$sha") + checked=$((checked + 1)) + + if ! echo "$subject" | grep -qE "$CONVENTIONAL_PATTERN"; then + echo "❌ Invalid commit message (${sha:0:7}): expected type(scope): description ≤72 chars" + errors=$((errors + 1)) + fi + + if [ -n "${DISALLOWED_TRAILER_PATTERN:-}" ]; then + if git show -s --format='%B' "$sha" | grep -qE "$DISALLOWED_TRAILER_PATTERN"; then + echo "❌ Disallowed trailer found (${sha:0:7}): remove before merging" + errors=$((errors + 1)) + fi + fi + done < <(git log --format='%H' "${BASE_SHA}..${HEAD_SHA}") + + if [ "$errors" -gt 0 ]; then + echo "::error::$errors commit(s) failed validation — run: git rebase -i ${BASE_SHA}" + exit 1 + fi + + echo "✅ $checked commit(s) validated" + + pr-title: + name: "📋 Validate PR Title" + runs-on: ubuntu-latest + steps: + - name: "📋 Check PR title follows Conventional Commits" + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + PATTERN='^(feat|fix|perf|refactor|docs|test|ci|chore|revert)(\([^)]+\))?!?: .{1,72}$' + if ! echo "$PR_TITLE" | grep -qE "$PATTERN"; then + echo "::error::PR title must follow Conventional Commits: type(scope): description" + exit 1 + fi + echo "✅ PR title valid" + + branch-naming: + name: "🌿 Validate Branch Name" + runs-on: ubuntu-latest + steps: + - name: "🌿 Check branch naming convention" + env: + BRANCH: ${{ github.head_ref }} + run: | + PATTERN='^(feat|fix|perf|refactor|docs|test|ci|chore|revert)/[a-z0-9][a-z0-9-]*[a-z0-9]$' + if echo "$BRANCH" | grep -q '^dependabot/'; then + echo "✅ OK" + exit 0 + fi + if ! echo "$BRANCH" | grep -qE "$PATTERN"; then + echo "::error::Branch name must follow type/short-description (e.g. feat/my-feature)" + exit 1 + fi + echo "✅ Branch name valid" diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 24151b81..00000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: 🔖 Pull Request Labeler -on: - pull_request_target: - -permissions: - contents: read - pull-requests: write - -jobs: - triage: - runs-on: ubuntu-latest - steps: - - uses: actions/labeler@v5 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - sync-labels: false diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml deleted file mode 100644 index 0ca1c103..00000000 --- a/.github/workflows/lock.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -name: 🔒 Lock closed issues and PRs - -on: - schedule: - - cron: "30 2 * * *" - -permissions: - issues: write - pull-requests: write - -concurrency: - group: lock - -jobs: - lock: - name: 🔐 Lock closed issues and PRs - runs-on: ubuntu-latest - steps: - - uses: dessant/lock-threads@v4 - with: - github-token: ${{ github.token }} - issue-inactive-days: "30" - issue-lock-reason: "" - issue-comment: > - Issue closed and locked due to lack of activity. - - If you encounter this same issue, please open a new issue and refer to this closed one. - - pr-inactive-days: "7" - pr-lock-reason: "" - pr-comment: > - Pull Request closed and locked due to lack of activity. - - If you'd like to build on this closed PR, you can clone it using this method: https://stackoverflow.com/a/14969986 - - Then open a new PR, referencing this closed PR in your message. diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml deleted file mode 100644 index 1f30bbc6..00000000 --- a/.github/workflows/pr-labels.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: 🏷️ Verify PR Labels - -on: - workflow_dispatch: - pull_request_target: - types: ["opened", "labeled", "unlabeled", "synchronize"] - -jobs: - pr_labels: - name: 🏭 Verify PR Labels - runs-on: ubuntu-latest - steps: - - name: 🏷 Verify PR has a valid label - uses: jesusvasquez333/verify-pr-label-action@v1.4.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - pull-request-number: "${{ github.event.pull_request.number }}" - valid-labels: > - "breaking-change 💥, bug 🐞, i18n 🌐, l10n 🗣, documentation 📝, enhancement ✨, security 🛡️, refactor ♻️, performance 🚀, new-feature 🎉, triage 📑, maintenance 📈, ci 🤖, fix ⚡, - dependencies 📦, submodules ⚙️, annex 🌀, plugin ⚙️, package 📦" - invalid-labels: > - "Q&A ✍️, stale 👻, no-stale 🔒, locked ‼️, resolved ☑️, feature-request 💡, help-wanted, beginner-friendly 💕, priority-low 🔖, invalid ⚠️" - disable-reviews: true diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml deleted file mode 100644 index ad7b8652..00000000 --- a/.github/workflows/rebase.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: "🔁 Rebase" -on: - issue_comment: - types: [created] -jobs: - rebase: - runs-on: ubuntu-latest - name: 🔁 Rebase - # Automate with comments: /autosquash, /rebase - if: >- - github.event.issue.pull_request != '' && ( - contains(github.event.comment.body, '/rebase') || - contains(github.event.comment.body, '/autosquash') - ) - steps: - - name: ⤵️ Check out code from GitHub - uses: actions/checkout@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # otherwise, you will fail to push refs to dest repo - - name: 🔁 Rebase - uses: z-shell/.github/actions/rebase@main - with: - autosquash: ${{ contains(github.event.comment.body, '/autosquash') || contains(github.event.comment.body, '/rebase-autosquash') }} - env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 91f6468f..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: 🧹 Clean up stale issues and PRs - -on: - schedule: - - cron: "0 8 * * *" - workflow_dispatch: - -jobs: - stale: - name: 🧹 Clean up stale issues and PRs - runs-on: ubuntu-latest - steps: - - name: 🚀 Run stale - uses: actions/stale@v7 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-stale: 30 - days-before-close: 7 - remove-stale-when-updated: true - stale-issue-label: "stale 👻" - exempt-issue-labels: "no-stale 🔒,help-wanted 👥" - stale-issue-message: > - There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale. - - Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by leaving a 👍 - - Because this issue is marked as stale, it will be closed and locked in 7 days if no further activity occurs. - - Thank you for your contributions! - stale-pr-label: "stale 👻" - exempt-pr-labels: "no-stale 🔒" - stale-pr-message: > - There hasn't been any activity on this pull request recently, and in order to prioritize active work, it has been marked as stale. - - This PR will be closed and locked in 7 days if no further activity occurs. - - Thank you for your contributions! diff --git a/.github/workflows/trunk-check.yml b/.github/workflows/trunk-check.yml index 4bf797d1..69b74740 100644 --- a/.github/workflows/trunk-check.yml +++ b/.github/workflows/trunk-check.yml @@ -2,7 +2,7 @@ name: Trunk Code Quality on: push: - branches: [main] + branches: [main, next] tags: ["v*.*.*"] pull_request: types: [opened, synchronize] @@ -22,6 +22,6 @@ jobs: contents: read # For repo checkout steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Trunk Code Quality uses: trunk-io/trunk-action@75699af9e26881e564e9d832ef7dc3af25ec031b diff --git a/.github/workflows/zd-integration.yml b/.github/workflows/zd-integration.yml new file mode 100644 index 00000000..1af598a1 --- /dev/null +++ b/.github/workflows/zd-integration.yml @@ -0,0 +1,28 @@ +--- +name: "🧪 ZD Integration" + +on: + push: + branches: [main, next] + paths: + - "zi.zsh" + - "lib/**" + pull_request: + paths: + - "zi.zsh" + - "lib/**" + workflow_dispatch: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + zd-test: + uses: z-shell/zd/.github/workflows/test-native.yml@cbb1211f6a39f9d89a600297883b3766d4fa8ab9 # main + with: + zi_repo: ${{ github.repository }} + zi_ref: ${{ github.head_ref || github.ref_name }} diff --git a/.github/workflows/zsh-n.yml b/.github/workflows/zsh-n.yml index d3ae47b7..1b0ec5d5 100644 --- a/.github/workflows/zsh-n.yml +++ b/.github/workflows/zsh-n.yml @@ -21,6 +21,13 @@ on: branches: [main] workflow_dispatch: {} +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + jobs: zsh-matrix: runs-on: ubuntu-latest @@ -28,7 +35,7 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - name: ⤵️ Check out code from GitHub - uses: actions/checkout@v3 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: "Set matrix output" id: set-matrix run: | @@ -44,7 +51,7 @@ jobs: matrix: ${{ fromJSON(needs.zsh-matrix.outputs.matrix) }} steps: - name: ⤵️ Check out code from GitHub - uses: actions/checkout@v3 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: "⚡ Install dependencies" run: sudo apt update && sudo apt-get install -yq zsh - name: "⚡ zsh -n: ${{ matrix.file }}" diff --git a/.github/workflows/zunit.yml b/.github/workflows/zunit.yml deleted file mode 100644 index 13c28d4d..00000000 --- a/.github/workflows/zunit.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -name: "♾️ ZUnit" - -on: - push: - branches: [main] - tags: ["v*.*.*"] - paths: - - "lib/zsh/install.zsh" - - "lib/zsh/autoload.zsh" - workflow_dispatch: {} - -env: - branch_ref: $GITHUB_REF_NAME - -jobs: - zunit-matrix: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - uses: actions/checkout@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - repository: "z-shell/zd" - - name: "Set matrix output" - id: set-matrix - run: | - builtin cd docker/tests - MATRIX="$(ls -1 *.zunit | sed 's/.zunit$//' | jq -ncR '{"include": [{"file": inputs}]}')" - echo "MATRIX=${MATRIX}" >&2 - echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT - - zunit: - runs-on: ubuntu-latest - needs: zunit-matrix - strategy: - fail-fast: false - matrix: ${{ fromJSON(needs.zunit-matrix.outputs.matrix) }} - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/checkout@v3 - with: - repository: "z-shell/zd" - token: ${{ secrets.GITHUB_TOKEN }} - - run: command git clone --branch ${{ env.branch_ref }} --depth 1 -- https://github.com/z-shell/zi.git zi - - name: "⚡ Install dependencies" - run: | - sudo apt-get update && sudo apt-get install -yq zsh - mkdir bin - curl -fsSL https://raw.githubusercontent.com/zdharma/revolver/v0.2.4/revolver > bin/revolver - curl -fsSL https://raw.githubusercontent.com/zdharma/color/d8f91ab5fcfceb623ae45d3333ad0e543775549c/color.zsh > bin/color - git clone https://github.com/zdharma/zunit.git zunit.git - cd zunit.git - ./build.zsh - cd .. - mv ./zunit.git/zunit bin - chmod u+x bin/{color,revolver,zunit} - - name: "⚡ ZUnit: ${{ matrix.file }}" - env: - ZUNIT_TEST: ${{ matrix.file }} - run: | - echo "⚡ $ZUNIT_TEST" >&2 - export PATH="$PWD/bin:$PATH" - export TERM=xterm-256color - zunit --tap --verbose "docker/tests/${ZUNIT_TEST}.zunit" diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 37779e87..d55e8ebd 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,7 +1,59 @@ -# Contributing Guidelines +# Contributing to zi -When contributing, please first [discuss](https://github.com/z-shell/zi/issues/new/choose) the change you wish. The -[contributing guidelines](https://github.com/z-shell/community/blob/main/docs/CONTRIBUTING_GUIDELINES.md) and other relevant documents can be found in the -[community](https://github.com/z-shell/community) repository. +Thank you for contributing! Please follow the guidelines below to keep the project history clean and easy to navigate. -Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. +## Branch model + +````text +main ←─── production (tagged releases only) + ↑ +next ←─── integration branch ← open all PRs here + ↑ + ├── feat/ new features + ├── fix/ bug fixes + ├── perf/ performance improvements + ├── refactor/ code refactors + ├── docs/ documentation updates + └── ci/ CI / workflow changes +```text + +1. **Always branch from `next`**: `git checkout -b fix/my-issue next` +2. **Open PRs targeting `next`** — never target `main` directly +3. `next` → `main` happens via a release PR once `next` is stable + +## Commit message format + +All commits must follow [Conventional Commits](https://www.conventionalcommits.org/): + +```text +type(scope): short description + +Optional body — explain what and why, not how. +Wrap at 72 characters. + +Optional footer(s): +Fixes #123 +BREAKING CHANGE: description of what breaks +```text + +**Allowed types:** `feat` `fix` `perf` `refactor` `docs` `test` `ci` `chore` `revert` + +**Rules:** + +- Subject line: imperative mood, ≤72 characters, no trailing period +- Breaking changes: use `!` suffix (`feat!:`) and add `BREAKING CHANGE:` footer +- **No AI co-author trailers** — do not add `Co-authored-by: Copilot` or similar + +To clean up commits before opening a PR: `git rebase -i $(git merge-base HEAD next)` + +## What not to add + +- `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, or any AI-specific config files +- Secrets, credentials, or tokens of any kind + +## Discussion and issues + +Before starting significant work, [open an issue](https://github.com/z-shell/zi/issues/new/choose) to discuss the change. + +See also the [community contributing guidelines](https://github.com/z-shell/community/blob/main/docs/CONTRIBUTING_GUIDELINES.md) and the [Code of Conduct](CODE_OF_CONDUCT.md). +```` diff --git a/docs/README.md b/docs/README.md index 5d9d6d42..f2713ca8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@

- Zi Logo + Zi Logo Zi

@@ -37,10 +37,10 @@ Version Project License - VIM + VIM - Visual Studio Code -

+ Visual Studio Code +

diff --git a/lib/_zi b/lib/_zi index b6933ca1..b1a759a0 100755 --- a/lib/_zi +++ b/lib/_zi @@ -1,6 +1,6 @@ #compdef zi -builtin setopt local_options warn_create_global type_set_silent +builtin setopt local_options warn_create_global typeset_silent local curcontext="$curcontext" state state_descr line ret=1 local -a expl