pi-git-delegate 0.2.0
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.
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +152 -0
- package/docs/examples.md +50 -0
- package/docs/release.md +57 -0
- package/docs/template-checklist.md +144 -0
- package/extensions/index.ts +8 -0
- package/lib/config.ts +122 -0
- package/lib/git-exec.ts +21 -0
- package/lib/prompts.ts +34 -0
- package/lib/register-commands.ts +57 -0
- package/lib/register-tools.ts +77 -0
- package/lib/schema.ts +8 -0
- package/lib/settings-help.ts +176 -0
- package/lib/subagent-runner.ts +148 -0
- package/lib/tools/git-blame-summary.ts +64 -0
- package/lib/tools/git-diff-summary.ts +57 -0
- package/lib/tools/git-log-summary.ts +64 -0
- package/package.json +58 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This project follows semantic versioning.
|
|
6
|
+
|
|
7
|
+
## [0.2.0] - 2026-06-13
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `git_diff_summary` typed tool — delegates `git diff` summarization to a subagent.
|
|
12
|
+
- `git_log_summary` typed tool — delegates `git log` digest generation to a subagent.
|
|
13
|
+
- `git_blame_summary` typed tool — delegates `git blame` contributor context to a subagent.
|
|
14
|
+
- `/git-delegate:configure` and `/git-delegate:status` commands for settings help.
|
|
15
|
+
- Removed template `skills/`, `prompts/`, and `themes/` resources to avoid Pi resource conflicts and invalid theme warnings.
|
|
16
|
+
|
|
17
|
+
## [0.1.2] - 2026-06-04
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- README and `docs/template-checklist.md` now follow the Pi OSS minimal-docs policy: `docs/` is optional, with explicit post-generation cleanup for template bootstrap docs.
|
|
22
|
+
- Template bootstrap docs (`github-template.md`, `repository-settings.md`, `typescript.md`) are labeled for delete-or-merge after setup.
|
|
23
|
+
|
|
24
|
+
## [0.1.1] - 2026-06-01
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Publish workflow now supports npm publishing on merged package version bumps in addition to tags, releases, and manual dispatch.
|
|
29
|
+
- Publish workflow now installs a current npm CLI so npm Trusted Publishing OIDC is supported.
|
|
30
|
+
- CI and publish workflow commands no longer include literal trailing `\\n` text.
|
|
31
|
+
|
|
32
|
+
## [0.1.0] - YYYY-MM-DD
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- Initial Pi package template.
|
|
37
|
+
- Example extension, Agent Skill, prompt, and theme.
|
|
38
|
+
- CI and npm Trusted Publishing workflow.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 YOUR_NAME
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Pi Git Delegate
|
|
2
|
+
|
|
3
|
+
[](https://github.com/eiei114/pi-git-delegate/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/eiei114/pi-git-delegate/actions/workflows/publish.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/pi-git-delegate)
|
|
6
|
+
[](https://www.npmjs.com/package/pi-git-delegate)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://pi.dev/packages)
|
|
9
|
+
|
|
10
|
+
> Delegate git operations (diff/log/blame) to cheaper models via subagents — keeping parent context clean and cutting costs.
|
|
11
|
+
|
|
12
|
+
## What this is
|
|
13
|
+
|
|
14
|
+
Pi Git Delegate provides typed tools that internally delegate heavy git read operations (diff, log, blame) to subagents. The subagent processes the raw git output and returns only a concise summary to the parent session. This prevents large diffs from polluting the parent's context window and lets you route expensive operations to cheaper models.
|
|
15
|
+
|
|
16
|
+
## When to delegate
|
|
17
|
+
|
|
18
|
+
The cost leverage principle: **delegate only when input is large and output is small.**
|
|
19
|
+
|
|
20
|
+
| Operation | Delegation | Why |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `git diff` (→ summary) | ✅ Delegate | Diff is large (1000+ tokens), summary is tiny |
|
|
23
|
+
| `git log` (→ changelog) | ✅ Delegate | Many commits → compact digest |
|
|
24
|
+
| `git blame` (→ context) | ✅ Delegate | Full blame is verbose; what matters is who/when/why |
|
|
25
|
+
| `git status` | ❌ Direct | Output is tiny; subagent overhead not worth it |
|
|
26
|
+
| `git push` / `git commit` | ❌ Direct | Write operations stay in parent for safety |
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **`git_diff_summary`** — delegate `git diff` to a subagent, return a 1-3 sentence summary
|
|
31
|
+
- **`git_log_summary`** — delegate `git log` range, return a structured digest
|
|
32
|
+
- **`git_blame_summary`** — delegate `git blame`, return who changed what and why
|
|
33
|
+
- **Per-tool model routing** — set `provider` and `model` per tool in `.pi/settings.json` (`null` uses the session defaults)
|
|
34
|
+
- **`/git-delegate:configure`** — interactive help for writing the settings block
|
|
35
|
+
- **`/git-delegate:status`** — show current model routing and example JSON
|
|
36
|
+
- **Model override parameter** — override model per-call via tool parameter
|
|
37
|
+
- **Fallback to current model** — no config needed; uses the parent session model
|
|
38
|
+
- **Write guard** — no write operations exposed as tools
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pi install npm:pi-git-delegate
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Install locally (project-scoped):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pi install npm:pi-git-delegate -l
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Try without installing:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pi -e .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Once installed, the tools are available automatically. Pi calls them via `pi list`.
|
|
61
|
+
|
|
62
|
+
### Configure model per tool (optional)
|
|
63
|
+
|
|
64
|
+
Run in Pi:
|
|
65
|
+
|
|
66
|
+
```txt
|
|
67
|
+
/git-delegate:configure
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This shows what each key does, prints a starter JSON block, and can save it to `.pi/settings.json` interactively.
|
|
71
|
+
|
|
72
|
+
Check the current routing anytime with:
|
|
73
|
+
|
|
74
|
+
```txt
|
|
75
|
+
/git-delegate:status
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Manual example for `.pi/settings.json`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"pi-git-delegate": {
|
|
83
|
+
"diff": { "provider": "anthropic", "model": "claude-3-5-haiku-latest" },
|
|
84
|
+
"log": { "provider": null, "model": null },
|
|
85
|
+
"blame": { "provider": null, "model": null }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`null` means "use the current session provider/model".
|
|
91
|
+
|
|
92
|
+
### Call a tool
|
|
93
|
+
|
|
94
|
+
```txt
|
|
95
|
+
git_diff_summary({ref: "HEAD~3"})
|
|
96
|
+
→ "feat: add avatar upload with resize (3 files, 2 commits)"
|
|
97
|
+
|
|
98
|
+
git_log_summary({range: "main..feature"})
|
|
99
|
+
→ "3 commits: feat(avatar), fix(crop), chore(deps)"
|
|
100
|
+
|
|
101
|
+
git_blame_summary({path: "src/auth.ts"})
|
|
102
|
+
→ "src/auth.ts: 3 authors, most recent by @alice (2026-06-01)"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Package contents
|
|
106
|
+
|
|
107
|
+
| Path | Purpose |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `extensions/` | Pi TypeScript extension entrypoints |
|
|
110
|
+
| `lib/` | Shared TypeScript helpers |
|
|
111
|
+
| `docs/` | Optional supporting docs |
|
|
112
|
+
|
|
113
|
+
## Development
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm install
|
|
117
|
+
npm run ci
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Release
|
|
121
|
+
|
|
122
|
+
This package is set up for npm Trusted Publishing, so no `NPM_TOKEN` is required.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm version patch
|
|
126
|
+
git push
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
See [`docs/release.md`](docs/release.md) for setup details.
|
|
130
|
+
|
|
131
|
+
## Docs
|
|
132
|
+
|
|
133
|
+
`docs/` is optional supporting documentation, not a fixed six-file set. README stays the GitHub/npm entrypoint; add `docs/*.md` only when they help users or maintainers.
|
|
134
|
+
|
|
135
|
+
- [`docs/examples.md`](docs/examples.md) — tool usage examples
|
|
136
|
+
- [`docs/release.md`](docs/release.md) — Trusted Publishing details (README Release summarizes the flow)
|
|
137
|
+
|
|
138
|
+
## Security
|
|
139
|
+
|
|
140
|
+
Pi packages can execute code with your local permissions. Review extensions before installing third-party packages.
|
|
141
|
+
|
|
142
|
+
For vulnerability reporting, see [`SECURITY.md`](SECURITY.md).
|
|
143
|
+
|
|
144
|
+
## Links
|
|
145
|
+
|
|
146
|
+
- npm: https://www.npmjs.com/package/pi-git-delegate
|
|
147
|
+
- GitHub: https://github.com/eiei114/pi-git-delegate
|
|
148
|
+
- Issues: https://github.com/eiei114/pi-git-delegate/issues
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT\n
|
package/docs/examples.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
Pi Git Delegate ships typed tools for delegating heavy git read operations to subagents.
|
|
4
|
+
|
|
5
|
+
## Extension
|
|
6
|
+
|
|
7
|
+
`extensions/index.ts` registers:
|
|
8
|
+
|
|
9
|
+
- `git_diff_summary`
|
|
10
|
+
- `git_log_summary`
|
|
11
|
+
- `git_blame_summary`
|
|
12
|
+
- `/git-delegate:configure`
|
|
13
|
+
- `/git-delegate:status`
|
|
14
|
+
|
|
15
|
+
Try it locally:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pi -e .
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then call a tool from Pi:
|
|
22
|
+
|
|
23
|
+
```txt
|
|
24
|
+
git_diff_summary({ref: "HEAD~3"})
|
|
25
|
+
git_log_summary({range: "HEAD~5..HEAD"})
|
|
26
|
+
git_blame_summary({path: "lib/config.ts"})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Settings
|
|
30
|
+
|
|
31
|
+
Configure per-tool subagent models:
|
|
32
|
+
|
|
33
|
+
```txt
|
|
34
|
+
/git-delegate:configure
|
|
35
|
+
/git-delegate:status
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Manual example for `.pi/settings.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"pi-git-delegate": {
|
|
43
|
+
"diff": { "provider": "anthropic", "model": "claude-3-5-haiku-latest" },
|
|
44
|
+
"log": { "provider": null, "model": null },
|
|
45
|
+
"blame": { "provider": null, "model": null }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`null` uses the current session provider/model.
|
package/docs/release.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Release
|
|
2
|
+
|
|
3
|
+
This package uses npm Trusted Publishing with GitHub Actions OIDC.
|
|
4
|
+
|
|
5
|
+
Do not add `NPM_TOKEN` or long-lived npm tokens to GitHub Secrets.
|
|
6
|
+
|
|
7
|
+
## One-time npm setup
|
|
8
|
+
|
|
9
|
+
On npmjs.com, configure Trusted Publishing for this package:
|
|
10
|
+
|
|
11
|
+
- Publisher: GitHub Actions
|
|
12
|
+
- Repository: this GitHub repository
|
|
13
|
+
- Workflow filename: `publish.yml`
|
|
14
|
+
|
|
15
|
+
## Publish
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm version patch
|
|
19
|
+
git push
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
On `main`, `.github/workflows/auto-release.yml` checks `package.json` version. If `v<version>` does not exist yet, it creates the tag, creates the GitHub Release, then explicitly dispatches `.github/workflows/publish.yml` for that tag.
|
|
23
|
+
|
|
24
|
+
The `v*.*.*` tag also triggers `.github/workflows/publish.yml`, which runs CI and publishes to npm when tags are pushed manually.
|
|
25
|
+
Publishing also runs when a GitHub Release is published, and can be run manually from GitHub Actions with `workflow_dispatch`.
|
|
26
|
+
|
|
27
|
+
The workflow skips `name@version` if that exact package version already exists on npm.
|
|
28
|
+
|
|
29
|
+
## Workflow guardrail
|
|
30
|
+
|
|
31
|
+
Do not ship a new Pi OSS package or version bump with only `package.json` changes.
|
|
32
|
+
The repository must include the release workflow pair:
|
|
33
|
+
|
|
34
|
+
- `.github/workflows/auto-release.yml` creates `v<version>` tags and GitHub Releases from `main` version bumps.
|
|
35
|
+
- `.github/workflows/publish.yml` publishes to npm through Trusted Publishing.
|
|
36
|
+
|
|
37
|
+
Important: tags or releases created by `GITHUB_TOKEN` do not reliably fan out into another workflow through normal `push.tags` or `release.published` triggers. The template keeps publishing reliable by having `auto-release.yml` explicitly dispatch `publish.yml` after creating the tag/release. If you change the release flow, keep one explicit handoff path: `workflow_dispatch` from auto-release, `repository_dispatch`, or `workflow_run` on the auto-release workflow.
|
|
38
|
+
|
|
39
|
+
## GitHub Actions requirements
|
|
40
|
+
|
|
41
|
+
- `permissions: id-token: write`
|
|
42
|
+
- `permissions: actions: write` on auto-release so it can dispatch `publish.yml`
|
|
43
|
+
- `auto-release.yml` must call `gh workflow run publish.yml --ref "$TAG" -f ref="$TAG"`, or `publish.yml` must have an equivalent explicit handoff trigger such as `workflow_run`
|
|
44
|
+
- GitHub-hosted runner
|
|
45
|
+
- Node.js 24, so the release job uses a current npm CLI for Trusted Publishing
|
|
46
|
+
- No `NPM_TOKEN`
|
|
47
|
+
- `npm publish` from the configured workflow file
|
|
48
|
+
|
|
49
|
+
## First release checklist
|
|
50
|
+
|
|
51
|
+
- [ ] `package.json` name is final
|
|
52
|
+
- [ ] `repository.url` points to the real GitHub repository
|
|
53
|
+
- [ ] npm Trusted Publisher is configured
|
|
54
|
+
- [ ] `npm run ci` passes
|
|
55
|
+
- [ ] `npm pack --dry-run` contains only intended files
|
|
56
|
+
- [ ] CHANGELOG.md has the release date
|
|
57
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Template Setup Checklist
|
|
2
|
+
|
|
3
|
+
このテンプレートから新しい Pi 拡張OSSを作った後に埋めること。
|
|
4
|
+
|
|
5
|
+
## Recommended flow
|
|
6
|
+
|
|
7
|
+
- [ ] Vault project notes を `4_Project/<ProjectName>/` に作る
|
|
8
|
+
- [ ] `CONTEXT.md` / `README.md` / `ROADMAP.md` / `Docs/` / `Issues/` / `Progress/` を揃える
|
|
9
|
+
- [ ] PRD を `4_Project/<ProjectName>/Docs/` に置く
|
|
10
|
+
- [ ] approved issue を `4_Project/<ProjectName>/Issues/` に切る
|
|
11
|
+
- [ ] OSS repo 側で実装する
|
|
12
|
+
- [ ] `npm run ci` / `npm test` / `npm pack --dry-run` を通す
|
|
13
|
+
- [ ] release 後に Vault へ learnings / release notes を戻す
|
|
14
|
+
|
|
15
|
+
## Repository
|
|
16
|
+
|
|
17
|
+
- [ ] GitHub repository name を決める
|
|
18
|
+
- [ ] GitHub About 欄を書く
|
|
19
|
+
- [ ] GitHub topics を設定する
|
|
20
|
+
- [ ] `pi`
|
|
21
|
+
- [ ] `pi-package`
|
|
22
|
+
- [ ] `agent-skill`
|
|
23
|
+
- [ ] `typescript`
|
|
24
|
+
- [ ] GitHub Settingsで `Template repository` をONにする
|
|
25
|
+
- [ ] Repository URL を `package.json` に反映する
|
|
26
|
+
- [ ] README の `OWNER/REPO` を実リポジトリに置き換える
|
|
27
|
+
|
|
28
|
+
## Package metadata
|
|
29
|
+
|
|
30
|
+
- [ ] `package.json` の `name` を変更する
|
|
31
|
+
- [ ] `description` を書く
|
|
32
|
+
- [ ] `author` を入れる
|
|
33
|
+
- [ ] `repository.url` を埋める
|
|
34
|
+
- [ ] `bugs.url` を埋める
|
|
35
|
+
- [ ] `homepage` を埋める
|
|
36
|
+
- [ ] `keywords` を見直す
|
|
37
|
+
- [ ] `LICENSE` の年・名前を更新する
|
|
38
|
+
|
|
39
|
+
## README placeholders
|
|
40
|
+
|
|
41
|
+
- [ ] `PACKAGE_DISPLAY_NAME` を置き換える
|
|
42
|
+
- [ ] `PACKAGE_NAME` を置き換える
|
|
43
|
+
- [ ] `OWNER/REPO` を置き換える
|
|
44
|
+
- [ ] one-line pitch を書く
|
|
45
|
+
- [ ] feature list を書く
|
|
46
|
+
- [ ] quick start command を実コマンドにする
|
|
47
|
+
- [ ] npm URL を確認する
|
|
48
|
+
- [ ] GitHub URL を確認する
|
|
49
|
+
|
|
50
|
+
## Pi package manifest
|
|
51
|
+
|
|
52
|
+
- [ ] `pi.extensions` に公開する拡張だけを残す
|
|
53
|
+
- [ ] **extension のみで ship するなら** `pi.skills` / `pi.prompts` / `pi.themes` を `package.json` から削除する
|
|
54
|
+
- [ ] **extension のみで ship するなら** `skills/` / `prompts/` / `themes/` ディレクトリを削除する
|
|
55
|
+
- [ ] skill を出すなら `example-skill` を **package 固有名** にリネームする(例: `<pkg>-workflow`)
|
|
56
|
+
- [ ] prompt を出すなら `example.md` を **package 固有名** にリネームする(例: `<pkg>-summarize.md`)
|
|
57
|
+
- [ ] theme を出すなら built-in theme と同じ **全必須 color token** を入れる。未完成なら `themes/` ごと削除
|
|
58
|
+
- [ ] `package.json` の `files` から、削除した resource パスを外す
|
|
59
|
+
- [ ] skill を出さないなら `keywords` / GitHub topics から `agent-skill` を外す
|
|
60
|
+
- [ ] Pi 起動ログに `[Skill conflicts]` / `[Prompt conflicts]` / `[Theme conflicts]` が **自 package 分で出ない** ことを確認する
|
|
61
|
+
|
|
62
|
+
## Documentation
|
|
63
|
+
|
|
64
|
+
`docs/` は固定6ファイル必須ではない。README を正とし、価値がある doc だけ残す。
|
|
65
|
+
|
|
66
|
+
### Required root files (public)
|
|
67
|
+
|
|
68
|
+
- [ ] `README.md` — GitHub/npm の入口。Install / Quick start / Release / Security を含める
|
|
69
|
+
- [ ] `LICENSE`
|
|
70
|
+
- [ ] `SECURITY.md`
|
|
71
|
+
- [ ] `CHANGELOG.md`
|
|
72
|
+
- [ ] Release 手順が README と workflow で明確(Trusted Publishing 設定含む)
|
|
73
|
+
|
|
74
|
+
### Recommended public docs (keep when useful)
|
|
75
|
+
|
|
76
|
+
- [ ] `docs/examples.md` — 例が README に載り切らないとき
|
|
77
|
+
- [ ] `docs/release.md` — Trusted Publishing や release 手順の詳細が README だけでは足りないとき
|
|
78
|
+
- [ ] `docs/usage.md` — 使い方が README に載り切らないとき(必要なら新規作成)
|
|
79
|
+
|
|
80
|
+
### Optional maintainer docs
|
|
81
|
+
|
|
82
|
+
- [ ] `docs/template-checklist.md` — このファイル。成熟 repo では README からの主ナビにしない。不要なら削除可
|
|
83
|
+
|
|
84
|
+
### Post-generation cleanup (delete or merge template setup docs)
|
|
85
|
+
|
|
86
|
+
テンプレート生成直後の bootstrap 用。プロジェクト固有の価値がなければ削除し、必要な内容は README / `docs/release.md` / `docs/examples.md` に統合する。
|
|
87
|
+
|
|
88
|
+
- [ ] `docs/github-template.md` を削除するか、固有の手順だけ README / Vault に移す
|
|
89
|
+
- [ ] `docs/repository-settings.md` を削除するか、About/topics など必要分だけ README に移す
|
|
90
|
+
- [ ] `docs/typescript.md` を削除するか、TypeScript 方針は README Development に要約する
|
|
91
|
+
- [ ] README の Docs 節から、削除したファイルへのリンクを外す
|
|
92
|
+
- [ ] `package.json` の `files` から、削除した `docs/` パスを外す(残す doc だけ明示する)
|
|
93
|
+
|
|
94
|
+
## TypeScript
|
|
95
|
+
|
|
96
|
+
- [ ] `extensions/index.ts` を実装に合わせて更新する
|
|
97
|
+
- [ ] `extensions/hello.ts` が不要なら削除する
|
|
98
|
+
- [ ] 共通ロジックを `lib/` に切り出す
|
|
99
|
+
- [ ] `strict: true` を維持する
|
|
100
|
+
- [ ] custom tool parameters は TypeBox schema で定義する
|
|
101
|
+
- [ ] string choices は `StringEnum` helper を使う
|
|
102
|
+
- [ ] runtime dependency は `dependencies`、Pi提供packageは `peerDependencies` に置く
|
|
103
|
+
- [ ] `package.json.files` に公開対象だけを入れる
|
|
104
|
+
- [ ] 詳細はセットアップ中だけ `docs/typescript.md` を参照し、不要なら post-generation cleanup で削除
|
|
105
|
+
|
|
106
|
+
## GitHub Template repo
|
|
107
|
+
|
|
108
|
+
- [ ] `gh repo create --template OWNER/pi-extension-template` で作成できることを確認する
|
|
109
|
+
- [ ] public/privateどちらの作成例もdocsに載せる(`docs/github-template.md` を残す場合)
|
|
110
|
+
|
|
111
|
+
## CI / Release
|
|
112
|
+
|
|
113
|
+
- [ ] `npm run ci` が通る
|
|
114
|
+
- [ ] `npm pack --dry-run` が通る
|
|
115
|
+
- [ ] npm Trusted Publishing を設定する
|
|
116
|
+
- [ ] npm Trusted Publisher の workflow filename が `publish.yml` になっている
|
|
117
|
+
- [ ] `NPM_TOKEN` を使っていないことを確認する
|
|
118
|
+
- [ ] `auto-release.yml` が `main` の version bump から tag/release を作ることを確認する
|
|
119
|
+
- [ ] `publish.yml` が `workflow_dispatch` と `release.published` に対応していることを確認する
|
|
120
|
+
- [ ] 初回リリースで npm provenance が付いているか確認する
|
|
121
|
+
|
|
122
|
+
### Workflow handoff guard
|
|
123
|
+
|
|
124
|
+
- [ ] `.github/workflows/auto-release.yml` exists before first release
|
|
125
|
+
- [ ] `.github/workflows/publish.yml` exists before first release
|
|
126
|
+
- [ ] `auto-release.yml` has `permissions: actions: write` and `contents: write`
|
|
127
|
+
- [ ] `publish.yml` has `permissions: id-token: write` for npm Trusted Publishing
|
|
128
|
+
- [ ] Auto release explicitly hands off to publish: `gh workflow run publish.yml --ref "$TAG" -f ref="$TAG"`, or `publish.yml` has an equivalent `workflow_run` / `repository_dispatch` trigger
|
|
129
|
+
- [ ] Do not rely only on `push.tags` or `release.published` when the tag/release is created by `GITHUB_TOKEN`; that can leave npm unchanged after merge
|
|
130
|
+
|
|
131
|
+
## npm page
|
|
132
|
+
|
|
133
|
+
- [ ] npm package URL を README に追加する
|
|
134
|
+
- [ ] npm description が適切に表示されるか確認する
|
|
135
|
+
- [ ] provenance が付いているか確認する
|
|
136
|
+
- [ ] 不要なファイルが package に含まれていないか確認する(`npm pack --dry-run` で `docs/` の残し方も確認)
|
|
137
|
+
|
|
138
|
+
## Before first release
|
|
139
|
+
|
|
140
|
+
- [ ] サンプルコードを実機 Pi でロードする
|
|
141
|
+
- [ ] `pi install git:github.com/OWNER/REPO` を試す
|
|
142
|
+
- [ ] `pi -e .` を試す
|
|
143
|
+
- [ ] README のコマンドがコピペで動くか確認する
|
|
144
|
+
- [ ] CHANGELOG に `0.1.0` を書く
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { registerGitDelegateCommands } from "../lib/register-commands.ts";
|
|
3
|
+
import { registerGitDelegateTools } from "../lib/register-tools.ts";
|
|
4
|
+
|
|
5
|
+
export default function (pi: ExtensionAPI) {
|
|
6
|
+
registerGitDelegateCommands(pi);
|
|
7
|
+
registerGitDelegateTools(pi);
|
|
8
|
+
}
|
package/lib/config.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
export type GitDelegateToolName = "git_diff_summary" | "git_log_summary" | "git_blame_summary";
|
|
6
|
+
export type GitDelegateToolKey = "diff" | "log" | "blame";
|
|
7
|
+
|
|
8
|
+
export interface ModelRoute {
|
|
9
|
+
provider: string | null;
|
|
10
|
+
model: string | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface GitDelegateConfig {
|
|
14
|
+
diff: ModelRoute;
|
|
15
|
+
log: ModelRoute;
|
|
16
|
+
blame: ModelRoute;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ResolvedSubagentRoute {
|
|
20
|
+
provider?: string;
|
|
21
|
+
model?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const NULL_MODEL_ROUTE: ModelRoute = {
|
|
25
|
+
provider: null,
|
|
26
|
+
model: null,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const DEFAULT_GIT_DELEGATE_CONFIG: GitDelegateConfig = {
|
|
30
|
+
diff: { ...NULL_MODEL_ROUTE },
|
|
31
|
+
log: { ...NULL_MODEL_ROUTE },
|
|
32
|
+
blame: { ...NULL_MODEL_ROUTE },
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const TOOL_CONFIG_KEYS: Record<GitDelegateToolName, GitDelegateToolKey> = {
|
|
36
|
+
git_diff_summary: "diff",
|
|
37
|
+
git_log_summary: "log",
|
|
38
|
+
git_blame_summary: "blame",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function trimOrUndefined(value: string | null | undefined): string | undefined {
|
|
46
|
+
if (value === null || value === undefined) return undefined;
|
|
47
|
+
const trimmed = value.trim();
|
|
48
|
+
return trimmed ? trimmed : undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function parseNullableString(value: unknown): string | null {
|
|
52
|
+
if (value === null || value === undefined) return null;
|
|
53
|
+
if (typeof value !== "string") return null;
|
|
54
|
+
const trimmed = value.trim();
|
|
55
|
+
return trimmed ? trimmed : null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseRoute(value: unknown): ModelRoute {
|
|
59
|
+
if (!isRecord(value)) {
|
|
60
|
+
return { ...NULL_MODEL_ROUTE };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
provider: parseNullableString(value.provider),
|
|
65
|
+
model: parseNullableString(value.model),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readSettingsFile(filePath: string): Record<string, unknown> | undefined {
|
|
70
|
+
if (!existsSync(filePath)) return undefined;
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(readFileSync(filePath, "utf8")) as unknown;
|
|
73
|
+
return isRecord(parsed) ? parsed : undefined;
|
|
74
|
+
} catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function parseGitDelegateConfig(settings: Record<string, unknown> | undefined): GitDelegateConfig | undefined {
|
|
80
|
+
if (!settings) return undefined;
|
|
81
|
+
const raw = settings["pi-git-delegate"];
|
|
82
|
+
if (!isRecord(raw)) return undefined;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
diff: parseRoute(raw.diff),
|
|
86
|
+
log: parseRoute(raw.log),
|
|
87
|
+
blame: parseRoute(raw.blame),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function loadGitDelegateConfig(cwd: string): GitDelegateConfig | undefined {
|
|
92
|
+
const projectSettings = readSettingsFile(join(cwd, ".pi", "settings.json"));
|
|
93
|
+
const projectConfig = parseGitDelegateConfig(projectSettings);
|
|
94
|
+
if (projectConfig !== undefined) return projectConfig;
|
|
95
|
+
|
|
96
|
+
const agentSettings = readSettingsFile(join(getAgentDir(), "settings.json"));
|
|
97
|
+
return parseGitDelegateConfig(agentSettings);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function resolveSubagentRoute(
|
|
101
|
+
toolName: GitDelegateToolName,
|
|
102
|
+
config: GitDelegateConfig | undefined,
|
|
103
|
+
override?: { provider?: string; model?: string },
|
|
104
|
+
): ResolvedSubagentRoute | undefined {
|
|
105
|
+
const overrideProvider = trimOrUndefined(override?.provider);
|
|
106
|
+
const overrideModel = trimOrUndefined(override?.model);
|
|
107
|
+
if (overrideProvider || overrideModel) {
|
|
108
|
+
return {
|
|
109
|
+
provider: overrideProvider,
|
|
110
|
+
model: overrideModel,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!config) return undefined;
|
|
115
|
+
|
|
116
|
+
const route = config[TOOL_CONFIG_KEYS[toolName]];
|
|
117
|
+
const provider = trimOrUndefined(route.provider);
|
|
118
|
+
const model = trimOrUndefined(route.model);
|
|
119
|
+
if (!provider && !model) return undefined;
|
|
120
|
+
|
|
121
|
+
return { provider, model };
|
|
122
|
+
}
|
package/lib/git-exec.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
export interface GitRunResult {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
status: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function runGit(args: string[], cwd: string): GitRunResult {
|
|
10
|
+
const result = spawnSync("git", args, {
|
|
11
|
+
cwd,
|
|
12
|
+
encoding: "utf8",
|
|
13
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
stdout: (result.stdout ?? "").trim(),
|
|
18
|
+
stderr: (result.stderr ?? "").trim(),
|
|
19
|
+
status: result.status ?? 1,
|
|
20
|
+
};
|
|
21
|
+
}
|
package/lib/prompts.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const DIFF_SUMMARY_PROMPT = `You are a git diff summarizer. Given a raw git diff output,
|
|
2
|
+
produce a concise summary in 1-3 sentences covering:
|
|
3
|
+
- What files changed
|
|
4
|
+
- The nature of the changes (feature, fix, refactor)
|
|
5
|
+
- Any notable patterns or risks
|
|
6
|
+
|
|
7
|
+
Do not output the diff back. Only output the summary.
|
|
8
|
+
Use no markdown formatting. One paragraph max.`;
|
|
9
|
+
|
|
10
|
+
export const LOG_SUMMARY_PROMPT = `You are a git log summarizer. Given a git log output with
|
|
11
|
+
commit hashes and messages, produce a concise digest in
|
|
12
|
+
2-4 sentences covering:
|
|
13
|
+
- How many commits and their general theme
|
|
14
|
+
- The main types of changes (features, fixes, refactors)
|
|
15
|
+
- Any notable patterns
|
|
16
|
+
|
|
17
|
+
Do not output the raw log. Only output the summary.
|
|
18
|
+
Use no markdown formatting. Two paragraphs max.`;
|
|
19
|
+
|
|
20
|
+
export const BLAME_SUMMARY_PROMPT = `You are a git blame summarizer. Given a git blame output,
|
|
21
|
+
produce a concise summary in 2-3 sentences covering:
|
|
22
|
+
- Total number of contributors to this file
|
|
23
|
+
- Who made the most recent changes and when
|
|
24
|
+
- The general age of the file (new, actively maintained, stable)
|
|
25
|
+
|
|
26
|
+
Do not output the raw blame. Only output the summary.
|
|
27
|
+
Use no markdown formatting. Two paragraphs max.`;
|
|
28
|
+
|
|
29
|
+
export function buildSubagentPrompt(systemPrompt: string, gitOutput: string): string {
|
|
30
|
+
return `${systemPrompt}
|
|
31
|
+
|
|
32
|
+
Git output:
|
|
33
|
+
${gitOutput}`;
|
|
34
|
+
}
|