@neturely/okffs 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.changes/README.md +29 -0
  2. package/CHANGELOG.md +29 -1
  3. package/README.md +104 -232
  4. package/dist/board.d.ts +33 -0
  5. package/dist/board.d.ts.map +1 -0
  6. package/dist/board.js +171 -0
  7. package/dist/board.js.map +1 -0
  8. package/dist/config.d.ts +6 -0
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +31 -0
  11. package/dist/config.js.map +1 -1
  12. package/dist/docs.d.ts +6 -0
  13. package/dist/docs.d.ts.map +1 -1
  14. package/dist/docs.js +78 -15
  15. package/dist/docs.js.map +1 -1
  16. package/dist/index.js +19 -4
  17. package/dist/index.js.map +1 -1
  18. package/dist/projects.d.ts +18 -3
  19. package/dist/projects.d.ts.map +1 -1
  20. package/dist/projects.js +169 -18
  21. package/dist/projects.js.map +1 -1
  22. package/dist/tools/create_issue.d.ts +5 -1
  23. package/dist/tools/create_issue.d.ts.map +1 -1
  24. package/dist/tools/create_issue.js +82 -41
  25. package/dist/tools/create_issue.js.map +1 -1
  26. package/dist/tools/create_issues_from_list.d.ts +11 -1
  27. package/dist/tools/create_issues_from_list.d.ts.map +1 -1
  28. package/dist/tools/create_issues_from_list.js +39 -2
  29. package/dist/tools/create_issues_from_list.js.map +1 -1
  30. package/dist/tools/create_pull_request.d.ts +1 -1
  31. package/dist/tools/create_pull_request.d.ts.map +1 -1
  32. package/dist/tools/create_pull_request.js +1 -1
  33. package/dist/tools/create_pull_request.js.map +1 -1
  34. package/dist/tools/list_issues.d.ts +1 -1
  35. package/dist/tools/list_issues.d.ts.map +1 -1
  36. package/dist/tools/list_issues.js +58 -7
  37. package/dist/tools/list_issues.js.map +1 -1
  38. package/dist/tools/plan.d.ts +11 -1
  39. package/dist/tools/plan.d.ts.map +1 -1
  40. package/dist/tools/plan.js +47 -5
  41. package/dist/tools/plan.js.map +1 -1
  42. package/dist/tools/prepare_release.d.ts.map +1 -1
  43. package/dist/tools/prepare_release.js +22 -5
  44. package/dist/tools/prepare_release.js.map +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,29 @@
1
+ # Changelog fragments
2
+
3
+ When `OKFFS_UPDATE_DOCS=true`, okffs does **not** edit the shared `CHANGELOG.md`
4
+ on each issue branch — that makes parallel branches deterministically conflict on
5
+ the changelog (add/add when the file is new, same-hunk when it already exists).
6
+
7
+ Instead, `create_pull_request` drops a uniquely-named fragment here:
8
+
9
+ ```
10
+ .changes/unreleased/<issue-number>-<slug>.md
11
+ ```
12
+
13
+ Each branch only ever creates its own file, so fragments **never conflict**. A
14
+ fragment carries its change type in a machine-readable header comment plus the
15
+ changelog bullet:
16
+
17
+ ```md
18
+ <!-- okffs:type=Fixed -->
19
+ - Some concise change ([#123](https://github.com/neturely/okffs/issues/123))
20
+ ```
21
+
22
+ `type` is one of `Added`, `Changed`, `Fixed`, `Removed`, `Security`.
23
+
24
+ ## Assembly
25
+
26
+ `prepare_release` folds every fragment in `.changes/unreleased/` into the
27
+ `## [Unreleased]` section of `CHANGELOG.md` (grouped under the right `###`
28
+ heading), rolls that into the new `## [X.Y.Z]` version section, and deletes the
29
+ consumed fragments — all in the release commit. You never assemble by hand.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,32 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.5.0] - 2026-07-04
9
+ ### Changed
10
+ - 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).
11
+ - `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).
12
+ ### Fixed
13
+ - 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).
14
+ - 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).
15
+ - 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).
16
+ ### Added
17
+ - `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).
18
+
19
+ ## [0.4.0] - 2026-07-03
20
+ ### Added
21
+ - 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`.
22
+ - Effort support, mirroring Priority: `create_issue` accepts an `effort` param (plus `OKFFS_DEFAULT_EFFORT`), and `list_issues` shows each issue's `effort:`. Works with both a project-native Effort field and a GitHub org-level Issue Field (via `OKFFS_CLASSIC_PAT`). The org Issue Field layer was generalized (`getOrgIssueField(name)`, name-keyed project metadata) so Priority, Effort, and any future single-select field share one code path.
23
+ - `create_issue` now asks Claude to **infer** an issue's `priority` and `effort` from the task itself (using the common scale), the same way it already infers labels — falling back to `OKFFS_DEFAULT_PRIORITY`/`OKFFS_DEFAULT_EFFORT` only when it can't judge. Toggle per field with `OKFFS_INFER_PRIORITY` / `OKFFS_INFER_EFFORT` (default on). Injecting each board's real option names for accurate inference on non-standard boards is tracked in [#133](https://github.com/neturely/okffs/issues/133).
24
+ - `OKFFS_CLASSIC_PAT` env flag (default `false`) — gates the org-level Issue Field Priority path (#91) behind an explicit opt-in that declares `GITHUB_TOKEN` is a classic PAT with `admin:org`. When off, okffs skips the org `organization.issueFields` call entirely and tells you to set Priority in the UI, avoiding a doomed API call and keeping the broad-scoped-token requirement opt-in for this public package ([#91](https://github.com/neturely/okffs/issues/91)).
25
+ - `create_issue`'s `priority` now supports GitHub **org-level Issue Fields** (e.g. Priority), not just project-native single-select fields. When the board's Priority field reports no options (the org Issue Field signature), okffs resolves the option via `organization.issueFields` and sets it on the issue with `setIssueFieldValue`. Requires a classic PAT with `admin:org` (fine-grained PATs get FORBIDDEN for this preview API); degrades gracefully with an actionable `[okffs]` message otherwise ([#91](https://github.com/neturely/okffs/issues/91)).
26
+ - `OKFFS_PROJECT_INITIAL_STATUS` — pins a freshly auto-added issue to a chosen board column (e.g. `Backlog`). `create_issue` sets it after the draft PR is created so it wins over GitHub's "PR linked to issue" workflow, which otherwise flips scaffolded issues straight to "In Progress" ([#103](https://github.com/neturely/okffs/issues/103)).
27
+
28
+ ### Changed
29
+ - `OKFFS_UPDATE_DOCS` now writes a per-issue changelog **fragment** at `.changes/unreleased/{issue-number}-{slug}.md` instead of editing the shared `CHANGELOG.md` on each branch, so parallel issue branches no longer conflict on the changelog. `prepare_release` assembles the fragments into `CHANGELOG.md` and deletes them in the release commit (changesets/towncrier pattern) ([#105](https://github.com/neturely/okffs/issues/105)).
30
+
31
+ ### Fixed
32
+ - Projects v2 auto-add no longer fails silently: `create_issue` now surfaces an auto-add failure in its response (not just the server log), and the Projects permission error now recognises the `INSUFFICIENT_SCOPES` case and points at the gh-CLI fallback token's missing `project` scope ([#101](https://github.com/neturely/okffs/issues/101)).
33
+
8
34
  ## [0.3.0] - 2026-07-01
9
35
  ### Changed
10
36
  - Harden publish workflow: prerelease-safe npm tag + verify-only job ([#95](https://github.com/neturely/okffs/issues/95))
@@ -69,7 +95,9 @@ See [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
69
95
  - `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)).
70
96
  - 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.
71
97
 
72
- [Unreleased]: https://github.com/neturely/okffs/compare/v0.3.0...HEAD
98
+ [Unreleased]: https://github.com/neturely/okffs/compare/v0.5.0...HEAD
99
+ [0.5.0]: https://github.com/neturely/okffs/compare/v0.4.0...v0.5.0
100
+ [0.4.0]: https://github.com/neturely/okffs/compare/v0.3.0...v0.4.0
73
101
  [0.3.0]: https://github.com/neturely/okffs/compare/v0.2.2...v0.3.0
74
102
  [0.2.2]: https://github.com/neturely/okffs/compare/v0.2.1...v0.2.2
75
103
  [0.2.1]: https://github.com/neturely/okffs/compare/v0.2.0...v0.2.1
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,252 +28,136 @@ Add okffs to any project by creating a `.mcp.json` in the project root:
40
28
  }
41
29
  ```
42
30
 
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"*
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).
77
32
 
78
- Claude infers appropriate labels (`bug`, `enhancement`, etc.) from the issue title and description, and merges them with your `OKFFS_DEFAULT_LABELS`.
33
+ Now just ask Claude:
79
34
 
80
- ## Getting started
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."*
81
42
 
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
- OKFFS_PROJECT_ENABLED=false # set to true to enable the GitHub Projects v2 integration
131
- OKFFS_PROJECT_ID= # the Project's GraphQL node ID (e.g. PVT_kwHO...); required when enabled
132
- OKFFS_PROJECT_AUTO_ADD=false # fallback: create_issue adds new issues to the board (skip if your board auto-adds natively)
133
- ```
134
-
135
- 4. Build and point your `.mcp.json` at the local build:
136
-
137
- ```bash
138
- npm run build
139
- ```
140
-
141
- ```json
142
- {
143
- "mcpServers": {
144
- "okffs": {
145
- "command": "node",
146
- "args": ["dist/index.js"]
147
- }
148
- }
149
- }
150
- ```
43
+ Claude infers labels (`bug`, `enhancement`, …) from the title and description and merges them with any you've set as defaults.
151
44
 
152
45
  ## Tools
153
46
 
154
- | Tool | Description |
47
+ | Tool | What it does |
155
48
  |------|-------------|
156
- | `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. |
157
- | `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. |
158
- | `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`. |
159
- | `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. |
160
- | `get_issue` | Fetches full details of an issue title, body, labels, assignees, branch, and status. |
161
- | `comment_issue` | Posts a comment to an issue. Useful for logging work done on a branch. |
162
- | `link_issues` | Links two issues with a relationship — `blocked_by`, `blocking`, or `parent`. Stored in the issue body under a `## Relationships` section. |
163
- | `close_issue` | Closes a GitHub issue by number. Returns a tip to run `/clear` in Claude Code before starting the next issue. |
164
- | `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. |
165
- | `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. |
166
- | `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. |
167
- | `reply_to_review_comment` | Replies to an inline PR review comment thread by id. |
168
- | `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. |
169
- | `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. |
170
- | `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`. |
171
- | `delete_issue` | Closes an issue **and** deletes its matching branch. Destructive — requires `confirmed: true`. |
172
- | `delete_branch` | Deletes a branch **and** closes its matching issue. Destructive — requires `confirmed: true`. |
173
-
174
- 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.
175
-
176
- ## Responding to PR reviews
177
-
178
- okffs ships a workflow for handling pull request review feedback out of the box. Just ask Claude in natural language, e.g.:
179
-
180
- - *"Address the review comments on PR #42"*
181
- - *"Can you fix any of the commented issues on the PR?"*
182
-
183
- 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.
184
-
185
- 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.
186
-
187
- 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.
188
74
 
189
75
  ## Keeping CLAUDE.md in sync
190
76
 
191
- 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.
192
-
193
- 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.
194
78
 
195
79
  ## Automatic doc updates
196
80
 
197
- 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.
198
-
199
- Entries are **title-based one-liners** — concise and complete, so nothing needs manual cleanup.
81
+ With `OKFFS_UPDATE_DOCS=true`, `create_pull_request` writes doc updates onto the branch so they land in the PR diff:
200
82
 
201
- Files updated when relevant:
202
- - `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.
203
- - `SECURITY.md` — updated when security, vulnerability, or CVE keywords are detected (only if the file exists).
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).
204
85
 
205
- `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.
206
-
207
- Use `OKFFS_EXCLUDE_DOCS` to exclude specific files per repo (valid options: `CHANGELOG.md`, `SECURITY.md`):
208
- ```env
209
- OKFFS_EXCLUDE_DOCS=SECURITY.md
210
- ```
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`).
211
87
 
212
88
  ## GitHub Projects v2
213
89
 
214
- okffs can keep a GitHub **Projects v2** board in step with your issue workflow. It's **opt-in** and has zero overhead when off.
215
-
216
- 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:
217
91
 
218
- ```
92
+ ```env
219
93
  OKFFS_PROJECT_ENABLED=true
220
- OKFFS_PROJECT_ID=PVT_kwHO... # the board's GraphQL node ID
221
- OKFFS_PROJECT_AUTO_ADD=false # see "auto-add vs native automation" below
94
+ OKFFS_PROJECT_ID=PVT_kwHO... # the board's GraphQL node ID
222
95
  ```
223
96
 
224
- Once enabled:
225
-
226
- - **`list_issues`** shows each issue's current board column (e.g. `project: In Progress`).
227
- - **`update_project_status`** moves an issue between `Backlog`, `Ready`, `In Progress`, and `Review`.
228
-
229
- ### How Claude drives status transitions
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.
230
98
 
231
- 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.
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.
232
100
 
233
- **`Done` is intentionally not settable** by okffs — it'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.
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.
234
102
 
235
- ### Auto-add vs native automation
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.
236
104
 
237
- `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`).
105
+ ## Configuration
238
106
 
239
- ### Token permission
107
+ okffs resolves a **token** and a **target repository** with fallbacks, so most users need little config.
240
108
 
241
- Projects v2 has no REST API, so okffs uses GraphQL, which needs a Projects-capable token:
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.
242
112
 
243
- - **Fine-grained PAT** *Organization permissions* → **Projects: Read and write**
244
- - **Classic PAT** the **`project`** scope
245
-
246
- 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.
247
-
248
- ## 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.
249
116
 
250
- **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`:
251
118
 
252
- ```
253
- 42-add-hero-section-to-homepage
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
254
124
  ```
255
125
 
256
- **Pull requests:**
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_IDENTIFIER` | — | Prefix for branch names: `{number}-{identifier}-{slug}`. |
139
+ | `OKFFS_AUTO_PR` | `false` | Open a draft PR when a new issue branch is created. |
140
+ | `OKFFS_RESOLVE_THREADS` | `false` | Auto-resolve PR review threads after they're addressed. |
141
+ | `OKFFS_UPDATE_GUIDANCE` | `false` | Nudge Claude to keep `CLAUDE.md` in sync at PR time. |
142
+ | `OKFFS_UPDATE_DOCS` | `false` | Auto-write CHANGELOG/SECURITY updates on `create_pull_request`. |
143
+ | `OKFFS_EXCLUDE_DOCS` | — | Comma-separated docs to skip (`CHANGELOG.md`, `SECURITY.md`). |
144
+ | `OKFFS_PROJECT_ENABLED` | `false` | Enable the GitHub Projects v2 integration. |
145
+ | `OKFFS_PROJECT_ID` | — | The board's GraphQL node ID (required when enabled). |
146
+ | `OKFFS_PROJECT_AUTO_ADD` | `false` | Add new issues to the board (fallback when the board has no native auto-add). |
147
+ | `OKFFS_PROJECT_INITIAL_STATUS` | — | Column a freshly added issue lands in (e.g. `Backlog`). |
148
+ | `OKFFS_CLASSIC_PAT` | `false` | Set `true` only with a classic `admin:org` PAT — enables org-level Issue Field Priority/Effort (broad token; security tradeoff). |
257
149
 
258
- - Title: `Close #42 - Add hero section to homepage`
259
- - 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.
260
-
261
- **Operating principles:**
150
+ ## Conventions
262
151
 
263
- - Destructive tools require `confirmed: true` call once for a warning, re-call to proceed. Bulk-creating tools confirm before acting.
152
+ - **Branches:** `{issue-number}-{kebab-title-slug}` (title truncated to ~5 words), e.g. `42-add-hero-section-to-homepage`.
153
+ - **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.
154
+ - Destructive tools require `confirmed: true`; bulk-creating tools confirm first.
264
155
  - GitHub is always the source of truth for issue state — never local.
265
- - Keep the tool surface minimal: do one thing well per tool.
266
-
267
- ## Publishing to npm
268
-
269
- Requires an npm account with maintainer access to the `@neturely/okffs` package (publishes publicly via `publishConfig.access`).
270
-
271
- 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`).
272
- 2. **Tag and push** the version:
273
-
274
- ```bash
275
- git tag v0.2.0
276
- git push origin v0.2.0
277
- ```
278
-
279
- 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.
280
-
281
- > `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.
282
156
 
283
- ## Codebase search
157
+ ## Contributing
284
158
 
285
- 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.
159
+ 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.
286
160
 
287
- To search manually (requires `uv`):
161
+ ## License
288
162
 
289
- ```bash
290
- uvx --from "semble[mcp]" semble search "your query" .
291
- ```
163
+ [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"}