@neturely/okffs 0.4.0 → 0.5.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/README.md +106 -250
  3. package/dist/board.d.ts +33 -0
  4. package/dist/board.d.ts.map +1 -0
  5. package/dist/board.js +171 -0
  6. package/dist/board.js.map +1 -0
  7. package/dist/config.d.ts +1 -0
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +8 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/github.d.ts +1 -0
  12. package/dist/github.d.ts.map +1 -1
  13. package/dist/github.js +6 -0
  14. package/dist/github.js.map +1 -1
  15. package/dist/index.js +19 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/projects.d.ts.map +1 -1
  18. package/dist/projects.js +30 -12
  19. package/dist/projects.js.map +1 -1
  20. package/dist/tools/close_issue.d.ts +1 -1
  21. package/dist/tools/close_issue.d.ts.map +1 -1
  22. package/dist/tools/close_issue.js +38 -3
  23. package/dist/tools/close_issue.js.map +1 -1
  24. package/dist/tools/create_issue.d.ts +5 -4
  25. package/dist/tools/create_issue.d.ts.map +1 -1
  26. package/dist/tools/create_issue.js +53 -114
  27. package/dist/tools/create_issue.js.map +1 -1
  28. package/dist/tools/create_issues_from_list.d.ts +11 -1
  29. package/dist/tools/create_issues_from_list.d.ts.map +1 -1
  30. package/dist/tools/create_issues_from_list.js +39 -2
  31. package/dist/tools/create_issues_from_list.js.map +1 -1
  32. package/dist/tools/create_pull_request.d.ts +4 -1
  33. package/dist/tools/create_pull_request.d.ts.map +1 -1
  34. package/dist/tools/create_pull_request.js +18 -1
  35. package/dist/tools/create_pull_request.js.map +1 -1
  36. package/dist/tools/delete_branch.d.ts.map +1 -1
  37. package/dist/tools/delete_branch.js +3 -10
  38. package/dist/tools/delete_branch.js.map +1 -1
  39. package/dist/tools/delete_issue.d.ts.map +1 -1
  40. package/dist/tools/delete_issue.js +3 -11
  41. package/dist/tools/delete_issue.js.map +1 -1
  42. package/dist/tools/plan.d.ts +11 -1
  43. package/dist/tools/plan.d.ts.map +1 -1
  44. package/dist/tools/plan.js +47 -5
  45. package/dist/tools/plan.js.map +1 -1
  46. package/dist/tools/prepare_release.d.ts.map +1 -1
  47. package/dist/tools/prepare_release.js +15 -1
  48. package/dist/tools/prepare_release.js.map +1 -1
  49. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,27 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.5.1] - 2026-07-04
9
+ ### Added
10
+ - publish.yml: create the GitHub Release automatically on stable tags ([#156](https://github.com/neturely/okffs/issues/156))
11
+ - Add OKFFS_PROTECTED_BRANCH — hard confirmation gate before okffs promotes into a protected branch ([#152](https://github.com/neturely/okffs/issues/152))
12
+ ### Changed
13
+ - Guidance: agents using okffs should prefer its tools/env over raw gh/git (fallback only) ([#154](https://github.com/neturely/okffs/issues/154))
14
+ ### Fixed
15
+ - `delete_branch` and `delete_issue` no longer write changelog fragments for pure cleanup — `create_pull_request` remains the single source of auto-changelog entries, matching `close_issue` ([#160](https://github.com/neturely/okffs/issues/160)).
16
+ - `close_issue` now cleans up an untouched `OKFFS_AUTO_PR` draft: when an issue is closed with no work, its empty draft PR is closed and the branch deleted (a ready PR, or a branch with real commits, is left untouched) ([#162](https://github.com/neturely/okffs/issues/162)).
17
+
18
+ ## [0.5.0] - 2026-07-04
19
+ ### Changed
20
+ - Rewrote the README for a friendlier first read: a plain-language intro and one-step quickstart up front, the internal build-phase "Status" section removed, and the scattered env-var documentation consolidated into a single Configuration reference table. Development setup, publishing, and codebase-search detail moved to CONTRIBUTING.md (#142).
21
+ - `create_issue` now injects the board's **real** Priority/Effort option names into its inference guidance (resolved at tools/list time), so Claude infers against the actual board options — e.g. a `P0/P1/P2` board — instead of the generic `Urgent/High/Medium/Low` scale. Falls back to the generic scale when the board is unreachable or the options can't be read (#133).
22
+ ### Fixed
23
+ - Harden org Issue Field / Projects queries against pagination truncation: bump the org `issueFields` and per-issue `issueFieldValues` page sizes (and the project `fields` query) so Priority/Effort are reliably found on boards/orgs with many fields, rather than being missed past the first page (PR #140 review). Also corrected the `create_pull_request` tool description to reflect the fragment-based `OKFFS_UPDATE_DOCS` behaviour (it writes a `.changes/unreleased/` fragment, not a direct `CHANGELOG.md` edit).
24
+ - Board Priority/Effort/initial-status steps that are skipped or fail are now surfaced in the tool response instead of only being written to the server's stderr (`console.warn`), which the host and user never see. When a field is requested but not applied (e.g. the board's field is an org-level Issue Field needing a classic PAT, or the value has no matching option), `create_issue`, `create_issues_from_list`, and `plan` now print a `⚠` line explaining why — an enabled board step is never silently dropped (#146).
25
+ - The org-level Issue Fields preview API (used for `list_issues` Priority/Effort and `create_issue` option lookup) is now retried up to 3 times with a short backoff on transient failures, making it far less likely to intermittently drop Priority/Effort. Permission errors (403/FORBIDDEN) are still reported immediately without retry (#137).
26
+ ### Added
27
+ - `create_issues_from_list` and `plan` now place each issue on the GitHub Projects v2 board like `create_issue` does — adding it, setting an inferred/default Priority and Effort, and applying `OKFFS_PROJECT_INITIAL_STATUS` — when `OKFFS_PROJECT_AUTO_ADD=true`. Both tools gained per-task `priority`/`effort` params. Board logic is now shared in `src/board.ts` (#144).
28
+
8
29
  ## [0.4.0] - 2026-07-03
9
30
  ### Added
10
31
  - Priority-aware workflow: `list_issues` now shows each issue's `priority:` and **orders the listing by Priority** (Urgent → High → Medium → Low → unset) so the most important work surfaces first when deciding what to do next. New `OKFFS_DEFAULT_PRIORITY` env var applies a fallback Priority to new issues when `create_issue` isn't given one (mirrors `OKFFS_DEFAULT_LABELS`). Priority is read from a project-native field, or a GitHub org-level Issue Field when `OKFFS_CLASSIC_PAT=true`.
@@ -84,7 +105,9 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
84
105
  - `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)).
85
106
  - 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.
86
107
 
87
- [Unreleased]: https://github.com/neturely/okffs/compare/v0.4.0...HEAD
108
+ [Unreleased]: https://github.com/neturely/okffs/compare/v0.5.1...HEAD
109
+ [0.5.1]: https://github.com/neturely/okffs/compare/v0.5.0...v0.5.1
110
+ [0.5.0]: https://github.com/neturely/okffs/compare/v0.4.0...v0.5.0
88
111
  [0.4.0]: https://github.com/neturely/okffs/compare/v0.3.0...v0.4.0
89
112
  [0.3.0]: https://github.com/neturely/okffs/compare/v0.2.2...v0.3.0
90
113
  [0.2.2]: https://github.com/neturely/okffs/compare/v0.2.1...v0.2.2
package/README.md CHANGED
@@ -1,33 +1,21 @@
1
1
  # okffs
2
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.
3
+ [![npm version](https://img.shields.io/npm/v/@neturely/okffs.svg)](https://www.npmjs.com/package/@neturely/okffs)
4
+ [![license: MIT](https://img.shields.io/npm/l/@neturely/okffs.svg)](https://github.com/neturely/okffs/blob/main/LICENSE)
5
+ [![MCP](https://img.shields.io/badge/MCP-server-blue.svg)](https://modelcontextprotocol.io)
4
6
 
5
- ## Stack
7
+ **Turn a conversation with Claude into GitHub issues, branches, and pull requests — without leaving Claude Code.**
6
8
 
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)
9
+ okffs is a [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude Code a clean **issue → branch → PR → close** workflow on GitHub. Talk through the work in plain language; okffs creates the issues, matching branches, and pull requests, keeps them linked, and (optionally) syncs a GitHub Projects board — all in one shot.
10
10
 
11
- ## Status
11
+ - **One-shot planning** — describe a chunk of work and get every issue + branch created, with relationships wired up.
12
+ - **The whole loop** — create, comment, commit, open PRs, handle review feedback, and close, each as a simple ask.
13
+ - **Sensible defaults** — Claude infers labels, priority, and effort from the task; GitHub stays the single source of truth.
14
+ - **Little to no config** — signed in with the `gh` CLI inside your repo? You're ready.
12
15
 
13
- This project is being built in phases. See [CLAUDE.md](CLAUDE.md) for the full roadmap.
16
+ ## Quick start
14
17
 
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) | Done |
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:
18
+ Add a `.mcp.json` to your project root:
31
19
 
32
20
  ```json
33
21
  {
@@ -40,270 +28,138 @@ Add okffs to any project by creating a `.mcp.json` in the project root:
40
28
  }
41
29
  ```
42
30
 
43
- ### Authentication & repository
31
+ That's it `npx` fetches okffs on first use, and Claude Code picks up the tools automatically. If you're signed in with the [GitHub CLI](https://cli.github.com/) (`gh auth login`) and working inside the repo you want to manage, **no other setup is needed**. To use a token or a different repo instead, see [Configuration](#configuration).
44
32
 
45
- okffs needs a GitHub token and a target repository. It resolves both with sensible fallbacks, so most users need little or no config:
33
+ Now just ask Claude:
46
34
 
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.
35
+ - *"Create an issue called 'Fix login button' and start a branch for it."*
36
+ - *"Plan the work for adding user authentication and create the issues."*
37
+ - *"Create issues from this task list: …"*
38
+ - *"List all open issues."*
39
+ - *"Mark issue #5 as blocked by issue #3."*
40
+ - *"Done with issue #42 — open a PR and close it."*
41
+ - *"Address the review comments on PR #42."*
52
42
 
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_DEFAULT_PRIORITY=Medium # fallback board Priority when create_issue isn't given one
123
- OKFFS_DEFAULT_EFFORT=Medium # fallback board Effort when create_issue isn't given one
124
- OKFFS_INFER_PRIORITY=true # let Claude infer priority from the task (falls back to the default)
125
- OKFFS_INFER_EFFORT=true # let Claude infer effort from the task (falls back to the default)
126
- OKFFS_PROMPT_METADATA=true # set to false to hide the tip
127
- OKFFS_BASE_BRANCH=main # branch to create issues from; defaults to repo default
128
- OKFFS_IDENTIFIER=okffs # optional prefix: branches become {number}-{identifier}-{slug}
129
- OKFFS_UPDATE_DOCS=false # set to true to auto-update project docs on workflow events
130
- OKFFS_AUTO_PR=false # set to true to open a draft PR when a new issue branch is created
131
- OKFFS_RESOLVE_THREADS=false # set to true to let okffs auto-resolve PR review threads after they're addressed
132
- OKFFS_UPDATE_GUIDANCE=false # set to true to nudge keeping CLAUDE.md in sync with functionality changes at PR time
133
- OKFFS_EXCLUDE_DOCS=SECURITY.md # comma-separated — valid options: CHANGELOG.md, SECURITY.md
134
- OKFFS_PROJECT_ENABLED=false # set to true to enable the GitHub Projects v2 integration
135
- OKFFS_PROJECT_ID= # the Project's GraphQL node ID (e.g. PVT_kwHO...); required when enabled
136
- OKFFS_PROJECT_AUTO_ADD=false # fallback: create_issue adds new issues to the board (skip if your board auto-adds natively)
137
- OKFFS_PROJECT_INITIAL_STATUS=Backlog # board column a freshly auto-added issue lands in (beats the linked-PR "In Progress" promotion)
138
- OKFFS_CLASSIC_PAT=false # set true ONLY with a classic admin:org PAT — enables org-level Issue Field Priority/Effort (security tradeoff)
139
- ```
140
-
141
- 4. Build and point your `.mcp.json` at the local build:
142
-
143
- ```bash
144
- npm run build
145
- ```
146
-
147
- ```json
148
- {
149
- "mcpServers": {
150
- "okffs": {
151
- "command": "node",
152
- "args": ["dist/index.js"]
153
- }
154
- }
155
- }
156
- ```
43
+ Claude infers labels (`bug`, `enhancement`, …) from the title and description and merges them with any you've set as defaults.
157
44
 
158
45
  ## Tools
159
46
 
160
- | Tool | Description |
47
+ | Tool | What it does |
161
48
  |------|-------------|
162
- | `create_issue` | Creates a GitHub issue and a matching branch. Infers labels automatically; merges them with `OKFFS_DEFAULT_LABELS`. Also infers a board `priority` and `effort` from the task (toggle with `OKFFS_INFER_PRIORITY`/`OKFFS_INFER_EFFORT`, default on), falling back to `OKFFS_DEFAULT_PRIORITY`/`OKFFS_DEFAULT_EFFORT`. Supports optional `assignees`, `labels`, `milestone`, `priority`, `effort`. If `OKFFS_AUTO_PR=true`, pushes an empty init commit and opens a draft PR for the branch immediately. |
163
- | `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. |
164
- | `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`. |
165
- | `list_issues` | Lists all open issues, each with its issue URL, branch + URL, any linked open/draft PR (matched by head branch), its board column (`project:`), its `priority:`/`effort:`, and its relationships (parent, children, blocked-by, blocking) as a tree. Ordered by Priority (Urgent → High → Medium → Low → unset) so the most important work surfaces first. |
166
- | `get_issue` | Fetches full details of an issue title, body, labels, assignees, branch, and status. |
167
- | `comment_issue` | Posts a comment to an issue. Useful for logging work done on a branch. |
168
- | `link_issues` | Links two issues with a relationship — `blocked_by`, `blocking`, or `parent`. Stored in the issue body under a `## Relationships` section. |
169
- | `close_issue` | Closes a GitHub issue by number. Returns a tip to run `/clear` in Claude Code before starting the next issue. |
170
- | `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`, writes a per-issue changelog **fragment** under `.changes/unreleased/` (assembled into `CHANGELOG.md` at release time by `prepare_release`) and commits it onto the branch; pushes the branch before opening the PR. Always includes `Closes #N`. Posts a summary comment to the issue. |
171
- | `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. |
172
- | `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. |
173
- | `reply_to_review_comment` | Replies to an inline PR review comment thread by id. |
174
- | `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. |
175
- | `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. |
176
- | `update_project_status` | Moves an issue between GitHub Project board columns (`Backlog`, `Ready`, `In Progress`, `Review`) via GraphQL. `Done` is intentionally excluded — native GitHub automation owns it on merge/close. Requires `OKFFS_PROJECT_ENABLED`. |
177
- | `delete_issue` | Closes an issue **and** deletes its matching branch. Destructive — requires `confirmed: true`. |
178
- | `delete_branch` | Deletes a branch **and** closes its matching issue. Destructive — requires `confirmed: true`. |
179
-
180
- 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.
181
-
182
- ## Responding to PR reviews
183
-
184
- okffs ships a workflow for handling pull request review feedback out of the box. Just ask Claude in natural language, e.g.:
185
-
186
- - *"Address the review comments on PR #42"*
187
- - *"Can you fix any of the commented issues on the PR?"*
188
-
189
- 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.
190
-
191
- 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.
192
-
193
- Review threads are only auto-resolved when `OKFFS_RESOLVE_THREADS=true`; by default they're left open for you to read and resolve yourself.
49
+ | `create_issue` | Creates an issue and a matching branch. Infers labels, and a board `priority`/`effort` from the task (toggle with `OKFFS_INFER_PRIORITY`/`OKFFS_INFER_EFFORT`). Optional `assignees`, `labels`, `milestone`, `priority`, `effort`. Opens a draft PR immediately when `OKFFS_AUTO_PR=true`. |
50
+ | `create_issues_from_list` | Creates many issues + branches from a task list in one shot. Confirms first. Per-task `labels`, `assignees`, `milestone`, `priority`, `effort`. |
51
+ | `plan` | Give it a free-text description plus the breakdown Claude generates (titles, descriptions, labels, relationships); it creates every issue + branch, wires up relationships, and opens draft PRs when `OKFFS_AUTO_PR=true`. Confirms first. |
52
+ | `list_issues` | Lists open issues with branch, linked PR, board column, `priority:`/`effort:`, and relationships as a tree ordered by priority so the most important work is on top. |
53
+ | `get_issue` | Full details for one issue: title, body, labels, assignees, branch, status. |
54
+ | `comment_issue` | Posts a comment handy for logging what a branch did. |
55
+ | `link_issues` | Links two issues (`blocked_by`, `blocking`, `parent`), stored under a `## Relationships` section. |
56
+ | `close_issue` | Closes an issue and tips you to `/clear` before the next one. |
57
+ | `create_pull_request` | Opens a PR for an issue branch generates the title/body, pushes the branch, always includes `Closes #N`, and comments back. Can write changelog fragments when `OKFFS_UPDATE_DOCS=true`. |
58
+ | `commit_and_update` | Stages, commits (message from your `hint` or the diff), pushes, and posts a progress comment to the issue. |
59
+ | `list_pr_review_comments` | Fetches a PR's inline review threads and summaries. |
60
+ | `reply_to_review_comment` | Replies to an inline review thread by id. |
61
+ | `resolve_review_thread` | Resolves a review thread only when `OKFFS_RESOLVE_THREADS=true`. |
62
+ | `prepare_release` | Bumps the version, rolls the CHANGELOG, commits on a release branch, and opens a PR. Confirms first; does not tag or publish. |
63
+ | `update_project_status` | Moves an issue between board columns (`Backlog`, `Ready`, `In Progress`, `Review`). Needs `OKFFS_PROJECT_ENABLED`. |
64
+ | `delete_issue` | Closes an issue **and** deletes its branch. Destructive — needs `confirmed: true`. |
65
+ | `delete_branch` | Deletes a branch **and** closes its issue. Destructive — needs `confirmed: true`. |
66
+
67
+ Destructive tools (`delete_issue`, `delete_branch`) always warn on the first call and only act when re-called with `confirmed: true`, posting a comment to the issue before doing anything.
68
+
69
+ ## Handling PR reviews
70
+
71
+ okffs has a built-in loop for review feedback just ask (*"address the review comments on PR #42"*). Claude reads the threads, fixes the valid ones, commits and pushes, replies per thread, and posts a summary. Claude brings the judgment and the fixes; okffs handles the GitHub plumbing. There's also a slash command, **`/okffs:address_pr_review`** (takes a PR number), that runs the same loop.
72
+
73
+ By default review threads are left open for you to resolve; set `OKFFS_RESOLVE_THREADS=true` to have okffs resolve them once addressed.
194
74
 
195
75
  ## Keeping CLAUDE.md in sync
196
76
 
197
- 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.
198
-
199
- 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.
77
+ The **`/okffs:update_guidance`** slash command reviews the changes on the current branch and maintains one okffs-owned section of your `CLAUDE.md` — `## Project Guidance (okffs usage)`, delimited by HTML markers without ever touching your hand-written content. It's guidance curation (tools, env vars, conventions), not a changelog. Set `OKFFS_UPDATE_GUIDANCE=true` to have `create_pull_request` nudge Claude to run it at PR time; the command is always available.
200
78
 
201
79
  ## Automatic doc updates
202
80
 
203
- 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.
204
-
205
- Entries are **title-based one-liners** — concise and complete, so nothing needs manual cleanup.
206
-
207
- Files updated when relevant:
208
- - `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.
209
- - `SECURITY.md` — updated when security, vulnerability, or CVE keywords are detected (only if the file exists).
81
+ With `OKFFS_UPDATE_DOCS=true`, `create_pull_request` writes doc updates onto the branch so they land in the PR diff:
210
82
 
211
- `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.
83
+ - **CHANGELOG.md** a per-issue [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) **fragment** under `.changes/unreleased/`, assembled into `CHANGELOG.md` at release time by `prepare_release`. Uniquely-named fragments avoid merge conflicts across parallel branches.
84
+ - **SECURITY.md** — updated when security-related keywords are detected (only if the file exists).
212
85
 
213
- Use `OKFFS_EXCLUDE_DOCS` to exclude specific files per repo (valid options: `CHANGELOG.md`, `SECURITY.md`):
214
- ```env
215
- OKFFS_EXCLUDE_DOCS=SECURITY.md
216
- ```
86
+ `CLAUDE.md`, `CONTRIBUTING.md`, and `README.md` are intentionally left for you to maintain. Exclude specific files per repo with `OKFFS_EXCLUDE_DOCS` (valid: `CHANGELOG.md`, `SECURITY.md`).
217
87
 
218
88
  ## GitHub Projects v2
219
89
 
220
- okffs can keep a GitHub **Projects v2** board in step with your issue workflow. It's **opt-in** and has zero overhead when off.
221
-
222
- Enable it in `.env`:
90
+ okffs can keep a **Projects v2** board in step with your workflow. It's opt-in with zero overhead when off:
223
91
 
224
- ```
92
+ ```env
225
93
  OKFFS_PROJECT_ENABLED=true
226
- OKFFS_PROJECT_ID=PVT_kwHO... # the board's GraphQL node ID
227
- OKFFS_PROJECT_AUTO_ADD=false # see "auto-add vs native automation" below
94
+ OKFFS_PROJECT_ID=PVT_kwHO... # the board's GraphQL node ID
228
95
  ```
229
96
 
230
- Once enabled:
231
-
232
- - **`list_issues`** shows each issue's current board column (e.g. `project: In Progress`) plus its `priority:` and `effort:`, and orders the listing by Priority.
233
- - **`update_project_status`** moves an issue between `Backlog`, `Ready`, `In Progress`, and `Review`.
234
- - **`create_issue`** can set a board `priority`/`effort` (inferred by Claude or from `OKFFS_DEFAULT_PRIORITY`/`OKFFS_DEFAULT_EFFORT`) and land the issue in `OKFFS_PROJECT_INITIAL_STATUS` (e.g. `Backlog`).
235
-
236
- ### Priority & Effort
237
-
238
- okffs sets and reads the board's **Priority** and **Effort** fields. Two field shapes are supported:
239
-
240
- - A **project-native single-select** field — works with a standard Projects-capable token.
241
- - A GitHub **org-level Issue Field** (the newer "Issue field" type shared across an org). These live outside the project and need a **classic PAT with the `admin:org` scope**; set **`OKFFS_CLASSIC_PAT=true`** to opt in. Fine-grained PATs can't reach them yet, so with the flag off okffs skips that path and tells you to set the value in the UI. ⚠️ A classic `admin:org` token is broad — only enable this if you accept that.
242
-
243
- Claude **infers** priority/effort from each task by default (like it infers labels), falling back to the `OKFFS_DEFAULT_*` values when it can't judge. Turn inference off per field with `OKFFS_INFER_PRIORITY=false` / `OKFFS_INFER_EFFORT=false`.
97
+ Once enabled, `list_issues` shows each issue's column, priority, and effort (ordered by priority); `update_project_status` moves issues between `Backlog`, `Ready`, `In Progress`, and `Review`; and `create_issue` can set priority/effort and an initial column. **`Done` is deliberately left to GitHub's native automation** (PR merge / issue close → Done) so two systems never fight over the terminal state.
244
98
 
245
- ### How Claude drives status transitions
99
+ **Priority & Effort** work as either a project-native single-select field (any Projects-capable token) or a GitHub org-level Issue Field. Org-level Issue Fields live outside the project and need a **classic PAT with `admin:org`** plus `OKFFS_CLASSIC_PAT=true` — fine-grained PATs can't reach them yet, so okffs skips that path and asks you to set the value in the UI. Claude infers priority/effort per task by default, falling back to the `OKFFS_DEFAULT_*` values.
246
100
 
247
- Column moves are **conversational**, not automatic. Claude offers them at the natural moments in the workflow — after `create_issue` puts an issue on the board it asks whether to move it to **In Progress** and start; when a PR goes up it can move the issue to **Review**. You stay in control; okffs just provides the `update_project_status` plumbing.
101
+ **Auto-add** (`OKFFS_PROJECT_AUTO_ADD`) is a fallback for boards without GitHub's native "Auto-add to project" workflow leave it `false` if your board already auto-adds.
248
102
 
249
- **`Done` is intentionally not settable** by okffsit's owned by GitHub's **native board automation** (the built-in "Item closed / PR merged Done" workflow). Since okffs always writes `Closes #N` into PRs, merging closes the issue and native automation moves the card to Done. This avoids two systems fighting over the terminal state.
103
+ **Token permission:** Projects v2 is GraphQL-only and needs a Projects-capable token a fine-grained PAT with *Organization Projects: Read and write*, or a classic PAT with the `project` scope. A single classic token with `repo` + `project` + `admin:org` covers everything, including org-level Issue Fields. Missing permission surfaces a clear `[okffs]` error naming what's needed.
250
104
 
251
- ### Auto-add vs native automation
105
+ ## Configuration
252
106
 
253
- `OKFFS_PROJECT_AUTO_ADD` is a **fallback**. GitHub Projects can natively auto-add issues to a board (Project Workflows → "Auto-add to project"). If you use that, leave `OKFFS_PROJECT_AUTO_ADD=false` okffs doesn't need to add issues itself. Only set it to `true` if your board has no native auto-add and you want `create_issue` to place new issues on the board (optionally with an initial `priority`/`effort` and `OKFFS_PROJECT_INITIAL_STATUS` column).
107
+ okffs resolves a **token** and a **target repository** with fallbacks, so most users need little config.
254
108
 
255
- ### Token permission
109
+ **Token** (first match wins):
110
+ 1. `GITHUB_TOKEN` in a `.env` file — either a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) (recommended; least privilege) with **Issues**, **Contents**, **Pull requests** (read/write), **Metadata** (read), and **Administration** (read/write) on the repo, or a [classic PAT](https://github.com/settings/tokens/new?scopes=repo&description=okffs) with the `repo` scope (broader — grants access across all your repos).
111
+ 2. Otherwise the **GitHub CLI** token — if you've run `gh auth login`, it just works.
256
112
 
257
- Projects v2 has no REST API, so okffs uses GraphQL, which needs a Projects-capable token:
258
-
259
- - **Fine-grained PAT** *Organization permissions* **Projects: Read and write**
260
- - **Classic PAT** → the **`project`** scope
261
-
262
- Setting a Priority/Effort that is an **org-level Issue Field** additionally needs a **classic PAT with `admin:org`** (plus `OKFFS_CLASSIC_PAT=true`) — fine-grained PATs return `FORBIDDEN` for that preview API. A single classic token with `repo` + `project` + `admin:org` covers everything.
263
-
264
- Without it, Projects calls fail with a clear `[okffs]` 403 error naming exactly what's missing. Reads/writes to an **org-level** board require the token to be able to see that org's projects.
265
-
266
- ## Conventions
113
+ **Repository** (first match wins):
114
+ 1. `GITHUB_OWNER` / `GITHUB_REPO` in `.env`.
115
+ 2. Otherwise **auto-detected** from the `origin` git remote of the directory okffs runs in.
267
116
 
268
- **Branch naming:** `{issue-number}-{kebab-title-slug}` (title truncated to ~5 words)
117
+ okffs loads `.env` automatically from that directory — no `--env-file` flag needed. A minimal explicit `.env`:
269
118
 
119
+ ```env
120
+ GITHUB_TOKEN=ghp_your_token_here
121
+ # Optional — auto-detected from the git origin remote when omitted:
122
+ GITHUB_OWNER=your-github-username
123
+ GITHUB_REPO=your-repo-name
270
124
  ```
271
- 42-add-hero-section-to-homepage
272
- ```
273
-
274
- **Pull requests:**
275
125
 
276
- - Title: `Close #42 - Add hero section to homepage`
277
- - 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.
126
+ ### Optional settings
127
+
128
+ All optional; unset unless noted. See [`.env.example`](.env.example) for a copyable template.
129
+
130
+ | Variable | Default | Purpose |
131
+ |----------|---------|---------|
132
+ | `OKFFS_DEFAULT_ASSIGNEES` | — | Comma-separated usernames assigned to every new issue. |
133
+ | `OKFFS_DEFAULT_LABELS` | — | Comma-separated labels merged with inferred ones. |
134
+ | `OKFFS_DEFAULT_PRIORITY` / `OKFFS_DEFAULT_EFFORT` | — | Board Priority/Effort fallback when none is inferred or given. |
135
+ | `OKFFS_INFER_PRIORITY` / `OKFFS_INFER_EFFORT` | `true` | Let Claude infer priority/effort from the task. |
136
+ | `OKFFS_PROMPT_METADATA` | `true` | Set `false` to hide the assignees/labels tip. |
137
+ | `OKFFS_BASE_BRANCH` | repo default | Branch new issue branches are created from. |
138
+ | `OKFFS_PROTECTED_BRANCH` | — | A branch okffs must never promote into without explicit user confirmation (e.g. `main`). `create_pull_request` refuses to target it without `confirmed: true`; `prepare_release` flags merging/tagging into it as a manual, user-gated step. |
139
+ | `OKFFS_IDENTIFIER` | — | Prefix for branch names: `{number}-{identifier}-{slug}`. |
140
+ | `OKFFS_AUTO_PR` | `false` | Open a draft PR when a new issue branch is created. |
141
+ | `OKFFS_RESOLVE_THREADS` | `false` | Auto-resolve PR review threads after they're addressed. |
142
+ | `OKFFS_UPDATE_GUIDANCE` | `false` | Nudge Claude to keep `CLAUDE.md` in sync at PR time. |
143
+ | `OKFFS_UPDATE_DOCS` | `false` | Auto-write CHANGELOG/SECURITY updates on `create_pull_request`. |
144
+ | `OKFFS_EXCLUDE_DOCS` | — | Comma-separated docs to skip (`CHANGELOG.md`, `SECURITY.md`). |
145
+ | `OKFFS_PROJECT_ENABLED` | `false` | Enable the GitHub Projects v2 integration. |
146
+ | `OKFFS_PROJECT_ID` | — | The board's GraphQL node ID (required when enabled). |
147
+ | `OKFFS_PROJECT_AUTO_ADD` | `false` | Add new issues to the board (fallback when the board has no native auto-add). |
148
+ | `OKFFS_PROJECT_INITIAL_STATUS` | — | Column a freshly added issue lands in (e.g. `Backlog`). |
149
+ | `OKFFS_CLASSIC_PAT` | `false` | Set `true` only with a classic `admin:org` PAT — enables org-level Issue Field Priority/Effort (broad token; security tradeoff). |
278
150
 
279
- **Operating principles:**
151
+ ## Conventions
280
152
 
281
- - Destructive tools require `confirmed: true` call once for a warning, re-call to proceed. Bulk-creating tools confirm before acting.
153
+ - **Branches:** `{issue-number}-{kebab-title-slug}` (title truncated to ~5 words), e.g. `42-add-hero-section-to-homepage`.
154
+ - **PRs:** titled `Close #42 - Add hero section to homepage`; the body always includes `Closes #42`. GitHub auto-closes the issue when the PR merges into the repo's **default branch**. If `OKFFS_BASE_BRANCH` points at a non-default branch (e.g. `develop`), close the issue manually with `close_issue` — `create_pull_request` flags this.
155
+ - Destructive tools require `confirmed: true`; bulk-creating tools confirm first.
282
156
  - GitHub is always the source of truth for issue state — never local.
283
- - Keep the tool surface minimal: do one thing well per tool.
284
-
285
- ## Publishing to npm
286
-
287
- Requires an npm account with maintainer access to the `@neturely/okffs` package (publishes publicly via `publishConfig.access`).
288
-
289
- 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`).
290
- 2. **Tag and push** the version:
291
-
292
- ```bash
293
- git tag v0.2.0
294
- git push origin v0.2.0
295
- ```
296
-
297
- 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.
298
-
299
- > `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.
157
+ - **Prefer okffs tools over raw `git`/`gh`.** When an okffs tool covers the action issues, PRs, comments, review threads (`resolve_review_thread` / `address_pr_review`), releases, project status — use it and honour its env toggles (`OKFFS_RESOLVE_THREADS`, `OKFFS_BASE_BRANCH`, `OKFFS_PROTECTED_BRANCH`, …) rather than re-deriving the behaviour. Fall back to raw `git`/`gh` only when no okffs tool fits.
300
158
 
301
- ## Codebase search
159
+ ## Contributing
302
160
 
303
- 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.
161
+ Bug reports, feature ideas, and PRs are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, how to add a tool, commit/branch conventions, and publishing. Release notes live in [CHANGELOG.md](CHANGELOG.md) and on the [Releases](https://github.com/neturely/okffs/releases) page.
304
162
 
305
- To search manually (requires `uv`):
163
+ ## License
306
164
 
307
- ```bash
308
- uvx --from "semble[mcp]" semble search "your query" .
309
- ```
165
+ [MIT](LICENSE)
@@ -0,0 +1,33 @@
1
+ export type BoardFieldOutcome = {
2
+ applied: string;
3
+ } | {
4
+ skipped: string;
5
+ };
6
+ export interface BoardAddResult {
7
+ itemId: string;
8
+ priority: BoardFieldOutcome | null;
9
+ effort: BoardFieldOutcome | null;
10
+ }
11
+ export interface InitialStatusResult {
12
+ applied: string | null;
13
+ skipped: string | null;
14
+ }
15
+ export declare function boardAutoAddEnabled(): boolean;
16
+ export declare function getBoardFieldOptions(label: string): Promise<string[] | null>;
17
+ export declare function addIssueToBoard(issueNodeId: string, opts: {
18
+ priority?: string | null;
19
+ effort?: string | null;
20
+ }): Promise<BoardAddResult>;
21
+ export declare function applyInitialStatus(itemId: string): Promise<InitialStatusResult>;
22
+ export declare function renderBoardLines(args: {
23
+ addedToBoard: boolean;
24
+ boardError: string | null;
25
+ requestedPriority?: string | null;
26
+ priority: BoardFieldOutcome | null;
27
+ requestedEffort?: string | null;
28
+ effort: BoardFieldOutcome | null;
29
+ requestedStatus?: string | null;
30
+ initialStatus: InitialStatusResult | null;
31
+ indent?: string;
32
+ }): string[];
33
+ //# sourceMappingURL=board.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,iBAAiB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAGD,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAQD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAelF;AAoED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzD,OAAO,CAAC,cAAc,CAAC,CAczB;AAMD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoBrF;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,EAAE,CA8BX"}