sase-github 0.1.0__tar.gz → 0.1.1__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 (42) hide show
  1. {sase_github-0.1.0 → sase_github-0.1.1}/.github/workflows/ci.yml +18 -2
  2. sase_github-0.1.1/.github/workflows/pr-title.yml +31 -0
  3. sase_github-0.1.1/.github/workflows/publish.yml +125 -0
  4. sase_github-0.1.1/.release-please-manifest.json +3 -0
  5. sase_github-0.1.1/.sase_beads/beads.db +0 -0
  6. sase_github-0.1.1/.sase_beads/config.json +5 -0
  7. sase_github-0.1.1/CHANGELOG.md +63 -0
  8. {sase_github-0.1.0 → sase_github-0.1.1}/CLAUDE.md +2 -2
  9. {sase_github-0.1.0 → sase_github-0.1.1}/Justfile +6 -2
  10. {sase_github-0.1.0 → sase_github-0.1.1}/PKG-INFO +2 -2
  11. sase_github-0.1.1/README.md +107 -0
  12. sase_github-0.1.1/docs/architecture.md +105 -0
  13. sase_github-0.1.1/docs/configuration.md +55 -0
  14. sase_github-0.1.1/docs/xprompts.md +93 -0
  15. {sase_github-0.1.0 → sase_github-0.1.1}/pyproject.toml +8 -2
  16. sase_github-0.1.1/release-please-config.json +14 -0
  17. sase_github-0.1.1/src/sase_github/__init__.py +6 -0
  18. sase_github-0.1.1/src/sase_github/config.py +18 -0
  19. sase_github-0.1.1/src/sase_github/default_config.yml +1 -0
  20. sase_github-0.1.1/src/sase_github/plugin.py +121 -0
  21. sase_github-0.1.1/src/sase_github/scripts/__init__.py +0 -0
  22. sase_github-0.1.1/src/sase_github/scripts/gh_setup.py +75 -0
  23. sase_github-0.1.1/src/sase_github/scripts/new_pr_desc_get_context.py +88 -0
  24. sase_github-0.1.1/src/sase_github/workspace_plugin.py +763 -0
  25. sase_github-0.1.1/src/sase_github/xprompts/gh.yml +160 -0
  26. {sase_github-0.1.0 → sase_github-0.1.1}/src/sase_github/xprompts/new_pr_desc.yml +4 -1
  27. sase_github-0.1.1/src/sase_github/xprompts/pr_diff.yml +14 -0
  28. sase_github-0.1.1/src/sase_github/xprompts/prdd.yml +28 -0
  29. sase_github-0.1.1/tests/__init__.py +0 -0
  30. sase_github-0.1.1/tests/test_github_plugin.py +606 -0
  31. sase_github-0.1.1/tests/test_submit_with_recorded_pr.py +133 -0
  32. sase_github-0.1.1/tests/test_workspace_plugin.py +336 -0
  33. sase_github-0.1.1/uv.lock +1389 -0
  34. sase_github-0.1.0/.github/workflows/publish.yml +0 -32
  35. sase_github-0.1.0/README.md +0 -82
  36. sase_github-0.1.0/src/sase_github/__init__.py +0 -5
  37. sase_github-0.1.0/src/sase_github/plugin.py +0 -44
  38. sase_github-0.1.0/src/sase_github/xprompts/gh.yml +0 -87
  39. sase_github-0.1.0/src/sase_github/xprompts/pr.yml +0 -88
  40. sase_github-0.1.0/tests/test_github_plugin.py +0 -308
  41. /sase_github-0.1.0/tests/__init__.py → /sase_github-0.1.1/.sase_beads/issues.jsonl +0 -0
  42. {sase_github-0.1.0 → sase_github-0.1.1}/LICENSE +0 -0
@@ -2,18 +2,28 @@ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [main]
5
+ branches: [master]
6
6
  pull_request:
7
- branches: [main]
7
+ branches: [master]
8
8
 
9
9
  permissions:
10
10
  contents: read
11
11
 
12
+ env:
13
+ SASE_CORE_REF: v0.1.3
14
+ SASE_CORE_PATH: .ci/sase
15
+
12
16
  jobs:
13
17
  lint:
14
18
  runs-on: ubuntu-latest
15
19
  steps:
16
20
  - uses: actions/checkout@v4
21
+ - name: Check out SASE
22
+ uses: actions/checkout@v4
23
+ with:
24
+ repository: sase-org/sase
25
+ ref: ${{ env.SASE_CORE_REF }}
26
+ path: ${{ env.SASE_CORE_PATH }}
17
27
  - uses: astral-sh/setup-uv@v4
18
28
  with:
19
29
  enable-cache: true
@@ -33,6 +43,12 @@ jobs:
33
43
  python-version: ["3.12", "3.13"]
34
44
  steps:
35
45
  - uses: actions/checkout@v4
46
+ - name: Check out SASE
47
+ uses: actions/checkout@v4
48
+ with:
49
+ repository: sase-org/sase
50
+ ref: ${{ env.SASE_CORE_REF }}
51
+ path: ${{ env.SASE_CORE_PATH }}
36
52
  - uses: astral-sh/setup-uv@v4
37
53
  with:
38
54
  enable-cache: true
@@ -0,0 +1,31 @@
1
+ name: PR Title
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [master]
6
+ types: [opened, edited, reopened, ready_for_review, synchronize]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ conventional-title:
13
+ name: Conventional PR title
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Validate squash-merge title
17
+ env:
18
+ PR_TITLE: ${{ github.event.pull_request.title }}
19
+ run: |
20
+ set -euo pipefail
21
+
22
+ allowed_types='feat|fix|perf|docs|ci|test|chore|refactor|build|deps'
23
+ pattern="^(${allowed_types})(\([A-Za-z0-9._/-]+\))?!?: [^[:space:]].*"
24
+
25
+ if [[ ! "${PR_TITLE}" =~ ${pattern} ]]; then
26
+ printf 'PR title must follow Conventional Commits so squash merges produce useful release metadata.\n' >&2
27
+ printf 'Allowed types: feat, fix, perf, docs, ci, test, chore, refactor, build, deps.\n' >&2
28
+ printf 'Examples: fix(release): add release workflow, feat!: remove legacy config.\n' >&2
29
+ printf 'Actual title: %s\n' "${PR_TITLE}" >&2
30
+ exit 1
31
+ fi
@@ -0,0 +1,125 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ workflow_dispatch:
7
+ inputs:
8
+ publish_existing:
9
+ description: Publish the existing release artifacts for the version on master
10
+ required: true
11
+ type: boolean
12
+ default: false
13
+
14
+ env:
15
+ SASE_CORE_REF: v0.1.3
16
+ SASE_CORE_PATH: .ci/sase
17
+
18
+ jobs:
19
+ release:
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: write
23
+ issues: write
24
+ pull-requests: write
25
+ outputs:
26
+ release_created: ${{ steps.release.outputs.release_created || 'false' }}
27
+ steps:
28
+ - uses: googleapis/release-please-action@v5
29
+ if: ${{ github.event_name == 'push' }}
30
+ id: release
31
+ with:
32
+ token: ${{ secrets.SASE_RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
33
+ config-file: release-please-config.json
34
+ manifest-file: .release-please-manifest.json
35
+
36
+ build:
37
+ needs: release
38
+ if: ${{ needs.release.outputs.release_created == 'true' || (github.event_name == 'workflow_dispatch' && inputs.publish_existing == true) }}
39
+ runs-on: ubuntu-latest
40
+ permissions:
41
+ contents: read
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: astral-sh/setup-uv@v4
45
+ with:
46
+ enable-cache: true
47
+ cache-dependency-glob: "**/pyproject.toml"
48
+ - name: Set up Python
49
+ run: uv python install 3.12
50
+ - name: Build package
51
+ run: uv build
52
+ - uses: actions/upload-artifact@v4
53
+ with:
54
+ name: dist
55
+ path: dist/
56
+
57
+ install-smoke:
58
+ needs: build
59
+ runs-on: ubuntu-latest
60
+ permissions:
61
+ contents: read
62
+ steps:
63
+ - uses: actions/download-artifact@v4
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+ - name: Check out SASE
68
+ uses: actions/checkout@v4
69
+ with:
70
+ repository: sase-org/sase
71
+ ref: ${{ env.SASE_CORE_REF }}
72
+ path: ${{ env.SASE_CORE_PATH }}
73
+ - uses: astral-sh/setup-uv@v4
74
+ - name: Set up Python
75
+ run: uv python install 3.12
76
+ - name: Install built sase-github wheel into a fresh venv
77
+ run: |
78
+ 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
81
+ - name: Smoke check
82
+ run: |
83
+ /tmp/smoke-venv/bin/python - <<'PY'
84
+ from importlib.metadata import entry_points
85
+
86
+ import sase_github
87
+
88
+ expected = {
89
+ "sase_vcs": {"github": "sase_github.plugin:GitHubPlugin"},
90
+ "sase_workspace": {
91
+ "github": "sase_github.workspace_plugin:GitHubWorkspacePlugin"
92
+ },
93
+ "sase_config": {"sase_github": "sase_github"},
94
+ "sase_xprompts": {"sase_github": "sase_github"},
95
+ }
96
+
97
+ discovered = entry_points()
98
+ for group, entries in expected.items():
99
+ group_entries = {
100
+ entry_point.name: entry_point.value
101
+ for entry_point in discovered.select(group=group)
102
+ }
103
+ for name, value in entries.items():
104
+ actual = group_entries.get(name)
105
+ if actual != value:
106
+ raise SystemExit(
107
+ f"{group} entry point {name!r}: expected {value!r}, got {actual!r}"
108
+ )
109
+
110
+ assert sase_github
111
+ PY
112
+
113
+ publish:
114
+ needs: [release, build, install-smoke]
115
+ if: ${{ needs.release.outputs.release_created == 'true' || (github.event_name == 'workflow_dispatch' && inputs.publish_existing == true) }}
116
+ runs-on: ubuntu-latest
117
+ environment: pypi
118
+ permissions:
119
+ id-token: write
120
+ steps:
121
+ - uses: actions/download-artifact@v4
122
+ with:
123
+ name: dist
124
+ path: dist/
125
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.1"
3
+ }
Binary file
@@ -0,0 +1,5 @@
1
+ {
2
+ "issue_prefix": "sase-github",
3
+ "next_counter": 1,
4
+ "owner": "bryanbugyi34@gmail.com"
5
+ }
@@ -0,0 +1,63 @@
1
+ # Changelog
2
+
3
+ ## 0.1.1 (2026-06-09)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add #prdd xprompt tagged with append_to_commit_and_propose ([cc29edd](https://github.com/sase-org/sase-github/commit/cc29eddaaad0e9dbdef90e045dc8e3bb046e7dbd))
9
+ * Add can_rename_branch override returning False ([f60d739](https://github.com/sase-org/sase-github/commit/f60d739b5278a625c39972aab748b736775a6d20))
10
+ * Add default_config.yml with pr_diff xprompt and sase_config entry point ([d1e9592](https://github.com/sase-org/sase-github/commit/d1e9592fb5f81954335b90d7747931c262f440cb))
11
+ * add descriptions to GitHub xprompts (sase-3w.5) ([ceb2c51](https://github.com/sase-org/sase-github/commit/ceb2c51bdd491a09c4128507fb6e6ee5e2772375))
12
+ * Add finally: true to release and diff steps in gh workflow ([3b7786e](https://github.com/sase-org/sase-github/commit/3b7786e734f9b256f745435daf78b29f297eb9a4))
13
+ * Add GitHubWorkspacePlugin and migrate scripts from sase core ([b6e1499](https://github.com/sase-org/sase-github/commit/b6e1499de165a6d0b22bbb39207e4ae913ee7954))
14
+ * Add LLM provider model name and agent name to PR description ([8a22569](https://github.com/sase-org/sase-github/commit/8a225697ba94bc23e6b78361d8ce371d693899e5))
15
+ * Add post-cleanup git pull to #gh xprompt workflow ([96bdc31](https://github.com/sase-org/sase-github/commit/96bdc31ad241f8a505055b3a8e2fc524cffb265d))
16
+ * Add rollover tag to gh VCS xprompt workflow ([661200c](https://github.com/sase-org/sase-github/commit/661200c32b0a9d724d98d006b36d88518c71b4e0))
17
+ * Add VCS check hooks for GitHub workspace plugin ([cd43132](https://github.com/sase-org/sase-github/commit/cd43132898038b96150a68b2216d30afcae8a696))
18
+ * Add VCS commit dispatch hooks (vcs_create_commit, vcs_create_proposal, vcs_create_pull_request) with tests (sase-a.1) ([1147d77](https://github.com/sase-org/sase-github/commit/1147d77ad77113c85feba7be3d17a0aa0fca3b10))
19
+ * Add vcs_classify_repo hook to claim repos with github.com URLs ([5098353](https://github.com/sase-org/sase-github/commit/50983531c226fb7d6977b5b1fe526cba11b8f473))
20
+ * Add vcs_get_change_body hook implementation ([d264a57](https://github.com/sase-org/sase-github/commit/d264a572657cd2a95e2858bf1872f13b1894377d))
21
+ * Add workflow_label to #gh xprompt for descriptive RUNNING field names ([3020428](https://github.com/sase-org/sase-github/commit/3020428201e0714052f9ac51e3b5e2972b2bd102))
22
+ * Add wraps_all flag to gh xprompt (sase-4.2) ([fd56d9c](https://github.com/sase-org/sase-github/commit/fd56d9cf7114fb763e07d8b05a8172b9ee355ef2))
23
+ * Add ws_prepare_mail hookimpl for GitHub git mail prep ([8865801](https://github.com/sase-org/sase-github/commit/886580159a80c5fba6a285975459547e6987b52d))
24
+ * allocate GitHub project aliases on first use (sase-4d.2) ([3fa99c8](https://github.com/sase-org/sase-github/commit/3fa99c8cc44825581c3ecd8a281402d2d9a087e2))
25
+ * Allow slash as VCS ref separator in #gh pattern ([e126779](https://github.com/sase-org/sase-github/commit/e126779256305df3e22cef8fb804f22899aa8111))
26
+ * Allow underscore as VCS ref separator (#gh_sase = #gh:sase) ([46aaabf](https://github.com/sase-org/sase-github/commit/46aaabf7ccfb7a75c085cc3ef4a381a97c09e487))
27
+ * Create %gh runner provider (%w:sase-yyyx.4) ([db2878d](https://github.com/sase-org/sase-github/commit/db2878d7af28c9b80d25c796fd5986cd3d079566))
28
+ * Data-Driven VCS Family Mapping + running_field.py Cleanup ([7128545](https://github.com/sase-org/sase-github/commit/7128545b5f681efb31b3df6f2828d900d4ac0190))
29
+ * Fix #pr branch naming and #gh checkout for project names ([f2c84dc](https://github.com/sase-org/sase-github/commit/f2c84dcb9b526e477f187869de8e481af7c65370))
30
+ * Implement vcs_abandon_change hook to close PRs during revert/archive (sase-c.2) ([94f3902](https://github.com/sase-org/sase-github/commit/94f3902b3432ff0d308ea076399ea520cffbbc9a))
31
+ * Implement ws_get_workflow_metadata hook for GitHub plugin ([39d6513](https://github.com/sase-org/sase-github/commit/39d65139c107fd7205232d20a765608f7e5de1ed))
32
+ * Implement ws_get_workspace_directory and ws_format_commit_description hooks ([393e77d](https://github.com/sase-org/sase-github/commit/393e77d21eaa4b1f1402a6d6a77e89697dfb3cd1))
33
+ * Inherit some VCS hooks from the common git impl ([879cd47](https://github.com/sase-org/sase-github/commit/879cd475549281c5a3c667d27de0a284ced9531f))
34
+ * Initial sase-github plugin package ([5372725](https://github.com/sase-org/sase-github/commit/537272566798840ec725169ecf676838b630854e))
35
+ * Make #pr fail fast when not on right branch ([eb475ba](https://github.com/sase-org/sase-github/commit/eb475baf24a86a522ded541f8911519a6f6a6dc6))
36
+ * prefer .sase project spec extension with legacy .gp fallback (sase-33.5a) (sase-33) ([9340d36](https://github.com/sase-org/sase-github/commit/9340d3676f0c15bd6b67dfa8d4b9da2372523e7a))
37
+ * Replace github_username with github_orgs list config ([11420cf](https://github.com/sase-org/sase-github/commit/11420cfbdc1b0c65601c11a6ca77b9eba3f05b3c))
38
+ * Skip prdd xprompt expansion on default branch ([add1609](https://github.com/sase-org/sase-github/commit/add160966c8803a8af6c278f701fa53a6d1d329b))
39
+ * Support use_project_pr_prefix config for PR title prefixing ([21a76b7](https://github.com/sase-org/sase-github/commit/21a76b7d2fe04c5bef523dd585062ad459d89619))
40
+ * Use _pr_body payload field for PR description body ([e3f48c7](https://github.com/sase-org/sase-github/commit/e3f48c75ed3dbf133f588ba763491a1e50ee7972))
41
+ * Use commit message body as PR description when available ([ecabacd](https://github.com/sase-org/sase-github/commit/ecabacd1ae5797475379fa21b2e41b60658054ab))
42
+
43
+
44
+ ### Bug Fixes
45
+
46
+ * #pr_diff showing unrelated file changes ([1c7cc23](https://github.com/sase-org/sase-github/commit/1c7cc23b9c219102fde9e30d867f0113a13c6708))
47
+ * Add explicit git push and robust URL extraction to #pr workflow ([b4da722](https://github.com/sase-org/sase-github/commit/b4da7226372b0722b93b0faf57eaa717bb5308c1))
48
+ * Add vcs_provider_name='github' to workspace plugin metadata ([05f5f1e](https://github.com/sase-org/sase-github/commit/05f5f1e18e64232c69ab4f87ed7ea130b80d3729))
49
+ * Checkout CL branch in #gh workflow before agent runs ([32163e0](https://github.com/sase-org/sase-github/commit/32163e0298a83e424b3ceb6e07aa933a0281e4ba))
50
+ * Emit meta_new_pr output so PR URL appears in ace TUI metadata panel ([83de875](https://github.com/sase-org/sase-github/commit/83de8753bbf3557b8c647fcbcdb69196dacff056))
51
+ * Fix PR description footer newline between Model and Agent lines ([087f9fd](https://github.com/sase-org/sase-github/commit/087f9fdd53356d22e1a011b3307229b5733510b0))
52
+ * Handle existing branch in #pr workflow create_branch step ([d5a212a](https://github.com/sase-org/sase-github/commit/d5a212a469a61ad7bbbd02f8681501ced90cbc50))
53
+ * Handle remote branch already existing in pr create_branch step ([b3a8196](https://github.com/sase-org/sase-github/commit/b3a81964c39b2e4c20a8aa87c6d28aec04f641c3))
54
+ * Inline pr_diff logic into prdd.yml so #pr_diff expands correctly ([28c428c](https://github.com/sase-org/sase-github/commit/28c428c3445a962d6682b1cd2fc652542896cae3))
55
+ * Make #prdd not show when not in a git repo ([8742394](https://github.com/sase-org/sase-github/commit/87423942a35fd90599c7f8908717e83c5b42bca4))
56
+ * Remove pipefail from #pr create_branch step (incompatible with dash) ([fceee3e](https://github.com/sase-org/sase-github/commit/fceee3e8ae7441c30a6dd756783ac63a286e0e55))
57
+ * Stash and pull as pre-step ([bbd8488](https://github.com/sase-org/sase-github/commit/bbd8488648d213059b88d0d9a1f2b50f7b656565))
58
+ * update callers for removed ensure_git_clone wrapper ([8a21fc2](https://github.com/sase-org/sase-github/commit/8a21fc2e63a4b8306552f1059746ac814d7864b3))
59
+ * Update stale test mocks for commit, proposal, and PR tests ([2bee80d](https://github.com/sase-org/sase-github/commit/2bee80d81bb37bb2fa9322d90684d9b2ceda073a))
60
+ * Update test to match new branch-reuse behavior in #pr workflow ([1ef7569](https://github.com/sase-org/sase-github/commit/1ef7569ce56833c8bb4b482b78dd21108442fb15))
61
+ * Use comma separator for multi-value xprompt tags in gh.yml ([1204d2b](https://github.com/sase-org/sase-github/commit/1204d2b95ab3ea302e5f5687eff2296dd0c2d47f))
62
+ * Use parent PID in gh_setup to prevent stale RUNNING entry cleanup ([09d0703](https://github.com/sase-org/sase-github/commit/09d07039ed59028d1dc4230b582bbb5ae21c2bfd))
63
+ * Use recorded PR URL for submit instead of branch heuristics ([e0f5013](https://github.com/sase-org/sase-github/commit/e0f5013636df527f9607bd6a269df606f8319788))
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
  GitHub VCS plugin for sase. Provides GitHubPlugin (PR creation, gh CLI integration)
5
- and GitHub-related xprompts (#gh, #pr, #new_pr_desc).
5
+ and GitHub-related xprompts (#gh, #new_pr_desc).
6
6
 
7
7
  ## Build & Run
8
8
  ```bash
@@ -16,7 +16,7 @@ just check # lint + test
16
16
  ## Architecture
17
17
  - `src/sase_github/plugin.py` — GitHubPlugin class (extends `sase.vcs_provider.plugins._git_common.GitCommon`)
18
18
  - `src/sase_github/xprompts/` — GitHub workflow YAML files discovered via `sase_xprompts` entry point
19
- - Depends on `sase>=0.1.0` for base classes, hookspec, and script modules
19
+ - Depends on `sase>=0.1.3` for base classes, hookspec, and script modules
20
20
 
21
21
  ## Code Conventions
22
22
  - Absolute imports: `from sase_github.plugin import GitHubPlugin`
@@ -7,9 +7,13 @@ default:
7
7
  @just --list
8
8
 
9
9
  _setup:
10
- @[ -x {{ venv_bin }}/python ] || (uv venv {{ venv_dir }} && uv pip install -e ".[dev]")
10
+ @[ -x {{ venv_bin }}/python ] || (uv venv {{ venv_dir }} && just install)
11
11
 
12
- install: _setup
12
+ install:
13
+ @[ -x {{ venv_bin }}/python ] || uv venv {{ venv_dir }}
14
+ @if [ -n "${SASE_CORE_PATH:-}" ]; then \
15
+ uv pip install -e "${SASE_CORE_PATH}"; \
16
+ fi
13
17
  uv pip install -e ".[dev]"
14
18
 
15
19
  lint: _setup
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sase-github
3
- Version: 0.1.0
3
+ Version: 0.1.1
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.1.0
8
+ Requires-Dist: sase>=0.1.3
9
9
  Provides-Extra: dev
10
10
  Requires-Dist: mypy; extra == 'dev'
11
11
  Requires-Dist: pytest; extra == 'dev'
@@ -0,0 +1,107 @@
1
+ # sase-github — GitHub VCS Plugin for sase
2
+
3
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
4
+ [![mypy](https://img.shields.io/badge/type_checker-mypy-blue.svg)](https://mypy-lang.org/)
5
+ [![pytest](https://img.shields.io/badge/tests-pytest-blue.svg)](https://docs.pytest.org/)
6
+
7
+ ## Overview
8
+
9
+ **sase-github** is a plugin for [sase](https://github.com/sase-org/sase) that adds GitHub-specific VCS and workspace
10
+ support. It provides the `GitHubPlugin` VCS provider and `GitHubWorkspacePlugin` workspace provider for GitHub-hosted
11
+ repositories, integrating with the `gh` CLI for pull request creation, management, and submission, along with
12
+ GitHub-specific xprompt workflows.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install sase-github
18
+ ```
19
+
20
+ Or with [uv](https://docs.astral.sh/uv/):
21
+
22
+ ```bash
23
+ uv pip install sase-github
24
+ ```
25
+
26
+ Requires `sase>=0.1.3` as a dependency (installed automatically).
27
+
28
+ ## What's Included
29
+
30
+ ### VCS Provider
31
+
32
+ - **GitHubPlugin** — GitHub VCS provider that extends `GitCommon` with `gh` CLI integration for PR workflows (push,
33
+ create PR, retrieve PR URL/number)
34
+
35
+ ### Workspace Provider
36
+
37
+ - **GitHubWorkspacePlugin** — Workspace provider that handles GitHub-specific workflow orchestration: reference
38
+ resolution (repo paths, project names, changespec names), PR submission via `gh pr merge`, branch management, and
39
+ commit description formatting
40
+
41
+ ### Configuration
42
+
43
+ - **`get_github_orgs()`** — Reads `github_orgs` from sase config to determine SSH vs HTTPS clone URLs for
44
+ organizations/users with push access
45
+
46
+ ### XPrompts
47
+
48
+ | XPrompt | Description |
49
+ | -------------- | ---------------------------------------------------------------------------------- |
50
+ | `#gh` | GitHub workflow orchestration — resolves refs, claims workspaces, manages branches |
51
+ | `#new_pr_desc` | AI-generated PR descriptions from commit diffs |
52
+ | `#prdd` | Injects PR diff and description as context (auto-appended on feature branches) |
53
+
54
+ ## How It Works
55
+
56
+ sase-github uses Python [entry points](https://packaging.python.org/en/latest/specifications/entry-points/) to register
57
+ itself with sase core:
58
+
59
+ - **`sase_vcs`** — Registers `GitHubPlugin` as the `github` VCS provider
60
+ - **`sase_workspace`** — Registers `GitHubWorkspacePlugin` as the `github` workspace provider
61
+ - **`sase_xprompts`** — Makes GitHub xprompts discoverable via plugin discovery
62
+
63
+ When sase detects a GitHub-hosted repository (via `gh` CLI), it automatically loads `GitHubPlugin` and
64
+ `GitHubWorkspacePlugin` to handle VCS operations like PR creation, branch management, commit workflows, and PR
65
+ submission.
66
+
67
+ ## Requirements
68
+
69
+ - Python 3.12+
70
+ - [sase](https://github.com/sase-org/sase) >= 0.1.3
71
+ - [gh](https://cli.github.com/) CLI (for GitHub API operations)
72
+
73
+ ## Development
74
+
75
+ ```bash
76
+ just install # Install in editable mode with dev deps
77
+ just fmt # Auto-format code
78
+ just lint # Run ruff + mypy
79
+ just test # Run tests
80
+ just check # All checks (lint + test)
81
+ just build # Build distribution packages
82
+ just clean # Remove build artifacts
83
+ ```
84
+
85
+ Set `SASE_CORE_PATH=/path/to/sase` when you need development installs to use an editable SASE checkout before installing
86
+ `sase-github`.
87
+
88
+ ## Project Structure
89
+
90
+ ```
91
+ src/sase_github/
92
+ ├── __init__.py # Package exports
93
+ ├── plugin.py # GitHubPlugin VCS implementation
94
+ ├── workspace_plugin.py # GitHubWorkspacePlugin workspace implementation
95
+ ├── config.py # GitHub config helpers (org/user list)
96
+ ├── scripts/
97
+ │ ├── gh_setup.py # Setup step for #gh workflow
98
+ │ └── new_pr_desc_get_context.py # Context retrieval for PR description generation
99
+ └── xprompts/
100
+ ├── gh.yml # GitHub workflow orchestration
101
+ ├── new_pr_desc.yml # PR description generation
102
+ └── prdd.yml # PR description detail injection
103
+ ```
104
+
105
+ ## License
106
+
107
+ MIT
@@ -0,0 +1,105 @@
1
+ # Architecture
2
+
3
+ sase-github is structured as two pluggy-based plugins that integrate with sase core via Python entry points.
4
+
5
+ ## Plugin System
6
+
7
+ ### Entry Points
8
+
9
+ Registered in `pyproject.toml`:
10
+
11
+ | Entry Point | Plugin | Purpose |
12
+ |---|---|---|
13
+ | `sase_vcs:github` | `GitHubPlugin` | VCS operations (push, PR creation, PR info) |
14
+ | `sase_workspace:github` | `GitHubWorkspacePlugin` | Workspace orchestration (ref resolution, submission, mail prep) |
15
+ | `sase_xprompts:sase_github` | — | Makes `#gh`, `#new_pr_desc`, `#prdd` xprompts discoverable |
16
+ | `sase_config:sase_github` | — | Contributes `default_config.yml` to the sase config chain |
17
+
18
+ ### GitHubPlugin (`plugin.py`)
19
+
20
+ Extends `GitCommon` from sase core. Handles low-level VCS operations by wrapping `git` and `gh` CLI commands.
21
+
22
+ **Hook implementations:**
23
+
24
+ | Hook | Behavior |
25
+ |---|---|
26
+ | `vcs_classify_repo()` | Claims repos with `github.com` in their origin URL |
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` |
29
+ | `vcs_mail()` | Pushes branch (`git push -u origin`) and creates PR if needed (`gh pr create --fill`) |
30
+ | `vcs_create_pull_request()` | Creates a PR with an AI-generated title and body |
31
+
32
+ ### GitHubWorkspacePlugin (`workspace_plugin.py`)
33
+
34
+ Handles higher-level workflow orchestration. Implements workspace hooks for GitHub-hosted projects.
35
+
36
+ **Hook implementations:**
37
+
38
+ | Hook | Behavior |
39
+ |---|---|
40
+ | `ws_get_workflow_metadata()` | Returns metadata for the `gh` workflow type (ref pattern `#gh`, vcs family `git`) |
41
+ | `ws_detect_workflow_type()` | Returns `"gh"` for repos with a remote origin URL (non-local) |
42
+ | `ws_get_change_label()` | Returns `"PR"` for GitHub projects |
43
+ | `ws_resolve_ref()` | Resolves `#gh` references (see [Reference Resolution](#reference-resolution)) |
44
+ | `ws_extract_change_identifier()` | Extracts PR number from GitHub PR URLs |
45
+ | `ws_generate_submitted_check_script()` | Generates a bash script that checks if a PR is merged via `gh pr view` |
46
+ | `ws_supports_reviewer_comments()` | Returns `False` for GitHub URLs (critique comments not supported) |
47
+ | `ws_get_workspace_directory()` | Ensures git clone exists via `ensure_git_clone()` |
48
+ | `ws_prepare_mail()` | Displays branch/description and prompts user before pushing |
49
+ | `ws_format_commit_description()` | Prepends `[project]` prefix to commit messages |
50
+ | `ws_submit()` | Submits a ChangeSpec by merging its PR via `gh pr merge --merge --delete-branch` |
51
+
52
+ ## Reference Resolution
53
+
54
+ The `resolve_gh_ref()` function supports three dispatch modes for `#gh` references:
55
+
56
+ ### Mode 1: Repo Path (`user/project`)
57
+
58
+ When the ref contains `/`, it's treated as a GitHub repo path:
59
+
60
+ - Derives workspace from `~/projects/github/<user>/<project>/`
61
+ - Clones the repo if it doesn't exist (SSH for orgs in `github_orgs`, HTTPS otherwise)
62
+ - Reuses an existing SASE ProjectSpec whose normalized `WORKSPACE_DIR` already points at that workspace
63
+ - Otherwise creates a canonical project name from the repo identity, normally `gh_<user>__<project>`
64
+ - Adds a deterministic suffix such as `-2` only if that canonical project name is already occupied by a different
65
+ project or alias
66
+ - Sets `WORKSPACE_DIR` in the canonical project file
67
+ - Ensures a useful short alias for the repo basename, suffixing duplicate basenames as `<project>-2`, `<project>-3`,
68
+ and higher
69
+ - Checks out the default branch
70
+
71
+ This preserves legacy basename projects. If `~/.sase/projects/foo/foo.sase` already points at
72
+ `~/projects/github/foo-org/foo/`, resolving `#gh:foo-org/foo` keeps using project `foo`; it does not rename or migrate
73
+ the ProjectSpec.
74
+
75
+ ### Mode 2: Project Shorthand (`myproject`)
76
+
77
+ When the ref matches an existing project directory or project alias:
78
+
79
+ - Resolves aliases before project-directory lookup, so a generated alias like `foo-2` points at its canonical project
80
+ - Looks up `~/.sase/projects/<name>/<name>.sase` (legacy `.gp` is read as a fallback)
81
+ - Reads `WORKSPACE_DIR` from the project file
82
+ - Checks out the default branch
83
+
84
+ ### Mode 3: ChangeSpec Name
85
+
86
+ When the ref matches an existing ChangeSpec:
87
+ - Searches all changespecs for a matching name
88
+ - Reads `WORKSPACE_DIR` from the changespec's project file
89
+ - Checks out `origin/<name>` (the ChangeSpec's branch)
90
+
91
+ ## Submission Flow
92
+
93
+ When submitting a GitHub ChangeSpec (`ws_submit`):
94
+
95
+ 1. Kill and persist all running processes on the ChangeSpec
96
+ 2. Verify no active child ChangeSpecs exist
97
+ 3. Claim a workspace and checkout the ChangeSpec branch
98
+ 4. Check for an existing PR on the branch
99
+ 5. Merge via `gh pr merge --merge --delete-branch`
100
+ 6. Finalize submission (update ChangeSpec status)
101
+ 7. Release the workspace
102
+
103
+ ## Config Helper
104
+
105
+ `config.py` provides `get_github_orgs()` which reads the `github_orgs` list from the merged sase config. This determines whether repos are cloned via SSH (for orgs the user has push access to) or HTTPS.
@@ -0,0 +1,55 @@
1
+ # Configuration
2
+
3
+ ## `github_orgs`
4
+
5
+ The `github_orgs` setting controls how sase-github clones repositories. Add it to your sase config file
6
+ (`~/.config/sase/sase.yml`):
7
+
8
+ ```yaml
9
+ github_orgs:
10
+ - your-username
11
+ - your-org
12
+ ```
13
+
14
+ **Effect:** When cloning a repo whose owner is in this list, sase-github uses SSH (`git@github.com:user/project.git`).
15
+ For all other repos, it uses HTTPS (`https://github.com/user/project.git`).
16
+
17
+ This matters because SSH URLs require an SSH key configured with GitHub, while HTTPS URLs work for public repos without
18
+ authentication (but require a token for push access).
19
+
20
+ ## Default Config
21
+
22
+ sase-github contributes a `default_config.yml` via the `sase_config` entry point. This is merged into the sase config
23
+ chain between sase core defaults and your user config.
24
+
25
+ Currently the default config defines:
26
+
27
+ - `xprompts.pr_diff` — an xprompt that expands to the diff of the current PR's changes
28
+
29
+ ## Requirements
30
+
31
+ - **`gh` CLI** — Required for all PR operations. Install from https://cli.github.com/ and authenticate with
32
+ `gh auth login`.
33
+ - **Git** — Standard git CLI for repository operations.
34
+
35
+ ## Workspace Layout
36
+
37
+ Primary GitHub workspaces are stored under `~/projects/github/<user>/<project>/` when first resolved from a
38
+ `#gh(user/project)` reference. Numbered parallel-work checkouts follow SASE's shared `workspace.root` policy: by
39
+ default they live under the platform state-root namespace, while explicit `workspace.root: adjacent` keeps the legacy
40
+ `~/projects/github/<user>/<project>_<N>/` sibling layout.
41
+
42
+ ## Project Files
43
+
44
+ Project metadata is stored in `~/.sase/projects/<project>/<project>.sase`; legacy `.gp` files remain readable as a
45
+ fallback. The key field is `WORKSPACE_DIR`, which points to the primary workspace directory and is set automatically
46
+ when you first use an `#gh:<user>/<project>` ref.
47
+
48
+ For new `owner/repo` refs, the project name is based on the full GitHub identity, normally `gh_<user>__<project>`, so
49
+ two owners can have repositories with the same basename. If that canonical name is already occupied by a different
50
+ project or alias, sase-github adds a deterministic suffix such as `-2`.
51
+
52
+ sase-github also writes a short `PROJECT_ALIASES` value for the repo basename when it is valid and useful. The first
53
+ `owner/foo` repo can get alias `foo`; a second `owner/foo` repo gets the next available alias such as `foo-2`. Existing
54
+ basename ProjectSpecs are reused when their `WORKSPACE_DIR` already matches the GitHub workspace, so no automatic
55
+ migration or rename is required. Inspect or adjust generated aliases with `sase project alias`.