@neturely/okffs 0.2.1
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 +60 -0
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +27 -0
- package/dist/config.js.map +1 -0
- package/dist/docs.d.ts +11 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +203 -0
- package/dist/docs.js.map +1 -0
- package/dist/git.d.ts +7 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +22 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +111 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +301 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/address_pr_review.d.ts +18 -0
- package/dist/prompts/address_pr_review.d.ts.map +1 -0
- package/dist/prompts/address_pr_review.js +35 -0
- package/dist/prompts/address_pr_review.js.map +1 -0
- package/dist/prompts/update_guidance.d.ts +18 -0
- package/dist/prompts/update_guidance.d.ts.map +1 -0
- package/dist/prompts/update_guidance.js +47 -0
- package/dist/prompts/update_guidance.js.map +1 -0
- package/dist/tools/close_issue.d.ts +17 -0
- package/dist/tools/close_issue.d.ts.map +1 -0
- package/dist/tools/close_issue.js +28 -0
- package/dist/tools/close_issue.js.map +1 -0
- package/dist/tools/comment_issue.d.ts +20 -0
- package/dist/tools/comment_issue.d.ts.map +1 -0
- package/dist/tools/comment_issue.js +23 -0
- package/dist/tools/comment_issue.js.map +1 -0
- package/dist/tools/commit_and_update.d.ts +20 -0
- package/dist/tools/commit_and_update.d.ts.map +1 -0
- package/dist/tools/commit_and_update.js +80 -0
- package/dist/tools/commit_and_update.js.map +1 -0
- package/dist/tools/create_issue.d.ts +29 -0
- package/dist/tools/create_issue.d.ts.map +1 -0
- package/dist/tools/create_issue.js +82 -0
- package/dist/tools/create_issue.js.map +1 -0
- package/dist/tools/create_issues_from_list.d.ts +50 -0
- package/dist/tools/create_issues_from_list.d.ts.map +1 -0
- package/dist/tools/create_issues_from_list.js +48 -0
- package/dist/tools/create_issues_from_list.js.map +1 -0
- package/dist/tools/create_pull_request.d.ts +20 -0
- package/dist/tools/create_pull_request.d.ts.map +1 -0
- package/dist/tools/create_pull_request.js +170 -0
- package/dist/tools/create_pull_request.js.map +1 -0
- package/dist/tools/delete_branch.d.ts +20 -0
- package/dist/tools/delete_branch.d.ts.map +1 -0
- package/dist/tools/delete_branch.js +39 -0
- package/dist/tools/delete_branch.js.map +1 -0
- package/dist/tools/delete_issue.d.ts +20 -0
- package/dist/tools/delete_issue.d.ts.map +1 -0
- package/dist/tools/delete_issue.js +46 -0
- package/dist/tools/delete_issue.js.map +1 -0
- package/dist/tools/get_issue.d.ts +17 -0
- package/dist/tools/get_issue.d.ts.map +1 -0
- package/dist/tools/get_issue.js +27 -0
- package/dist/tools/get_issue.js.map +1 -0
- package/dist/tools/link_issues.d.ts +23 -0
- package/dist/tools/link_issues.d.ts.map +1 -0
- package/dist/tools/link_issues.js +42 -0
- package/dist/tools/link_issues.js.map +1 -0
- package/dist/tools/list_issues.d.ts +11 -0
- package/dist/tools/list_issues.d.ts.map +1 -0
- package/dist/tools/list_issues.js +61 -0
- package/dist/tools/list_issues.js.map +1 -0
- package/dist/tools/list_pr_review_comments.d.ts +17 -0
- package/dist/tools/list_pr_review_comments.d.ts.map +1 -0
- package/dist/tools/list_pr_review_comments.js +43 -0
- package/dist/tools/list_pr_review_comments.js.map +1 -0
- package/dist/tools/plan.d.ts +79 -0
- package/dist/tools/plan.d.ts.map +1 -0
- package/dist/tools/plan.js +159 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/prepare_release.d.ts +23 -0
- package/dist/tools/prepare_release.d.ts.map +1 -0
- package/dist/tools/prepare_release.js +172 -0
- package/dist/tools/prepare_release.js.map +1 -0
- package/dist/tools/reply_to_review_comment.d.ts +23 -0
- package/dist/tools/reply_to_review_comment.d.ts.map +1 -0
- package/dist/tools/reply_to_review_comment.js +25 -0
- package/dist/tools/reply_to_review_comment.js.map +1 -0
- package/dist/tools/resolve_review_thread.d.ts +17 -0
- package/dist/tools/resolve_review_thread.d.ts.map +1 -0
- package/dist/tools/resolve_review_thread.js +27 -0
- package/dist/tools/resolve_review_thread.js.map +1 -0
- package/package.json +48 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.2.1] - 2026-06-30
|
|
9
|
+
### Changed
|
|
10
|
+
- Migrated the project to the `neturely` GitHub organization; updated repository, homepage, and documentation links accordingly.
|
|
11
|
+
- Renamed the npm package from `okffs` to the scoped `@neturely/okffs` (published publicly via `publishConfig.access`). The unscoped `okffs` package is deprecated — install `@neturely/okffs` going forward.
|
|
12
|
+
- README: removed the "Work in progress" banner and led the auth docs with the fine-grained PAT (classic PAT demoted to a fallback).
|
|
13
|
+
|
|
14
|
+
## [0.2.0] - 2026-06-28
|
|
15
|
+
### Fixed
|
|
16
|
+
- The MCP server now reports the real package version instead of a hard-coded `0.0.1`.
|
|
17
|
+
- Auto-doc entries are now concise title-based one-liners instead of truncated summary dumps; CLAUDE.md and CONTRIBUTING.md are no longer auto-updated (CHANGELOG.md, plus SECURITY.md when relevant, are the only auto-doc targets) ([#60](https://github.com/2b9sa2owa/okffs/issues/60)).
|
|
18
|
+
- Corrected the stale `OKFFS_EXCLUDE_DOCS` example in the README (valid options are `CHANGELOG.md`, `SECURITY.md`) ([#62](https://github.com/2b9sa2owa/okffs/issues/62)).
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `prepare_release` tool — bumps the version (`package.json` + `package-lock.json`), rolls the CHANGELOG (`[Unreleased]` → a dated version section with updated compare links), commits on a release branch, and opens a PR. Two-step confirm; explicit `version`/`bump` or inferred. Does not tag or publish ([#68](https://github.com/2b9sa2owa/okffs/issues/68)).
|
|
22
|
+
- `update_guidance` MCP prompt (slash command) that intelligently maintains a bounded, okffs-owned `## Project Guidance (okffs usage)` section of CLAUDE.md (marker-delimited; never touches your other content) to reflect new/changed functionality, plus the `OKFFS_UPDATE_GUIDANCE` env var to nudge it at PR time ([#64](https://github.com/2b9sa2owa/okffs/issues/64), [#66](https://github.com/2b9sa2owa/okffs/issues/66)).
|
|
23
|
+
- A Changelog section in the README linking to Releases and `CHANGELOG.md` ([#62](https://github.com/2b9sa2owa/okffs/issues/62)).
|
|
24
|
+
- PR review-response workflow: new `list_pr_review_comments`, `reply_to_review_comment`, and `resolve_review_thread` tools, plus an `address_pr_review` MCP prompt (slash command) that reads a PR's review comments, fixes them, replies per thread, and posts a summary. Thread resolution is gated by the new `OKFFS_RESOLVE_THREADS` env var (default off) ([#58](https://github.com/2b9sa2owa/okffs/issues/58)).
|
|
25
|
+
- Reduced auth/setup friction: token resolves from `GITHUB_TOKEN` or falls back to `gh auth token`, and owner/repo auto-detect from the `origin` git remote when env vars are unset ([#56](https://github.com/2b9sa2owa/okffs/issues/56)).
|
|
26
|
+
|
|
27
|
+
## [0.1.6] - 2026-06-27
|
|
28
|
+
### Added
|
|
29
|
+
- `plan` tool — takes a free-text description plus the issue breakdown Claude generates from it (titles, descriptions, labels, inter-task relationships), previews the plan, and creates all issues + branches (and draft PRs when `OKFFS_AUTO_PR=true`) in one shot. Resolves relationships to issue numbers and writes them to each issue's `## Relationships` section ([#42](https://github.com/2b9sa2owa/okffs/issues/42)).
|
|
30
|
+
- Redesigned `list_issues` — each open issue now shows its branch + URL, any linked open/draft PR (matched by head branch), and its relationships (parent, children, blocked-by, blocking) as a tree ([#43](https://github.com/2b9sa2owa/okffs/issues/43)).
|
|
31
|
+
- `OKFFS_IDENTIFIER` env var — when set, branch names use `{issue-number}-{identifier}-{slug}` instead of `{issue-number}-{slug}` ([#41](https://github.com/2b9sa2owa/okffs/issues/41)).
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- `OKFFS_UPDATE_DOCS` auto-changelog now fires only on `create_pull_request`; `comment_issue` and `close_issue` no longer trigger doc updates, making `create_pull_request` the single source of changelog entries and eliminating noisy/duplicate entries ([#47](https://github.com/2b9sa2owa/okffs/issues/47)).
|
|
35
|
+
- `create_pull_request` now commits all updated docs (CLAUDE.md, CONTRIBUTING.md, SECURITY.md), not just CHANGELOG.md.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- `OKFFS_AUTO_PR=true` left the CHANGELOG with no auto-update trigger. `create_pull_request` now reuses an existing open PR for the branch (e.g. a draft opened by `create_issue`), updating it and marking it ready for review instead of erroring ([#49](https://github.com/2b9sa2owa/okffs/issues/49)).
|
|
39
|
+
- Docs incorrectly claimed `Closes #N` auto-closes on merge to `main`; it only fires when merging into the repo's default branch. Corrected the docs and added a warning in `create_pull_request` when the PR base isn't the default branch ([#51](https://github.com/2b9sa2owa/okffs/issues/51)).
|
|
40
|
+
|
|
41
|
+
## [0.1.5] - 2026-06-26
|
|
42
|
+
### Added
|
|
43
|
+
- New `commit_and_update` tool — stages all changes, builds a commit message from a hint (or the changed file list), commits, pushes to the issue branch, and posts a rich progress comment to the linked issue.
|
|
44
|
+
- `prepublishOnly` hook so `dist/` is always freshly built before publishing.
|
|
45
|
+
- `.github/instructions/okffs.instructions.md` Copilot instructions file.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
- Redesigned `OKFFS_AUTO_PR`: a draft PR is now opened at branch-creation time by `create_issue` (instead of on issue close), pushing an empty init commit first so GitHub accepts the draft immediately.
|
|
49
|
+
- `close_issue` now returns a `/clear` tip and no longer triggers a PR on close.
|
|
50
|
+
- `CHANGELOG.md` is now shipped in the npm package.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
- `create_pull_request` commits the updated CHANGELOG onto the branch and pushes the branch before opening the PR, with non-blocking error handling ([#38](https://github.com/2b9sa2owa/okffs/issues/38)).
|
|
54
|
+
- All git operations now run via `execFileSync` with argument arrays (no shell), removing command-injection risk from branch names and commit hints; tools also checkout the target branch before committing/pushing and restore the original branch afterward.
|
|
55
|
+
|
|
56
|
+
[Unreleased]: https://github.com/neturely/okffs/compare/v0.2.1...HEAD
|
|
57
|
+
[0.2.1]: https://github.com/neturely/okffs/compare/v0.2.0...v0.2.1
|
|
58
|
+
[0.2.0]: https://github.com/neturely/okffs/compare/v0.1.6...v0.2.0
|
|
59
|
+
[0.1.6]: https://github.com/neturely/okffs/compare/v0.1.5...v0.1.6
|
|
60
|
+
[0.1.5]: https://github.com/neturely/okffs/compare/v0.1.4...v0.1.5
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Glory to Mankind
|
|
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,251 @@
|
|
|
1
|
+
# okffs
|
|
2
|
+
|
|
3
|
+
**okffs** is a TypeScript/Node.js [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that connects Claude Code to GitHub, enabling a full **issue → branch → merge → close** workflow. Discuss tasks in Claude.ai, then push them to GitHub as issues and branches in one shot via Claude Code.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- TypeScript / Node.js MCP server
|
|
8
|
+
- GitHub Personal Access Token (PAT) authentication (GitHub App support planned)
|
|
9
|
+
- Published to [npm](https://www.npmjs.com/) and the [MCP Registry](https://registry.modelcontextprotocol.io)
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
This project is being built in phases. See [CLAUDE.md](CLAUDE.md) for the full roadmap.
|
|
14
|
+
|
|
15
|
+
| Phase | Scope | Status |
|
|
16
|
+
|------|-------|--------|
|
|
17
|
+
| 1 | Core MCP server — `create_issue`, `list_issues`, `close_issue`, `delete_issue`, `delete_branch`, `get_issue`, `comment_issue`, `link_issues` | **Complete** |
|
|
18
|
+
| 2 | Bulk creation — `create_issues_from_list` | **Complete** |
|
|
19
|
+
| 3 | Claude.ai bridge | Skipped — not required |
|
|
20
|
+
| 4 | Auto-close on merge — `create_pull_request`, `commit_and_update` | **Complete** |
|
|
21
|
+
| 5 | GitHub Projects v2 (optional) | Planned |
|
|
22
|
+
| 6 | Project site — `okffs.g2mk.dev` | Planned |
|
|
23
|
+
|
|
24
|
+
## Changelog
|
|
25
|
+
|
|
26
|
+
See [Releases](https://github.com/neturely/okffs/releases) for per-version release notes, or [CHANGELOG.md](CHANGELOG.md) for the full history.
|
|
27
|
+
|
|
28
|
+
## Usage with Claude Code
|
|
29
|
+
|
|
30
|
+
Add okffs to any project by creating a `.mcp.json` in the project root:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"okffs": {
|
|
36
|
+
"command": "npx",
|
|
37
|
+
"args": ["@neturely/okffs@latest"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Authentication & repository
|
|
44
|
+
|
|
45
|
+
okffs needs a GitHub token and a target repository. It resolves both with sensible fallbacks, so most users need little or no config:
|
|
46
|
+
|
|
47
|
+
**Token** (in order of preference):
|
|
48
|
+
1. `GITHUB_TOKEN` in a `.env` file. Two ways to create one:
|
|
49
|
+
- **Fine-grained PAT (recommended, least privilege)** — [create one here](https://github.com/settings/personal-access-tokens/new) with **Issues**, **Contents**, **Pull requests** (read/write), **Metadata** (read), and **Administration** (read/write) on the target repo. See [Prerequisites](#prerequisites).
|
|
50
|
+
- **Classic PAT (quickest)** — one-click pre-scoped link: [github.com/settings/tokens/new?scopes=repo&description=okffs](https://github.com/settings/tokens/new?scopes=repo&description=okffs). Note this grants the **broad `repo` scope** across all your repos; prefer the fine-grained option above if you want to limit access.
|
|
51
|
+
2. If `GITHUB_TOKEN` is unset, okffs falls back to the **GitHub CLI** — if you've run `gh auth login`, it just works with no token setup.
|
|
52
|
+
|
|
53
|
+
**Repository** (in order of preference):
|
|
54
|
+
1. `GITHUB_OWNER` / `GITHUB_REPO` in `.env`.
|
|
55
|
+
2. If unset, okffs **auto-detects** them from the `origin` git remote of the directory it runs in.
|
|
56
|
+
|
|
57
|
+
So the minimal setup is often just the `.mcp.json` above — if you're signed in with `gh` and run okffs inside the repo you want to manage, no `.env` is needed at all. To configure explicitly, create a `.env` in the same directory:
|
|
58
|
+
|
|
59
|
+
```env
|
|
60
|
+
GITHUB_TOKEN=ghp_your_personal_access_token_here
|
|
61
|
+
# Optional — auto-detected from the git `origin` remote when omitted:
|
|
62
|
+
GITHUB_OWNER=your-github-username
|
|
63
|
+
GITHUB_REPO=your-repo-name
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
okffs loads `.env` automatically from the directory it starts in — no `--env-file` flag needed.
|
|
67
|
+
|
|
68
|
+
Once configured, Claude Code will pick up the tools automatically. You can ask Claude things like:
|
|
69
|
+
|
|
70
|
+
- *"Create an issue called 'Fix login button' with description '...'"*
|
|
71
|
+
- *"List all open issues"*
|
|
72
|
+
- *"Create issues from this task list: ..."*
|
|
73
|
+
- *"Plan out the work for adding user authentication and create the issues"*
|
|
74
|
+
- *"Post a comment to issue #12 saying what was done"*
|
|
75
|
+
- *"Mark issue #5 as blocked by issue #3"*
|
|
76
|
+
- *"Done with issue #42, close it and open a PR"*
|
|
77
|
+
|
|
78
|
+
Claude infers appropriate labels (`bug`, `enhancement`, etc.) from the issue title and description, and merges them with your `OKFFS_DEFAULT_LABELS`.
|
|
79
|
+
|
|
80
|
+
## Getting started
|
|
81
|
+
|
|
82
|
+
### Prerequisites
|
|
83
|
+
|
|
84
|
+
- Node.js (LTS) and npm
|
|
85
|
+
- A GitHub Personal Access Token. **Fine-grained (recommended, least privilege)** — [create one here](https://github.com/settings/personal-access-tokens/new) scoped to the target repo.
|
|
86
|
+
- Required: Issues (read/write), Contents (read/write), Metadata (read), Pull requests (read/write), Administration (read/write)
|
|
87
|
+
- A classic PAT with the `repo` scope also works but grants broad access across all your repos — prefer fine-grained.
|
|
88
|
+
|
|
89
|
+
### Quick start (recommended)
|
|
90
|
+
|
|
91
|
+
No installation needed. Add the `.mcp.json` and `.env` to your project as shown in [Usage with Claude Code](#usage-with-claude-code) above — `npx` fetches okffs automatically on first use.
|
|
92
|
+
|
|
93
|
+
### Local development setup
|
|
94
|
+
|
|
95
|
+
1. Clone the repo and install dependencies:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
git clone https://github.com/neturely/okffs.git
|
|
99
|
+
cd okffs
|
|
100
|
+
npm install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
2. Copy the environment template and fill in your credentials:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cp .env.example .env
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Auth & repo (all optional if you use the `gh` CLI and run inside the target repo — see [Authentication & repository](#authentication--repository)):
|
|
110
|
+
|
|
111
|
+
```env
|
|
112
|
+
GITHUB_TOKEN=ghp_your_personal_access_token_here # or sign in with `gh auth login`
|
|
113
|
+
GITHUB_OWNER=your-github-username # auto-detected from git origin if omitted
|
|
114
|
+
GITHUB_REPO=your-repo-name # auto-detected from git origin if omitted
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
3. Optionally set defaults applied to every new issue:
|
|
118
|
+
|
|
119
|
+
```env
|
|
120
|
+
OKFFS_DEFAULT_ASSIGNEES=your-github-username # comma-separated
|
|
121
|
+
OKFFS_DEFAULT_LABELS=okffs # merged with any inferred labels
|
|
122
|
+
OKFFS_PROMPT_METADATA=true # set to false to hide the tip
|
|
123
|
+
OKFFS_BASE_BRANCH=main # branch to create issues from; defaults to repo default
|
|
124
|
+
OKFFS_IDENTIFIER=okffs # optional prefix: branches become {number}-{identifier}-{slug}
|
|
125
|
+
OKFFS_UPDATE_DOCS=false # set to true to auto-update project docs on workflow events
|
|
126
|
+
OKFFS_AUTO_PR=false # set to true to open a draft PR when a new issue branch is created
|
|
127
|
+
OKFFS_RESOLVE_THREADS=false # set to true to let okffs auto-resolve PR review threads after they're addressed
|
|
128
|
+
OKFFS_UPDATE_GUIDANCE=false # set to true to nudge keeping CLAUDE.md in sync with functionality changes at PR time
|
|
129
|
+
OKFFS_EXCLUDE_DOCS=SECURITY.md # comma-separated — valid options: CHANGELOG.md, SECURITY.md
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
4. Build and point your `.mcp.json` at the local build:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run build
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"mcpServers": {
|
|
141
|
+
"okffs": {
|
|
142
|
+
"command": "node",
|
|
143
|
+
"args": ["dist/index.js"]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Tools
|
|
150
|
+
|
|
151
|
+
| Tool | Description |
|
|
152
|
+
|------|-------------|
|
|
153
|
+
| `create_issue` | Creates a GitHub issue and a matching branch. Infers labels automatically; merges them with `OKFFS_DEFAULT_LABELS`. Supports optional `assignees`, `labels`, and `milestone`. If `OKFFS_AUTO_PR=true`, pushes an empty init commit and opens a draft PR for the branch immediately. |
|
|
154
|
+
| `create_issues_from_list` | Creates multiple issues and branches from a task list in one shot. Confirms before acting. Per-task `labels`, `assignees`, and `milestone` supported. |
|
|
155
|
+
| `plan` | Takes a free-text description of work plus the issue breakdown Claude generates from it (titles, descriptions, labels, inter-task relationships) and creates all issues + branches in one shot. Two-step confirmation. Wires up relationships between the new issues; opens a draft PR per branch when `OKFFS_AUTO_PR=true`. |
|
|
156
|
+
| `list_issues` | Lists all open issues, each with its issue URL, branch + URL, any linked open/draft PR (matched by head branch), and its relationships (parent, children, blocked-by, blocking) as a tree. |
|
|
157
|
+
| `get_issue` | Fetches full details of an issue — title, body, labels, assignees, branch, and status. |
|
|
158
|
+
| `comment_issue` | Posts a comment to an issue. Useful for logging work done on a branch. |
|
|
159
|
+
| `link_issues` | Links two issues with a relationship — `blocked_by`, `blocking`, or `parent`. Stored in the issue body under a `## Relationships` section. |
|
|
160
|
+
| `close_issue` | Closes a GitHub issue by number. Returns a tip to run `/clear` in Claude Code before starting the next issue. |
|
|
161
|
+
| `create_pull_request` | Creates a PR for an issue branch. Generates title and body from the issue, commits, and comments. If `OKFFS_UPDATE_DOCS=true`, commits the updated CHANGELOG onto the branch; pushes the branch before opening the PR. Always includes `Closes #N`. Posts a summary comment to the issue. |
|
|
162
|
+
| `commit_and_update` | Stages all changes, builds a commit message from the provided `hint` (or the changed file list), commits, pushes to the issue branch, and posts a rich progress comment to the linked issue. |
|
|
163
|
+
| `list_pr_review_comments` | Fetches a PR's review feedback: inline comment threads (with comment ids, file/line, author, body, resolved state) and review summaries. |
|
|
164
|
+
| `reply_to_review_comment` | Replies to an inline PR review comment thread by id. |
|
|
165
|
+
| `resolve_review_thread` | Marks a PR review thread resolved. Gated by `OKFFS_RESOLVE_THREADS` — declines unless that's enabled, leaving threads for you to resolve. |
|
|
166
|
+
| `prepare_release` | Bumps the version (`package.json` + `package-lock.json`), rolls the CHANGELOG (`[Unreleased]` → a dated version section), commits on a release branch, and opens a PR. Two-step confirm; takes an explicit `version` or `bump` level (inferred if omitted). Does **not** tag or publish. |
|
|
167
|
+
| `delete_issue` | Closes an issue **and** deletes its matching branch. Destructive — requires `confirmed: true`. |
|
|
168
|
+
| `delete_branch` | Deletes a branch **and** closes its matching issue. Destructive — requires `confirmed: true`. |
|
|
169
|
+
|
|
170
|
+
Destructive tools (`delete_issue`, `delete_branch`) follow a two-step confirmation pattern: call once to see a warning, then re-call with `confirmed: true` to proceed. A comment is posted to the issue before any action is taken.
|
|
171
|
+
|
|
172
|
+
## Responding to PR reviews
|
|
173
|
+
|
|
174
|
+
okffs ships a workflow for handling pull request review feedback out of the box. Just ask Claude in natural language, e.g.:
|
|
175
|
+
|
|
176
|
+
- *"Address the review comments on PR #42"*
|
|
177
|
+
- *"Can you fix any of the commented issues on the PR?"*
|
|
178
|
+
|
|
179
|
+
Claude reads the review threads (`list_pr_review_comments`), fixes the valid ones, commits and pushes (`commit_and_update`), replies to each thread (`reply_to_review_comment`), and posts an overall summary (`comment_issue`). Claude provides the judgment and code fixes; okffs provides the GitHub plumbing.
|
|
180
|
+
|
|
181
|
+
There's also a ready-made prompt exposed as a slash command — **`/okffs:address_pr_review`** (takes a PR number) — that runs the same loop.
|
|
182
|
+
|
|
183
|
+
Review threads are only auto-resolved when `OKFFS_RESOLVE_THREADS=true`; by default they're left open for you to read and resolve yourself.
|
|
184
|
+
|
|
185
|
+
## Keeping CLAUDE.md in sync
|
|
186
|
+
|
|
187
|
+
The **`/okffs:update_guidance`** slash command (optionally takes an issue number) reviews the changes on the current branch and maintains a single okffs-owned section of `CLAUDE.md` — `## Project Guidance (okffs usage)`, delimited by `<!-- okffs:guidance:start -->` / `<!-- okffs:guidance:end -->` markers (created once if absent). It curates **only that region** (tools, env vars, prompts, conventions) and **never touches your hand-written content** elsewhere. It's *intelligent* guidance maintenance, not a changelog append (that's `CHANGELOG.md`'s job), and it does nothing when nothing substantive changed.
|
|
188
|
+
|
|
189
|
+
Set `OKFFS_UPDATE_GUIDANCE=true` to have `create_pull_request` nudge the agent to run it at PR time so the CLAUDE.md update lands in the same PR. The slash command is available either way.
|
|
190
|
+
|
|
191
|
+
## Automatic doc updates
|
|
192
|
+
|
|
193
|
+
When `OKFFS_UPDATE_DOCS=true` in your `.env`, okffs automatically updates local project docs when a pull request is created (`create_pull_request`). Changes are written to local files — committing is your responsibility. Commenting on or closing an issue does **not** trigger doc updates, to keep the CHANGELOG free of noise and duplicate entries.
|
|
194
|
+
|
|
195
|
+
Entries are **title-based one-liners** — concise and complete, so nothing needs manual cleanup.
|
|
196
|
+
|
|
197
|
+
Files updated when relevant:
|
|
198
|
+
- `CHANGELOG.md` — always updated, created if missing. Entries follow [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format, added under `## [Unreleased]`. `create_pull_request` updates it before opening the PR and commits it onto the branch so it's included in the diff.
|
|
199
|
+
- `SECURITY.md` — updated when security, vulnerability, or CVE keywords are detected (only if the file exists).
|
|
200
|
+
|
|
201
|
+
`CLAUDE.md` and `CONTRIBUTING.md` are **not** auto-updated — they previously received truncated, changelog-style appends that duplicated `CHANGELOG.md` and needed manual cleanup. `README.md` is also intentionally excluded — maintain it manually.
|
|
202
|
+
|
|
203
|
+
Use `OKFFS_EXCLUDE_DOCS` to exclude specific files per repo (valid options: `CHANGELOG.md`, `SECURITY.md`):
|
|
204
|
+
```env
|
|
205
|
+
OKFFS_EXCLUDE_DOCS=SECURITY.md
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Conventions
|
|
209
|
+
|
|
210
|
+
**Branch naming:** `{issue-number}-{kebab-title-slug}` (title truncated to ~5 words)
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
42-add-hero-section-to-homepage
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Pull requests:**
|
|
217
|
+
|
|
218
|
+
- Title: `Close #42 - Add hero section to homepage`
|
|
219
|
+
- Body always includes `Closes #42` so GitHub auto-closes the issue when the PR merges into the repository's **default branch** (usually `main`). If you set `OKFFS_BASE_BRANCH` to a non-default branch (e.g. `develop`), GitHub will not auto-close on merge — close the issue manually with `close_issue`. `create_pull_request` flags this when the PR targets a non-default base.
|
|
220
|
+
|
|
221
|
+
**Operating principles:**
|
|
222
|
+
|
|
223
|
+
- Destructive tools require `confirmed: true` — call once for a warning, re-call to proceed. Bulk-creating tools confirm before acting.
|
|
224
|
+
- GitHub is always the source of truth for issue state — never local.
|
|
225
|
+
- Keep the tool surface minimal: do one thing well per tool.
|
|
226
|
+
|
|
227
|
+
## Publishing to npm
|
|
228
|
+
|
|
229
|
+
Requires an npm account with maintainer access to the `@neturely/okffs` package (publishes publicly via `publishConfig.access`).
|
|
230
|
+
|
|
231
|
+
1. **Prepare the release** with the `prepare_release` tool (ask Claude, e.g. *"prepare a release"* or *"prepare release 0.2.0"*). It bumps `package.json` + `package-lock.json`, rolls the CHANGELOG, and opens a release PR. Review and merge it (then merge to `main`).
|
|
232
|
+
2. **Tag and push** the version:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
git tag v0.2.0
|
|
236
|
+
git push origin v0.2.0
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The GitHub Actions workflow publishes to npm automatically on semver tags (`v*.*.*`) — so **do not run `npm publish` manually** (it would collide with CI). The `NPM_TOKEN` secret must be set in the repository settings.
|
|
240
|
+
|
|
241
|
+
> `prepare_release` deliberately stops before tagging/publishing, keeping the irreversible step (the tag that triggers CI publish) a manual decision. You can still bump by hand if you prefer.
|
|
242
|
+
|
|
243
|
+
## Codebase search
|
|
244
|
+
|
|
245
|
+
This project uses [semble](https://github.com/MinishLab/semble) for semantic code search via MCP. The sub-agent config lives at `.claude/agents/semble-search.md` and is picked up automatically by Claude Code.
|
|
246
|
+
|
|
247
|
+
To search manually (requires `uv`):
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
uvx --from "semble[mcp]" semble search "your query" .
|
|
251
|
+
```
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const config: {
|
|
2
|
+
promptForMetadata: boolean;
|
|
3
|
+
defaultAssignees: string[];
|
|
4
|
+
defaultLabels: string[];
|
|
5
|
+
baseBranch: string | null;
|
|
6
|
+
identifier: string | null;
|
|
7
|
+
updateDocs: boolean;
|
|
8
|
+
autoPR: boolean;
|
|
9
|
+
resolveThreads: boolean;
|
|
10
|
+
updateGuidance: boolean;
|
|
11
|
+
excludeDocs: string[];
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;;;;;;;;CAyBlB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const config = {
|
|
2
|
+
promptForMetadata: process.env.OKFFS_PROMPT_METADATA !== "false",
|
|
3
|
+
defaultAssignees: process.env.OKFFS_DEFAULT_ASSIGNEES
|
|
4
|
+
? process.env.OKFFS_DEFAULT_ASSIGNEES.split(",").map((s) => s.trim())
|
|
5
|
+
: [],
|
|
6
|
+
defaultLabels: process.env.OKFFS_DEFAULT_LABELS
|
|
7
|
+
? process.env.OKFFS_DEFAULT_LABELS.split(",").map((s) => s.trim())
|
|
8
|
+
: [],
|
|
9
|
+
baseBranch: process.env.OKFFS_BASE_BRANCH || null,
|
|
10
|
+
// OKFFS_IDENTIFIER — optional project-scoped prefix inserted into branch names:
|
|
11
|
+
// {issue-number}-{identifier}-{slug} instead of {issue-number}-{slug}
|
|
12
|
+
identifier: process.env.OKFFS_IDENTIFIER || null,
|
|
13
|
+
updateDocs: process.env.OKFFS_UPDATE_DOCS === "true",
|
|
14
|
+
// OKFFS_AUTO_PR=true — creates a draft PR when a new issue branch is created
|
|
15
|
+
autoPR: process.env.OKFFS_AUTO_PR === "true",
|
|
16
|
+
// OKFFS_RESOLVE_THREADS=true — auto-resolve PR review threads after they are
|
|
17
|
+
// addressed. Default false: threads are left open for the user to resolve.
|
|
18
|
+
resolveThreads: process.env.OKFFS_RESOLVE_THREADS === "true",
|
|
19
|
+
// OKFFS_UPDATE_GUIDANCE=true — nudge the agent to keep CLAUDE.md in sync with
|
|
20
|
+
// new/changed functionality when a PR is created (intelligent, not a changelog
|
|
21
|
+
// append). Default false. The `update_guidance` prompt works regardless.
|
|
22
|
+
updateGuidance: process.env.OKFFS_UPDATE_GUIDANCE === "true",
|
|
23
|
+
excludeDocs: process.env.OKFFS_EXCLUDE_DOCS
|
|
24
|
+
? process.env.OKFFS_EXCLUDE_DOCS.split(",").map((s) => s.trim())
|
|
25
|
+
: [],
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,OAAO;IAChE,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACnD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,CAAC,CAAC,EAAE;IACN,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC7C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClE,CAAC,CAAC,EAAE;IACN,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI;IACjD,gFAAgF;IAChF,sEAAsE;IACtE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI;IAChD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,MAAM;IACpD,6EAA6E;IAC7E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM;IAC5C,6EAA6E;IAC7E,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM;IAC5D,8EAA8E;IAC9E,+EAA+E;IAC/E,yEAAyE;IACzE,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM;IAC5D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QACzC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,CAAC,CAAC,EAAE;CACP,CAAC"}
|
package/dist/docs.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DocsContext {
|
|
2
|
+
trigger: string;
|
|
3
|
+
issueNumber?: number;
|
|
4
|
+
issueTitle?: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
branchName?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function getUnreleasedSection(changelog: string): string | null;
|
|
9
|
+
export declare function rollChangelogForRelease(changelog: string, version: string, prevVersion: string, date: string): string;
|
|
10
|
+
export declare function updateProjectDocs(ctx: DocsContext): Promise<string[]>;
|
|
11
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8CD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOrE;AAKD,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,MAAM,CAiCR;AAyGD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqB3E"}
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { config } from "./config.js";
|
|
4
|
+
import { owner, repo } from "./github.js";
|
|
5
|
+
function isoDate() {
|
|
6
|
+
return new Date().toISOString().slice(0, 10);
|
|
7
|
+
}
|
|
8
|
+
function getChangeType(ctx) {
|
|
9
|
+
const lower = (ctx.issueTitle ?? ctx.trigger).toLowerCase();
|
|
10
|
+
if (/fix|bug|error|crash|broken/.test(lower))
|
|
11
|
+
return "Fixed";
|
|
12
|
+
if (/add|new|create|implement|feature/.test(lower))
|
|
13
|
+
return "Added";
|
|
14
|
+
if (/remove|delete|deprecat/.test(lower))
|
|
15
|
+
return "Removed";
|
|
16
|
+
if (/security|vulnerability|cve/.test(lower))
|
|
17
|
+
return "Security";
|
|
18
|
+
return "Changed";
|
|
19
|
+
}
|
|
20
|
+
// Truncate at a word boundary (never mid-word) so summaries don't get cut into
|
|
21
|
+
// a half-word followed by an ellipsis.
|
|
22
|
+
function truncateAtWord(text, max) {
|
|
23
|
+
if (text.length <= max)
|
|
24
|
+
return text;
|
|
25
|
+
const slice = text.slice(0, max);
|
|
26
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
27
|
+
return (lastSpace > 0 ? slice.slice(0, lastSpace) : slice).trimEnd() + "…";
|
|
28
|
+
}
|
|
29
|
+
function buildChangelogEntry(ctx) {
|
|
30
|
+
const ref = ctx.issueNumber ? ` ([#${ctx.issueNumber}](https://github.com/${owner}/${repo}/issues/${ctx.issueNumber}))` : "";
|
|
31
|
+
// Title-based entry: titles are already concise and complete, so the entry is
|
|
32
|
+
// readable with nothing to curate. We deliberately do NOT append a truncated
|
|
33
|
+
// excerpt of the (often long) summary — that produced incomplete-looking,
|
|
34
|
+
// ellipsis-ended entries that needed manual cleanup on every PR. truncateAtWord
|
|
35
|
+
// remains only as a safety net for an unusually long title.
|
|
36
|
+
// Prefer the issue title; fall back to the summary (non-issue triggers like
|
|
37
|
+
// delete_branch pass a meaningful summary but no title) before the bare trigger.
|
|
38
|
+
const source = ctx.issueTitle || ctx.summary || ctx.trigger;
|
|
39
|
+
const title = truncateAtWord(source.replace(/\s+/g, " ").trim(), 120);
|
|
40
|
+
return `- ${title}${ref}`;
|
|
41
|
+
}
|
|
42
|
+
// Return the body of the ## [Unreleased] section (everything between that
|
|
43
|
+
// heading and the next "## [" version heading), or null if there's no marker.
|
|
44
|
+
export function getUnreleasedSection(changelog) {
|
|
45
|
+
const marker = "## [Unreleased]";
|
|
46
|
+
const idx = changelog.indexOf(marker);
|
|
47
|
+
if (idx === -1)
|
|
48
|
+
return null;
|
|
49
|
+
const after = idx + marker.length;
|
|
50
|
+
const nextRel = changelog.slice(after).search(/\n## \[/);
|
|
51
|
+
return (nextRel === -1 ? changelog.slice(after) : changelog.slice(after, after + nextRel)).trim();
|
|
52
|
+
}
|
|
53
|
+
// Roll the CHANGELOG for a release: move the [Unreleased] entries under a new
|
|
54
|
+
// "## [version] - date" heading, leave a fresh empty [Unreleased], and update
|
|
55
|
+
// the compare links at the bottom. Returns the new changelog text.
|
|
56
|
+
export function rollChangelogForRelease(changelog, version, prevVersion, date) {
|
|
57
|
+
const marker = "## [Unreleased]";
|
|
58
|
+
const idx = changelog.indexOf(marker);
|
|
59
|
+
if (idx === -1)
|
|
60
|
+
throw new Error("CHANGELOG.md has no ## [Unreleased] section.");
|
|
61
|
+
const after = idx + marker.length;
|
|
62
|
+
const nextRel = changelog.slice(after).search(/\n## \[/);
|
|
63
|
+
const bodyEnd = nextRel === -1 ? changelog.length : after + nextRel;
|
|
64
|
+
const body = changelog.slice(after, bodyEnd).replace(/\s+$/, ""); // entries, trimmed
|
|
65
|
+
const head = changelog.slice(0, after); // up to & including "## [Unreleased]"
|
|
66
|
+
const tail = changelog.slice(bodyEnd); // "\n## [prev]…" onward (incl. links)
|
|
67
|
+
let result = `${head}\n\n## [${version}] - ${date}${body}\n${tail}`;
|
|
68
|
+
// Update the compare links at the bottom.
|
|
69
|
+
const repoUrl = `https://github.com/${owner}/${repo}`;
|
|
70
|
+
const unreleasedLink = `[Unreleased]: ${repoUrl}/compare/v${version}...HEAD`;
|
|
71
|
+
const versionLink = `[${version}]: ${repoUrl}/compare/v${prevVersion}...v${version}`;
|
|
72
|
+
const versionRefExists = new RegExp(`^\\[${version.replace(/\./g, "\\.")}\\]:`, "m").test(result);
|
|
73
|
+
if (/^\[Unreleased\]:/m.test(result)) {
|
|
74
|
+
result = result.replace(/^\[Unreleased\]:.*$/m, unreleasedLink);
|
|
75
|
+
// Add the new version ref after [Unreleased], unless it's already there
|
|
76
|
+
// (avoids a duplicate if prepare_release is re-run for the same version).
|
|
77
|
+
if (!versionRefExists) {
|
|
78
|
+
result = result.replace(/^(\[Unreleased\]:.*\n)/m, `$1${versionLink}\n`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// No compare links yet (new/manually-edited changelog) — append a block.
|
|
83
|
+
result = result.replace(/\s*$/, "") + `\n\n${unreleasedLink}\n`;
|
|
84
|
+
if (!versionRefExists)
|
|
85
|
+
result += `${versionLink}\n`;
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
// Insert a changelog entry under the ## [Unreleased] section, scoping the search
|
|
90
|
+
// for the type heading (### Added, ### Fixed, …) to that section only. Without
|
|
91
|
+
// scoping, an existing "### Added" under the latest *released* version would
|
|
92
|
+
// match first and the entry would land in the wrong place.
|
|
93
|
+
function insertChangelogEntry(changelog, type, entry) {
|
|
94
|
+
const unreleasedMarker = "## [Unreleased]";
|
|
95
|
+
const typeHeading = `### ${type}`;
|
|
96
|
+
const markerIdx = changelog.indexOf(unreleasedMarker);
|
|
97
|
+
// No [Unreleased] section yet — add one above the first released version
|
|
98
|
+
// heading, or at the end of the file if there are none.
|
|
99
|
+
if (markerIdx === -1) {
|
|
100
|
+
const block = `${unreleasedMarker}\n${typeHeading}\n${entry}\n\n`;
|
|
101
|
+
const firstVersionIdx = changelog.search(/\n## \[/);
|
|
102
|
+
if (firstVersionIdx !== -1) {
|
|
103
|
+
const at = firstVersionIdx + 1; // preserve the leading newline
|
|
104
|
+
return changelog.slice(0, at) + block + changelog.slice(at);
|
|
105
|
+
}
|
|
106
|
+
return changelog.trimEnd() + "\n\n" + block.trimEnd() + "\n";
|
|
107
|
+
}
|
|
108
|
+
// Bounds of the [Unreleased] block: from the marker to the next "## " heading.
|
|
109
|
+
const afterMarker = markerIdx + unreleasedMarker.length;
|
|
110
|
+
const nextSectionRel = changelog.slice(afterMarker).search(/\n## /);
|
|
111
|
+
const blockEnd = nextSectionRel === -1 ? changelog.length : afterMarker + nextSectionRel;
|
|
112
|
+
const head = changelog.slice(0, afterMarker);
|
|
113
|
+
let block = changelog.slice(afterMarker, blockEnd);
|
|
114
|
+
const tail = changelog.slice(blockEnd);
|
|
115
|
+
const typeIdxInBlock = block.indexOf(typeHeading);
|
|
116
|
+
if (typeIdxInBlock !== -1) {
|
|
117
|
+
// Insert right after the existing type heading within the Unreleased block.
|
|
118
|
+
const insertAt = typeIdxInBlock + typeHeading.length;
|
|
119
|
+
block = block.slice(0, insertAt) + "\n" + entry + block.slice(insertAt);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Add the type heading and entry at the end of the Unreleased block.
|
|
123
|
+
block = block.replace(/\s*$/, "") + `\n${typeHeading}\n${entry}\n`;
|
|
124
|
+
}
|
|
125
|
+
return head + block + tail;
|
|
126
|
+
}
|
|
127
|
+
function shouldUpdateSecurity(ctx) {
|
|
128
|
+
const lower = (ctx.issueTitle ?? "") + ctx.summary;
|
|
129
|
+
return /security|vulnerability|cve/i.test(lower);
|
|
130
|
+
}
|
|
131
|
+
function readFile(filePath) {
|
|
132
|
+
try {
|
|
133
|
+
return fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : null;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function determineUpdates(ctx, base) {
|
|
140
|
+
const updates = [];
|
|
141
|
+
const isExcluded = (filename) => config.excludeDocs.some((f) => f.toLowerCase() === filename.toLowerCase());
|
|
142
|
+
// CHANGELOG.md — always append an entry under ## [Unreleased] or at the end
|
|
143
|
+
if (!isExcluded("CHANGELOG.md")) {
|
|
144
|
+
const changelogPath = path.join(base, "CHANGELOG.md");
|
|
145
|
+
const changelog = readFile(changelogPath);
|
|
146
|
+
const type = getChangeType(ctx);
|
|
147
|
+
const entry = buildChangelogEntry(ctx);
|
|
148
|
+
if (changelog !== null) {
|
|
149
|
+
updates.push({ path: changelogPath, content: insertChangelogEntry(changelog, type, entry), created: false });
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
updates.push({
|
|
153
|
+
path: changelogPath,
|
|
154
|
+
content: `# Changelog\n\nAll notable changes to this project will be documented in this file.\nSee [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).\n\n## [Unreleased]\n### ${type}\n${entry}`,
|
|
155
|
+
created: true,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// SECURITY.md — only for security-related triggers. Title-based one-liner.
|
|
160
|
+
if (shouldUpdateSecurity(ctx) && !isExcluded("SECURITY.md")) {
|
|
161
|
+
const secPath = path.join(base, "SECURITY.md");
|
|
162
|
+
const sec = readFile(secPath);
|
|
163
|
+
if (sec !== null) {
|
|
164
|
+
const source = ctx.issueTitle || ctx.summary || ctx.trigger;
|
|
165
|
+
const title = truncateAtWord(source.replace(/\s+/g, " ").trim(), 120);
|
|
166
|
+
const line = `\n- ${isoDate()}${ctx.issueNumber ? ` (#${ctx.issueNumber})` : ""}: ${title}`;
|
|
167
|
+
updates.push({ path: secPath, content: sec.trimEnd() + line, created: false });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Note: CLAUDE.md and CONTRIBUTING.md are intentionally NOT auto-updated.
|
|
171
|
+
// They previously got truncated "## Recent Changes"/"## Changelog" appends
|
|
172
|
+
// that duplicated the CHANGELOG and required manual cleanup every PR. The
|
|
173
|
+
// CHANGELOG is the single auto-doc target now (plus SECURITY.md when relevant).
|
|
174
|
+
return updates;
|
|
175
|
+
}
|
|
176
|
+
// Returns the repo-relative paths of the files that were actually written, so
|
|
177
|
+
// callers can stage exactly those (rather than assuming only CHANGELOG.md
|
|
178
|
+
// changed). Paths are relative to base (process.cwd()) so they pass cleanly to
|
|
179
|
+
// `git add`, which runs from the same working directory.
|
|
180
|
+
export async function updateProjectDocs(ctx) {
|
|
181
|
+
try {
|
|
182
|
+
const base = process.cwd();
|
|
183
|
+
const updates = determineUpdates(ctx, base);
|
|
184
|
+
if (updates.length === 0)
|
|
185
|
+
return [];
|
|
186
|
+
const written = [];
|
|
187
|
+
for (const u of updates) {
|
|
188
|
+
try {
|
|
189
|
+
fs.writeFileSync(u.path, u.content, "utf8");
|
|
190
|
+
written.push(path.relative(base, u.path));
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
console.warn(`[okffs] docs: failed to write ${u.path}:`, err);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return written;
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
console.warn("[okffs] docs: unexpected error:", err);
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Run a git command with arguments passed as an array. Throws on failure. */
|
|
2
|
+
export declare function git(args: string[]): void;
|
|
3
|
+
/** Run a git command and return its trimmed stdout. Throws on failure. */
|
|
4
|
+
export declare function gitOutput(args: string[]): string;
|
|
5
|
+
/** Current branch name, or null if it can't be determined. */
|
|
6
|
+
export declare function currentBranch(): string | null;
|
|
7
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAExC;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEhD;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAM7C"}
|