sase-github 0.1.5__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {sase_github-0.1.5 → sase_github-0.2.0}/.github/workflows/ci.yml +28 -8
  2. {sase_github-0.1.5 → sase_github-0.2.0}/.github/workflows/publish.yml +18 -6
  3. sase_github-0.2.0/.release-please-manifest.json +3 -0
  4. {sase_github-0.1.5 → sase_github-0.2.0}/CHANGELOG.md +60 -0
  5. sase_github-0.2.0/Justfile +74 -0
  6. {sase_github-0.1.5 → sase_github-0.2.0}/PKG-INFO +2 -2
  7. {sase_github-0.1.5 → sase_github-0.2.0}/README.md +33 -13
  8. {sase_github-0.1.5 → sase_github-0.2.0}/docs/architecture.md +27 -1
  9. {sase_github-0.1.5 → sase_github-0.2.0}/docs/configuration.md +38 -16
  10. {sase_github-0.1.5 → sase_github-0.2.0}/docs/xprompts.md +2 -1
  11. {sase_github-0.1.5 → sase_github-0.2.0}/pyproject.toml +4 -3
  12. sase_github-0.2.0/src/sase_github/__init__.py +17 -0
  13. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/config.py +62 -0
  14. sase_github-0.2.0/src/sase_github/errors.py +22 -0
  15. sase_github-0.2.0/src/sase_github/plugin.py +421 -0
  16. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/scripts/gh_setup.py +3 -0
  17. sase_github-0.2.0/src/sase_github/workspace_plugin.py +1906 -0
  18. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/xprompts/gh.yml +2 -2
  19. sase_github-0.2.0/tests/test_ci_install_contract.py +56 -0
  20. {sase_github-0.1.5 → sase_github-0.2.0}/tests/test_config.py +37 -0
  21. sase_github-0.2.0/tests/test_github_issues.py +400 -0
  22. {sase_github-0.1.5 → sase_github-0.2.0}/tests/test_github_plugin.py +10 -10
  23. {sase_github-0.1.5 → sase_github-0.2.0}/tests/test_submit_with_recorded_pr.py +1 -1
  24. sase_github-0.2.0/tests/test_workspace_plugin.py +2210 -0
  25. sase_github-0.1.5/.release-please-manifest.json +0 -3
  26. sase_github-0.1.5/Justfile +0 -36
  27. sase_github-0.1.5/src/sase_github/__init__.py +0 -6
  28. sase_github-0.1.5/src/sase_github/plugin.py +0 -121
  29. sase_github-0.1.5/src/sase_github/workspace_plugin.py +0 -786
  30. sase_github-0.1.5/tests/test_workspace_plugin.py +0 -509
  31. {sase_github-0.1.5 → sase_github-0.2.0}/.github/workflows/pr-title.yml +0 -0
  32. {sase_github-0.1.5 → sase_github-0.2.0}/.sase_beads/beads.db +0 -0
  33. {sase_github-0.1.5 → sase_github-0.2.0}/.sase_beads/config.json +0 -0
  34. {sase_github-0.1.5 → sase_github-0.2.0}/.sase_beads/issues.jsonl +0 -0
  35. {sase_github-0.1.5 → sase_github-0.2.0}/CLAUDE.md +0 -0
  36. {sase_github-0.1.5 → sase_github-0.2.0}/LICENSE +0 -0
  37. {sase_github-0.1.5 → sase_github-0.2.0}/release-please-config.json +0 -0
  38. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/default_config.yml +0 -0
  39. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/scripts/__init__.py +0 -0
  40. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/scripts/new_pr_desc_get_context.py +0 -0
  41. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/xprompts/new_pr_desc.yml +0 -0
  42. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/xprompts/pr_diff.yml +0 -0
  43. {sase_github-0.1.5 → sase_github-0.2.0}/src/sase_github/xprompts/prdd.yml +0 -0
  44. {sase_github-0.1.5 → sase_github-0.2.0}/tests/__init__.py +0 -0
  45. {sase_github-0.1.5 → sase_github-0.2.0}/uv.lock +0 -0
@@ -10,8 +10,10 @@ permissions:
10
10
  contents: read
11
11
 
12
12
  env:
13
- SASE_CORE_REF: master
14
- SASE_CORE_PATH: .ci/sase
13
+ SASE_PYTHON_REF: master
14
+ SASE_PYTHON_PATH: .ci/sase
15
+ SASE_RUST_CORE_REF: master
16
+ SASE_RUST_CORE_PATH: .ci/sase-core
15
17
 
16
18
  jobs:
17
19
  lint:
@@ -22,15 +24,24 @@ jobs:
22
24
  uses: actions/checkout@v4
23
25
  with:
24
26
  repository: sase-org/sase
25
- ref: ${{ env.SASE_CORE_REF }}
26
- path: ${{ env.SASE_CORE_PATH }}
27
+ ref: ${{ env.SASE_PYTHON_REF }}
28
+ path: ${{ env.SASE_PYTHON_PATH }}
29
+ - name: Check out SASE Rust core
30
+ uses: actions/checkout@v4
31
+ with:
32
+ repository: sase-org/sase-core
33
+ ref: ${{ env.SASE_RUST_CORE_REF }}
34
+ path: ${{ env.SASE_RUST_CORE_PATH }}
27
35
  - uses: astral-sh/setup-uv@v4
28
36
  with:
29
37
  enable-cache: true
30
38
  cache-dependency-glob: "**/pyproject.toml"
31
39
  - uses: extractions/setup-just@v2
40
+ - uses: dtolnay/rust-toolchain@stable
32
41
  - name: Set up Python
33
- run: uv python install 3.12
42
+ run: |
43
+ uv python install 3.12
44
+ uv venv --python 3.12 .venv
34
45
  - name: Install dependencies
35
46
  run: just install
36
47
  - name: Lint
@@ -47,15 +58,24 @@ jobs:
47
58
  uses: actions/checkout@v4
48
59
  with:
49
60
  repository: sase-org/sase
50
- ref: ${{ env.SASE_CORE_REF }}
51
- path: ${{ env.SASE_CORE_PATH }}
61
+ ref: ${{ env.SASE_PYTHON_REF }}
62
+ path: ${{ env.SASE_PYTHON_PATH }}
63
+ - name: Check out SASE Rust core
64
+ uses: actions/checkout@v4
65
+ with:
66
+ repository: sase-org/sase-core
67
+ ref: ${{ env.SASE_RUST_CORE_REF }}
68
+ path: ${{ env.SASE_RUST_CORE_PATH }}
52
69
  - uses: astral-sh/setup-uv@v4
53
70
  with:
54
71
  enable-cache: true
55
72
  cache-dependency-glob: "**/pyproject.toml"
56
73
  - uses: extractions/setup-just@v2
74
+ - uses: dtolnay/rust-toolchain@stable
57
75
  - name: Set up Python ${{ matrix.python-version }}
58
- run: uv python install ${{ matrix.python-version }}
76
+ run: |
77
+ uv python install ${{ matrix.python-version }}
78
+ uv venv --python ${{ matrix.python-version }} .venv
59
79
  - name: Install dependencies
60
80
  run: just install
61
81
  - name: Run tests
@@ -12,8 +12,10 @@ on:
12
12
  default: false
13
13
 
14
14
  env:
15
- SASE_CORE_REF: master
16
- SASE_CORE_PATH: .ci/sase
15
+ SASE_PYTHON_REF: master
16
+ SASE_PYTHON_PATH: .ci/sase
17
+ SASE_RUST_CORE_REF: master
18
+ SASE_RUST_CORE_PATH: .ci/sase-core
17
19
 
18
20
  jobs:
19
21
  release:
@@ -60,6 +62,7 @@ jobs:
60
62
  permissions:
61
63
  contents: read
62
64
  steps:
65
+ - uses: actions/checkout@v4
63
66
  - uses: actions/download-artifact@v4
64
67
  with:
65
68
  name: dist
@@ -68,16 +71,25 @@ jobs:
68
71
  uses: actions/checkout@v4
69
72
  with:
70
73
  repository: sase-org/sase
71
- ref: ${{ env.SASE_CORE_REF }}
72
- path: ${{ env.SASE_CORE_PATH }}
74
+ ref: ${{ env.SASE_PYTHON_REF }}
75
+ path: ${{ env.SASE_PYTHON_PATH }}
76
+ - name: Check out SASE Rust core
77
+ uses: actions/checkout@v4
78
+ with:
79
+ repository: sase-org/sase-core
80
+ ref: ${{ env.SASE_RUST_CORE_REF }}
81
+ path: ${{ env.SASE_RUST_CORE_PATH }}
73
82
  - uses: astral-sh/setup-uv@v4
83
+ - uses: extractions/setup-just@v2
84
+ - uses: dtolnay/rust-toolchain@stable
74
85
  - name: Set up Python
75
86
  run: uv python install 3.12
76
87
  - name: Install built sase-github wheel into a fresh venv
77
88
  run: |
78
89
  uv venv --python 3.12 /tmp/smoke-venv
79
- uv pip install --python /tmp/smoke-venv/bin/python "${SASE_CORE_PATH}"
80
- uv pip install --python /tmp/smoke-venv/bin/python dist/*.whl
90
+ printf -- '-e %s\n' "$(realpath "${SASE_PYTHON_PATH}")" > /tmp/sase-overrides.txt
91
+ uv pip install --python /tmp/smoke-venv/bin/python --overrides /tmp/sase-overrides.txt dist/*.whl
92
+ just install-source-sase /tmp/smoke-venv/bin/python
81
93
  - name: Smoke check
82
94
  run: |
83
95
  /tmp/smoke-venv/bin/python - <<'PY'
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.0"
3
+ }
@@ -1,5 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0](https://github.com/sase-org/sase-github/compare/v0.1.7...v0.2.0) (2026-07-16)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **sdd:** GitHub workspace-provider integrations must use ws_preflight_sdd_sidecar and the sdd_sidecar_suffix/sidecar_suffix options.
9
+ * **sdd:** GitHub workspaces no longer fall back to local SDD storage; companion repository materialization must succeed before workspace claim.
10
+ * GitHub SDD discovery no longer falls back to <owner>/sdd by default. Set sdd.repo.name to sdd or owner/sdd to keep using an org-level companion repository.
11
+
12
+ ### Features
13
+
14
+ * add GitHub issue provider operations (sase-69.4) ([2b7bb90](https://github.com/sase-org/sase-github/commit/2b7bb90e1a0d6c70d835e4082a83fab6651ae146))
15
+ * add GitHub ref namespace completion (sase-5i.2) ([f318dbf](https://github.com/sase-org/sase-github/commit/f318dbfc7a04c7e8ed4411265c09481f2219aa35))
16
+ * add GitHub repo completion provider (sase-5h.2) ([bf28a38](https://github.com/sase-org/sase-github/commit/bf28a381db470b7d293f4ef4d046d0fac9f54238))
17
+ * add GitHub SDD companion repo creation (sase-5j.4) ([bd4c37a](https://github.com/sase-org/sase-github/commit/bd4c37a0755f0db7f6ec84913f322ab688138326))
18
+ * clone external GitHub repositories (sase-5y.2) ([b2e3a1a](https://github.com/sase-org/sase-github/commit/b2e3a1aae685c46aaf90b8b21bf6b1a712f775a2))
19
+ * create project-specific SDD companion repos ([1dff94c](https://github.com/sase-org/sase-github/commit/1dff94cad5142e6b4d62cc72fea805fbd7fecad3))
20
+ * create public SDD companions with labels ([975fbd3](https://github.com/sase-org/sase-github/commit/975fbd3176171de30ab44bc74bee7daa0ee66ed0))
21
+ * drop org-level SDD fallback discovery ([c76814d](https://github.com/sase-org/sase-github/commit/c76814d595bad186a484bbc0124fac8967491b1a))
22
+ * materialize GitHub SDD companion repos (sase-5j.3) ([4245691](https://github.com/sase-org/sase-github/commit/4245691e7551e75c0fbf09c29cfc7ae6f1506622))
23
+ * prefer owner sdd companion repos ([b5d31b1](https://github.com/sase-org/sase-github/commit/b5d31b1ef0eab4526783b71e242661bbe8ca222f))
24
+ * **sdd:** adopt sidecar terminology for SDD repositories (sase-5w.2) ([35fa968](https://github.com/sase-org/sase-github/commit/35fa968d585c0dd476aead6bb71b1276be85597d))
25
+ * **sdd:** enforce companion creation authorization ([69551b7](https://github.com/sase-org/sase-github/commit/69551b799fab83090d6680e653448efe190ec549))
26
+ * **sdd:** require companion repository storage ([5a2eb57](https://github.com/sase-org/sase-github/commit/5a2eb57bc044dd9945d54d52c7fa6eb0cf7e5dd9))
27
+ * support split SDD companion repositories (sase-5q.4) ([eb68a32](https://github.com/sase-org/sase-github/commit/eb68a327ad6dbeaade32855807c3582f0320e4b2))
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * make GitHub ref lookup credential-free ([8821154](https://github.com/sase-org/sase-github/commit/88211548c56df3ae539a175bbb49df8a5cdf26be))
33
+ * **projects:** align GitHub discovery with enabled lifecycle (sase-5w.1) ([ff08b5d](https://github.com/sase-org/sase-github/commit/ff08b5d9bd9dddb3934877bc16a5b2c8c7e163a5))
34
+ * refuse archived SDD repositories ([f5f5246](https://github.com/sase-org/sase-github/commit/f5f5246ade2152ae1c7c62c4baa765c248a7a234))
35
+ * reject mismatched sidecar repository remotes ([f333836](https://github.com/sase-org/sase-github/commit/f3338367c3d35d97ee3ea2828d08214197bb6385))
36
+ * require authorization for SDD repository creation ([f416ff3](https://github.com/sase-org/sase-github/commit/f416ff37ad8f72fe063dc98cf30faeca978c63ef))
37
+ * **sdd:** keep companion init alive when label creation is denied ([f9bd0b1](https://github.com/sase-org/sase-github/commit/f9bd0b16caf4a5d69ec5156af6cfd742371f0a75))
38
+
39
+ ## [0.1.7](https://github.com/sase-org/sase-github/compare/v0.1.6...v0.1.7) (2026-07-07)
40
+
41
+
42
+ ### Features
43
+
44
+ * use PR terminology for GitHub review hooks ([45cb817](https://github.com/sase-org/sase-github/commit/45cb817503216b4def7f4bd8ef752a285a781323))
45
+
46
+
47
+ ### Bug Fixes
48
+
49
+ * preserve canonical refs in GitHub resolution ([73e3c4b](https://github.com/sase-org/sase-github/commit/73e3c4b8e66e79911c305b6aad5677d658862830))
50
+
51
+ ## [0.1.6](https://github.com/sase-org/sase-github/compare/v0.1.5...v0.1.6) (2026-07-02)
52
+
53
+
54
+ ### Bug Fixes
55
+
56
+ * report closed GitHub PRs in submitted checks ([5ad2168](https://github.com/sase-org/sase-github/commit/5ad2168c1e36cca4b39e4435fff3076f3492dfb5))
57
+
58
+
59
+ ### Documentation
60
+
61
+ * drop `--python 3.12` pin from install commands ([4ecc344](https://github.com/sase-org/sase-github/commit/4ecc344987dd7609996d8ee9040a31e4adb7bb96))
62
+
3
63
  ## [0.1.5](https://github.com/sase-org/sase-github/compare/v0.1.4...v0.1.5) (2026-07-01)
4
64
 
5
65
 
@@ -0,0 +1,74 @@
1
+ # sase-github task runner
2
+
3
+ venv_dir := ".venv"
4
+ venv_bin := venv_dir / "bin"
5
+
6
+ default:
7
+ @just --list
8
+
9
+ _setup:
10
+ @[ -x {{ venv_bin }}/python ] || (uv venv {{ venv_dir }} && just install)
11
+
12
+ install-source-sase python:
13
+ @set -eu; \
14
+ sase_python_path="${SASE_PYTHON_PATH:-}"; \
15
+ sase_rust_core_path="${SASE_RUST_CORE_PATH:-}"; \
16
+ if [ -z "$sase_python_path" ] || [ -z "$sase_rust_core_path" ]; then \
17
+ printf '%s\n' \
18
+ 'SASE_PYTHON_PATH and SASE_RUST_CORE_PATH must be set together' >&2; \
19
+ exit 2; \
20
+ fi; \
21
+ sase_python_path="$(realpath "$sase_python_path")"; \
22
+ sase_rust_core_path="$(realpath "$sase_rust_core_path")"; \
23
+ python_dir="$(cd "$(dirname "{{ python }}")" && pwd)"; \
24
+ python_path="$python_dir/$(basename "{{ python }}")"; \
25
+ venv_path="$(dirname "$python_dir")"; \
26
+ uv pip install --python "$python_path" -e "$sase_python_path"; \
27
+ uv pip install --python "$python_path" maturin; \
28
+ ( \
29
+ cd "$sase_rust_core_path/crates/sase_core_py"; \
30
+ VIRTUAL_ENV="$venv_path" \
31
+ PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 \
32
+ "$venv_path/bin/maturin" develop --release; \
33
+ ); \
34
+ uv pip install --python "$python_path" --no-deps -e "$sase_python_path"
35
+
36
+ install:
37
+ @[ -x {{ venv_bin }}/python ] || uv venv {{ venv_dir }}
38
+ @set -eu; \
39
+ sase_python_path="${SASE_PYTHON_PATH:-}"; \
40
+ sase_rust_core_path="${SASE_RUST_CORE_PATH:-}"; \
41
+ if [ -z "$sase_python_path" ] && [ -z "$sase_rust_core_path" ]; then \
42
+ rm -f {{ venv_dir }}/sase-overrides.txt; \
43
+ uv pip install --python {{ venv_bin }}/python -e ".[dev]"; \
44
+ elif [ -z "$sase_python_path" ] || [ -z "$sase_rust_core_path" ]; then \
45
+ printf '%s\n' \
46
+ 'SASE_PYTHON_PATH and SASE_RUST_CORE_PATH must be set together' >&2; \
47
+ exit 2; \
48
+ else \
49
+ sase_python_path="$(realpath "$sase_python_path")"; \
50
+ venv_path="$(realpath {{ venv_dir }})"; \
51
+ printf -- '-e %s\n' "$sase_python_path" > "$venv_path/sase-overrides.txt"; \
52
+ uv pip install --python "$venv_path/bin/python" \
53
+ --overrides "$venv_path/sase-overrides.txt" -e ".[dev]"; \
54
+ just install-source-sase "$venv_path/bin/python"; \
55
+ fi
56
+
57
+ lint: _setup
58
+ {{ venv_bin }}/ruff check src/ tests/
59
+ {{ venv_bin }}/mypy
60
+
61
+ fmt: _setup
62
+ {{ venv_bin }}/ruff format src/ tests/
63
+ {{ venv_bin }}/ruff check --fix src/ tests/
64
+
65
+ test *args: _setup
66
+ {{ venv_bin }}/pytest {{ args }}
67
+
68
+ check: lint test
69
+
70
+ clean:
71
+ rm -rf build/ dist/ *.egg-info src/*.egg-info .mypy_cache/ .ruff_cache/ .pytest_cache/
72
+
73
+ build: _setup
74
+ {{ venv_bin }}/python -m build
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sase-github
3
- Version: 0.1.5
3
+ Version: 0.2.0
4
4
  Summary: GitHub VCS plugin for sase
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.12
8
- Requires-Dist: sase>=0.6.0
8
+ Requires-Dist: sase>=0.11.0
9
9
  Provides-Extra: dev
10
10
  Requires-Dist: mypy; extra == 'dev'
11
11
  Requires-Dist: pytest; extra == 'dev'
@@ -24,13 +24,14 @@ to the **Updates** tab (`5`, or `[` / `]`). Highlight `sase-github` in the plugi
24
24
  press `i` to install, and confirm the preview modal. The preview shows the exact `uv` command and resolved package set;
25
25
  the install runs as a tracked background task and is discovered on the next `sase` run.
26
26
 
27
- See the core SASE docs for the [Updates tab](https://github.com/sase-org/sase/blob/master/docs/configuration.md#updates-tab)
28
- and [`sase plugin` commands](https://github.com/sase-org/sase/blob/master/docs/plugins.md).
27
+ See the core SASE docs for the
28
+ [Updates tab](https://github.com/sase-org/sase/blob/master/docs/configuration.md#updates-tab) and
29
+ [`sase plugin` commands](https://github.com/sase-org/sase/blob/master/docs/plugins.md).
29
30
 
30
31
  ### Alternative: install SASE and the plugin together
31
32
 
32
33
  ```bash
33
- uv tool install sase --python 3.12 --with sase-github
34
+ uv tool install sase --with sase-github
34
35
  ```
35
36
 
36
37
  Repeat `--with` for additional plugins, for example `--with sase-github --with sase-telegram`. Add `--force` to replace
@@ -45,7 +46,7 @@ sase plugin install github
45
46
  `pip install sase-github` is only an escape hatch for non-managed or library-style environments. It is not the normal
46
47
  path for a `uv tool`-managed SASE command.
47
48
 
48
- Requires `sase>=0.1.3` as a dependency. For GitHub Enterprise Server or self-hosted GitHub, follow the
49
+ Requires `sase>=0.11.0` as a dependency. For GitHub Enterprise Server or self-hosted GitHub, follow the
49
50
  [GitHub Enterprise setup walkthrough](docs/configuration.md#github-enterprise-setup).
50
51
 
51
52
  ## What's Included
@@ -59,14 +60,21 @@ Requires `sase>=0.1.3` as a dependency. For GitHub Enterprise Server or self-hos
59
60
 
60
61
  - **GitHubWorkspacePlugin** — Workspace provider that handles GitHub-specific workflow orchestration: reference
61
62
  resolution (repo paths, project names, changespec names), PR submission via `gh pr merge`, branch management, and
62
- commit description formatting
63
+ commit description formatting. It also owns GitHub SDD policy: every GitHub project requires a labeled sidecar
64
+ repository, materialized before `#gh` work starts.
65
+ - **Repo completion for `#gh:<owner>/` refs** — Supplies repository candidates to SASE prompt completion by calling
66
+ `gh repo list <owner>`. Authenticated `gh` sessions include private repositories the user can access, and configured
67
+ GitHub Enterprise hosts are respected through `GH_HOST`.
68
+ - **Owner completion for `#gh:` refs** — Supplies local namespace candidates from active canonical GitHub project
69
+ records (`gh_<owner>__<repo>`) plus configured `github_orgs`, so accepting an owner can chain into repo completion
70
+ without a network call.
63
71
 
64
72
  ### Configuration
65
73
 
66
74
  - **`get_github_hosts()` / `get_default_github_host()`** — Read `github_hosts` from sase config to recognize GitHub
67
75
  Enterprise hosts and choose the default host for `#gh(owner/repo)` clone refs
68
76
  - **`get_github_orgs()`** — Reads `github_orgs` from sase config to determine SSH vs HTTPS clone URLs for
69
- organizations/users with push access
77
+ organizations/users with push access, and to seed local `#gh:` owner completion
70
78
 
71
79
  ### XPrompts
72
80
 
@@ -86,15 +94,24 @@ itself with sase core:
86
94
  - **`sase_xprompts`** — Makes GitHub xprompts discoverable via plugin discovery
87
95
 
88
96
  When sase detects a repository whose remote origin host is in the configured GitHub host set, it automatically loads
89
- `GitHubPlugin` and `GitHubWorkspacePlugin` to handle VCS operations like PR creation, branch management, commit
90
- workflows, and PR submission.
97
+ `GitHubPlugin` and `GitHubWorkspacePlugin` to handle VCS operations and provider-owned SDD storage. The first `#gh` or
98
+ For managed projects, `sase sdd init` finds or creates the public `<owner>/<repo>--plans` and `<owner>/<repo>--research`
99
+ sidecars and returns their provider metadata to SASE core. The same hooks retain `<owner>/<repo>--sdd` discovery for
100
+ legacy stores. Authentication, permission, network, repository creation, labeling, clone, or initial-push failures stop
101
+ setup; there is no GitHub-local SDD fallback.
102
+
103
+ The explicit `sase sdd init` flow first uses a read-only `gh repo view` preflight for each sidecar. Existing
104
+ sidecars connect without a creation prompt. Each missing sidecar requires a fresh, default-no interactive `y`/`yes`
105
+ response naming the full `--plans` or `--research` repository. Non-interactive stdin, EOF, interruption, and bare
106
+ `sase init --yes` cannot authorize creation.
91
107
 
92
108
  ## Requirements
93
109
 
94
110
  - Python 3.12+
95
- - [sase](https://github.com/sase-org/sase) >= 0.1.3
96
- - [gh](https://cli.github.com/) CLI (for GitHub API operations). For GitHub Enterprise, run
97
- `gh auth login --hostname <host>` for each configured Enterprise host.
111
+ - [sase](https://github.com/sase-org/sase) >= 0.11.0
112
+ - [gh](https://cli.github.com/) CLI (for GitHub API operations, mandatory sidecar repository setup, and `#gh:<owner>/`
113
+ repository completion). Run `gh auth login`; the account must be able to create the sidecar when it is missing and
114
+ manage its labels. For GitHub Enterprise, run `gh auth login --hostname <host>` for each configured Enterprise host.
98
115
 
99
116
  See [Configuration](docs/configuration.md) for `github_hosts`, `github_orgs`, workspace layout, and the ordered GitHub
100
117
  Enterprise setup flow.
@@ -111,8 +128,11 @@ just build # Build distribution packages
111
128
  just clean # Remove build artifacts
112
129
  ```
113
130
 
114
- Set `SASE_CORE_PATH=/path/to/sase` when you need development installs to use an editable SASE checkout before installing
115
- `sase-github`.
131
+ Set both `SASE_PYTHON_PATH=/path/to/sase` and `SASE_RUST_CORE_PATH=/path/to/sase-core` when development installs need to
132
+ use coordinated source checkouts. The Rust binding is built into the plugin virtual environment before the editable
133
+ SASE checkout is overlaid without dependencies. Leave both variables unset to use the ordinary published dependencies.
134
+ The same variables can be used with `just install-source-sase /path/to/venv/bin/python` to prepare another existing
135
+ virtual environment, such as an install-smoke environment.
116
136
 
117
137
  ## Project Structure
118
138
 
@@ -25,7 +25,7 @@ Extends `GitCommon` from sase core. Handles low-level VCS operations by wrapping
25
25
  | --------------------------- | ------------------------------------------------------------------------------------- |
26
26
  | `vcs_classify_repo()` | Claims repos whose origin host is in the configured GitHub host set |
27
27
  | `vcs_get_change_url()` | Returns PR URL via `gh pr view --json url` |
28
- | `vcs_get_cl_number()` | Returns PR number via `gh pr view --json number` |
28
+ | `vcs_get_pr_number()` | Returns PR number via `gh pr view --json number` |
29
29
  | `vcs_mail()` | Pushes branch (`git push -u origin`) and creates PR if needed (`gh pr create --fill`) |
30
30
  | `vcs_create_pull_request()` | Creates a PR with an AI-generated title and body |
31
31
 
@@ -41,14 +41,29 @@ Handles higher-level workflow orchestration. Implements workspace hooks for GitH
41
41
  | `ws_detect_workflow_type()` | Returns `"gh"` for repos with a remote origin URL (non-local) |
42
42
  | `ws_get_change_label()` | Returns `"PR"` for GitHub projects |
43
43
  | `ws_resolve_ref()` | Resolves `#gh` references (see [Reference Resolution](#reference-resolution)) |
44
+ | `ws_list_ref_namespaces()` | Lists local `#gh:` owner candidates from active canonical projects and config |
44
45
  | `ws_extract_change_identifier()` | Extracts PR number from GitHub PR URLs |
45
46
  | `ws_generate_submitted_check_script()` | Generates a bash script that checks if a PR is merged via `gh pr view` |
46
47
  | `ws_supports_reviewer_comments()` | Returns `False` for GitHub URLs (critique comments not supported) |
47
48
  | `ws_get_workspace_directory()` | Ensures git clone exists via `ensure_git_clone()` |
49
+ | `ws_preflight_sdd_sidecar()` | Read-only suffix-aware sidecar discovery for guarded explicit initialization |
50
+ | `ws_materialize_sdd_store()` | Finds or creates, labels, and stages a selected GitHub SDD sidecar |
51
+ | `ws_create_sdd_remote()` | Verifies or creates `--sdd`, `--plans`, or `--research` and returns its metadata |
48
52
  | `ws_prepare_mail()` | Displays branch/description and prompts user before pushing |
49
53
  | `ws_format_commit_description()` | Prepends `[project]` prefix to commit messages |
50
54
  | `ws_submit()` | Submits a ChangeSpec by merging its PR via `gh pr merge --merge --delete-branch` |
51
55
 
56
+ The provider declares `separate_repo` SDD policy. Core supplies a unique staging path; the plugin finds or creates the
57
+ selected sidecar, ensures its `sase--sdd` label, and clones with the normal SSH/HTTPS fallback. It returns only a
58
+ positive materialized record. SASE core owns legacy-artifact conflict checks, import, initial commit/push, atomic
59
+ adoption, and the durable primary-workspace record.
60
+
61
+ The explicit initializer calls `ws_preflight_sdd_sidecar()` before materialization. This hook may run `gh repo view`
62
+ but never creates or labels a repository, clones, or writes local state. Core then includes a per-invocation creation
63
+ authorization in materialization options: `False` after a found result and `True` only after the user answers `y` or
64
+ `yes` for a missing public sidecar. The provider checks this option immediately before both repository-creation
65
+ branches. Other materialization callers omit the option and retain provider-owned behavior.
66
+
52
67
  ## Reference Resolution
53
68
 
54
69
  The `resolve_gh_ref()` function supports three dispatch modes for `#gh` references:
@@ -91,6 +106,17 @@ When the ref matches an existing ChangeSpec:
91
106
  - Reads `WORKSPACE_DIR` from the changespec's project file
92
107
  - Checks out `origin/<name>` (the ChangeSpec's branch)
93
108
 
109
+ ## Ref Namespace Completion
110
+
111
+ For root ref completion after `#gh:`, `GitHubWorkspacePlugin` implements `ws_list_ref_namespaces()`. It returns GitHub
112
+ owner/org candidates from two local sources only:
113
+
114
+ - Active SASE project records whose directory keys use the canonical GitHub shape `gh_<owner>__<repo>`
115
+ - The configured `github_orgs` list
116
+
117
+ Record-derived owners show their active project count. Config-only owners show `from github_orgs`. Duplicate owners are
118
+ deduplicated case-insensitively, with record-derived spellings preferred when both sources include the same owner.
119
+
94
120
  ## Submission Flow
95
121
 
96
122
  When submitting a GitHub ChangeSpec (`ws_submit`):
@@ -4,19 +4,20 @@
4
4
 
5
5
  Use this checklist for GitHub Enterprise Server or another self-hosted GitHub host:
6
6
 
7
- 1. **Install SASE and `sase-github`.** Use the
8
- [README installation routes](../README.md#installation): the SASE Admin Center Updates tab is the recommended path
9
- for an existing managed install, while `uv tool install sase --python 3.12 --with sase-github` installs SASE and the
10
- plugin together. The core SASE [plugin docs](https://github.com/sase-org/sase/blob/master/docs/plugins.md) also cover
11
- `sase plugin install github` for existing installs.
7
+ 1. **Install SASE and `sase-github`.** Use the [README installation routes](../README.md#installation): the SASE Admin
8
+ Center Updates tab is the recommended path for an existing managed install, while
9
+ `uv tool install sase --with sase-github` installs SASE and the plugin together. The core SASE
10
+ [plugin docs](https://github.com/sase-org/sase/blob/master/docs/plugins.md) also cover `sase plugin install github`
11
+ for existing installs.
12
12
  2. **Authenticate `gh` to the Enterprise host.**
13
13
 
14
14
  ```bash
15
15
  gh auth login --hostname github.mycompany.com
16
16
  ```
17
17
 
18
- Repo-scoped `gh` commands auto-detect the host from the git remote, so this host-specific login is enough for PR
19
- operations once the repo is cloned.
18
+ Repo-scoped `gh` commands auto-detect the host from the git remote. The authenticated account must also be able to
19
+ create the mandatory SDD sidecar when missing and manage its `sase--sdd` label.
20
+
20
21
  3. **Set `github_hosts` in `~/.config/sase/sase.yml`.** **Put your Enterprise host first** if you want bare
21
22
  `#gh(owner/repo)` refs to clone from Enterprise. `github.com` is always included implicitly, but the first configured
22
23
  host is the default for bare refs; listing `github.com` first means bare refs default there instead. See
@@ -33,6 +34,10 @@ Use this checklist for GitHub Enterprise Server or another self-hosted GitHub ho
33
34
  Then resolve a repo with `#gh(owner/repo)`. Enterprise workspaces are namespaced by host under
34
35
  `~/projects/github/<host>/<user>/<project>/`; see [Workspace Layout](#workspace-layout).
35
36
 
37
+ Prompt completion for `#gh:<owner>/` uses the same default host through `GH_HOST`, so Enterprise repository lists
38
+ come from the first configured `github_hosts` entry. Authenticate the GitHub CLI to that host before relying on
39
+ completion for private repositories.
40
+
36
41
  ## `github_hosts`
37
42
 
38
43
  The `github_hosts` setting controls which GitHub hosts sase-github recognizes. Add it to your sase config file
@@ -47,8 +52,8 @@ github_hosts:
47
52
  **Effect:** sase-github claims repositories whose remote origin host matches one of these hosts. `github.com` is always
48
53
  included implicitly, so public GitHub keeps working even if you only configure an Enterprise host.
49
54
 
50
- The first configured host is the default for bare `#gh(owner/repo)` refs. With the example above,
51
- `#gh(my-org/my-repo)` clones from `github.mycompany.com`. If `github_hosts` is unset, the default host is `github.com`.
55
+ The first configured host is the default for bare `#gh(owner/repo)` refs. With the example above, `#gh(my-org/my-repo)`
56
+ clones from `github.mycompany.com`. If `github_hosts` is unset, the default host is `github.com`.
52
57
 
53
58
  Host entries are normalized, so pasted values such as `https://github.mycompany.com/` are accepted.
54
59
 
@@ -64,12 +69,15 @@ github_orgs:
64
69
  ```
65
70
 
66
71
  **Effect:** When cloning a repo whose owner is in this list, sase-github uses SSH
67
- (`git@<github-host>:user/project.git`). For all other repos, it uses HTTPS
68
- (`https://<github-host>/user/project.git`).
72
+ (`git@<github-host>:user/project.git`). For all other repos, it uses HTTPS (`https://<github-host>/user/project.git`).
69
73
 
70
74
  This matters because SSH URLs require an SSH key configured with GitHub, while HTTPS URLs work for public repos without
71
75
  authentication (but require a token for push access).
72
76
 
77
+ The same list also seeds local owner completion for `#gh:` prompts. SASE combines `github_orgs` with owners discovered
78
+ from active canonical GitHub project records named `gh_<owner>__<repo>`. This completion source is local-only; it does
79
+ not run `gh` or contact GitHub until you accept an owner and ask for repository completion with `#gh:<owner>/`.
80
+
73
81
  ## Default Config
74
82
 
75
83
  sase-github contributes a `default_config.yml` via the `sase_config` entry point. This is merged into the sase config
@@ -81,17 +89,31 @@ Currently the default config defines:
81
89
 
82
90
  ## Requirements
83
91
 
84
- - **`gh` CLI** — Required for all PR operations. Install from https://cli.github.com/ and authenticate with
85
- `gh auth login`. For GitHub Enterprise, authenticate to the configured host with
86
- `gh auth login --hostname github.mycompany.com`.
92
+ - **`gh` CLI** — Required for PR operations and mandatory SDD sidecar discovery, creation, and labeling. Install from
93
+ https://cli.github.com/ and authenticate with `gh auth login`; ensure the account can create the sidecar when
94
+ missing and manage its labels. It is also used for `#gh:<owner>/` repository completion via `gh repo list <owner>`,
95
+ including private repositories visible to the authenticated account. For GitHub Enterprise, authenticate to the
96
+ configured host with `gh auth login --hostname github.mycompany.com`.
87
97
  - **Git** — Standard git CLI for repository operations.
88
98
 
99
+ ## SDD sidecar repository
100
+
101
+ Managed projects use public `<owner>/<repo>--plans` and `<owner>/<repo>--research` sidecars. The legacy
102
+ `<owner>/<repo>--sdd` candidate and the `sdd.repo.name` override remain supported for unmigrated stores. `sase sdd init`
103
+ fails closed if discovery, creation, labeling, cloning, or the initial push fails. Fix `gh auth status`, repository
104
+ permissions, or network access and retry; SASE does not switch GitHub projects to a local store.
105
+
106
+ For explicit `sase sdd init`, authoritative read-only discovery precedes materialization. Each missing split sidecar
107
+ requires its own `y` or `yes` response at a default-no prompt naming visibility, full name, and host. Non-interactive
108
+ stdin and bare `sase init --yes` cannot grant it. A sidecar found during preflight receives no creation authorization,
109
+ so if it disappears before materialization the provider stops instead of silently recreating it.
110
+
89
111
  ## Workspace Layout
90
112
 
91
113
  Primary GitHub workspaces are stored under `~/projects/github/<user>/<project>/` when first resolved from a
92
114
  `#gh(user/project)` reference and the default host is `github.com`. For other default hosts, workspaces are namespaced
93
- by host at `~/projects/github/<host>/<user>/<project>/` to avoid collisions between same-named repos on different
94
- GitHub installations.
115
+ by host at `~/projects/github/<host>/<user>/<project>/` to avoid collisions between same-named repos on different GitHub
116
+ installations.
95
117
 
96
118
  Numbered parallel-work checkouts follow SASE's shared `workspace.root` policy: by default they live under the platform
97
119
  state-root namespace, while explicit `workspace.root: adjacent` keeps the legacy
@@ -21,7 +21,8 @@ the target branch, and captures diffs.
21
21
 
22
22
  ### Steps
23
23
 
24
- 1. **setup** — Resolves the `gh_ref` to a project file, workspace directory, and checkout target. Claims the workspace.
24
+ 1. **setup** — Resolves the `gh_ref`, ensures the checkout, materializes the mandatory GitHub SDD sidecar, and only
25
+ then claims the workspace. Sidecar setup failures stop the workflow before the claim or agent launch.
25
26
  2. **prepare** — Stashes uncommitted changes (including untracked files) and fetches from origin.
26
27
  3. **checkout** — Checks out the target branch/commit. Falls back to `master`/`main` for project refs. Pulls with
27
28
  rebase to sync with remote.
@@ -1,14 +1,15 @@
1
1
  [build-system]
2
- requires = ["hatchling"]
2
+ requires = ["hatchling>=1.27"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sase-github"
7
- version = "0.1.5"
7
+ version = "0.2.0"
8
8
  description = "GitHub VCS plugin for sase"
9
9
  requires-python = ">=3.12"
10
10
  license = "MIT"
11
- dependencies = ["sase>=0.6.0"]
11
+ license-files = ["LICENSE"]
12
+ dependencies = ["sase>=0.11.0"]
12
13
 
13
14
  [project.optional-dependencies]
14
15
  dev = [
@@ -0,0 +1,17 @@
1
+ """sase-github: GitHub VCS plugin for sase."""
2
+
3
+ from sase_github.errors import (
4
+ GitHubAuthenticationError,
5
+ GitHubIssueError,
6
+ GitHubRateLimitError,
7
+ )
8
+ from sase_github.plugin import GitHubPlugin
9
+ from sase_github.workspace_plugin import GitHubWorkspacePlugin
10
+
11
+ __all__ = [
12
+ "GitHubAuthenticationError",
13
+ "GitHubIssueError",
14
+ "GitHubPlugin",
15
+ "GitHubRateLimitError",
16
+ "GitHubWorkspacePlugin",
17
+ ]