@neturely/okffs 0.7.0 → 0.9.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 (66) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +15 -2
  3. package/dist/cli/banner.d.ts +17 -0
  4. package/dist/cli/banner.d.ts.map +1 -0
  5. package/dist/cli/banner.js +65 -0
  6. package/dist/cli/banner.js.map +1 -0
  7. package/dist/cli/env.d.ts +30 -0
  8. package/dist/cli/env.d.ts.map +1 -0
  9. package/dist/cli/env.js +171 -0
  10. package/dist/cli/env.js.map +1 -0
  11. package/dist/cli/index.d.ts +12 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +77 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/manifest.d.ts +48 -0
  16. package/dist/cli/manifest.d.ts.map +1 -0
  17. package/dist/cli/manifest.js +303 -0
  18. package/dist/cli/manifest.js.map +1 -0
  19. package/dist/cli/probe.d.ts +32 -0
  20. package/dist/cli/probe.d.ts.map +1 -0
  21. package/dist/cli/probe.js +101 -0
  22. package/dist/cli/probe.js.map +1 -0
  23. package/dist/cli/sanity.d.ts +16 -0
  24. package/dist/cli/sanity.d.ts.map +1 -0
  25. package/dist/cli/sanity.js +99 -0
  26. package/dist/cli/sanity.js.map +1 -0
  27. package/dist/cli/setup.d.ts +2 -0
  28. package/dist/cli/setup.d.ts.map +1 -0
  29. package/dist/cli/setup.js +254 -0
  30. package/dist/cli/setup.js.map +1 -0
  31. package/dist/github.d.ts.map +1 -1
  32. package/dist/github.js +4 -2
  33. package/dist/github.js.map +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +19 -105
  36. package/dist/index.js.map +1 -1
  37. package/dist/prompts/setup.d.ts +18 -0
  38. package/dist/prompts/setup.d.ts.map +1 -0
  39. package/dist/prompts/setup.js +77 -0
  40. package/dist/prompts/setup.js.map +1 -0
  41. package/dist/server.d.ts +2 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +166 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/tools/commit_and_update.d.ts +19 -0
  46. package/dist/tools/commit_and_update.d.ts.map +1 -1
  47. package/dist/tools/commit_and_update.js +59 -6
  48. package/dist/tools/commit_and_update.js.map +1 -1
  49. package/dist/tools/configure.d.ts +27 -0
  50. package/dist/tools/configure.d.ts.map +1 -0
  51. package/dist/tools/configure.js +91 -0
  52. package/dist/tools/configure.js.map +1 -0
  53. package/dist/tools/fix_into_base.d.ts +23 -0
  54. package/dist/tools/fix_into_base.d.ts.map +1 -0
  55. package/dist/tools/fix_into_base.js +110 -0
  56. package/dist/tools/fix_into_base.js.map +1 -0
  57. package/dist/tools/merge_pull_request.d.ts +6 -3
  58. package/dist/tools/merge_pull_request.d.ts.map +1 -1
  59. package/dist/tools/merge_pull_request.js +52 -18
  60. package/dist/tools/merge_pull_request.js.map +1 -1
  61. package/dist/tools/reply_to_review_comment.d.ts +4 -1
  62. package/dist/tools/reply_to_review_comment.d.ts.map +1 -1
  63. package/dist/tools/reply_to_review_comment.js +39 -10
  64. package/dist/tools/reply_to_review_comment.js.map +1 -1
  65. package/dist/tools/update_project_status.d.ts +2 -2
  66. package/package.json +6 -2
@@ -0,0 +1,303 @@
1
+ // The env-var manifest — the single source of truth the setup wizard, sync mode,
2
+ // and the .env writer all read from. It mirrors .env.example (grouped sections,
3
+ // descriptions, defaults) in a structured form so the three consumers never
4
+ // drift from one another. Keep it in sync with .env.example and src/config.ts
5
+ // when adding a variable (the sanity of that trio is the whole point).
6
+ const PRIORITY = ["Urgent", "High", "Medium", "Low"];
7
+ const EFFORT = ["High", "Medium", "Low"];
8
+ const MERGE_METHODS = ["squash", "merge", "rebase"];
9
+ export const SECTIONS = [
10
+ {
11
+ id: "auth",
12
+ title: "1. GitHub connection",
13
+ blurb: "Auth & repository. Leave GITHUB_TOKEN blank to fall back to the GitHub CLI (`gh auth token`); owner/repo auto-detect from the `origin` remote.",
14
+ gated: false,
15
+ vars: [
16
+ {
17
+ key: "GITHUB_TOKEN",
18
+ kind: "secret",
19
+ description: "GitHub personal access token. Create a fine-grained one at " +
20
+ "https://github.com/settings/personal-access-tokens/new with these repo permissions: " +
21
+ "Issues, Contents, Pull requests (Read & write), Metadata (Read), Administration (Read & write). " +
22
+ "Leave blank to fall back to the GitHub CLI (`gh auth token`).",
23
+ default: "",
24
+ },
25
+ {
26
+ key: "GITHUB_OWNER",
27
+ kind: "text",
28
+ description: "Repository owner (org or user). Blank = auto-detect from the git remote.",
29
+ default: "",
30
+ placeholder: "neturely",
31
+ },
32
+ {
33
+ key: "GITHUB_REPO",
34
+ kind: "text",
35
+ description: "Repository name. Blank = auto-detect from the git remote.",
36
+ default: "",
37
+ placeholder: "okffs",
38
+ },
39
+ ],
40
+ },
41
+ {
42
+ id: "branching",
43
+ title: "2. Branching",
44
+ gated: true,
45
+ gatePrompt: "Configure branching (base/protected branch, identifier prefix)?",
46
+ vars: [
47
+ {
48
+ key: "OKFFS_BASE_BRANCH",
49
+ kind: "text",
50
+ description: "Branch new issue branches are created from. Blank = the repo's default branch.",
51
+ default: "",
52
+ placeholder: "develop",
53
+ },
54
+ {
55
+ key: "OKFFS_PROTECTED_BRANCH",
56
+ kind: "text",
57
+ description: "A branch okffs must never autonomously merge/tag/publish into (e.g. main). Governs merging, not PR creation.",
58
+ default: "",
59
+ placeholder: "main",
60
+ },
61
+ {
62
+ key: "OKFFS_IDENTIFIER",
63
+ kind: "text",
64
+ description: "Project-scoped prefix inserted into branch names: {issue}-{identifier}-{slug}.",
65
+ default: "",
66
+ placeholder: "okffs",
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ id: "defaults",
72
+ title: "3. Issue defaults & inference",
73
+ gated: true,
74
+ gatePrompt: "Configure issue defaults & inference (labels, assignees, priority/effort/type)?",
75
+ vars: [
76
+ {
77
+ key: "OKFFS_DEFAULT_LABELS",
78
+ kind: "text",
79
+ description: "Comma-separated labels added to EVERY new issue, on top of any Claude picks from the task — e.g. okffs, backend, needs-triage.",
80
+ default: "",
81
+ placeholder: "okffs, backend",
82
+ },
83
+ {
84
+ key: "OKFFS_DEFAULT_ASSIGNEES",
85
+ kind: "text",
86
+ description: "Comma-separated usernames assigned to every new issue.",
87
+ default: "",
88
+ },
89
+ {
90
+ key: "OKFFS_DEFAULT_PRIORITY",
91
+ kind: "select",
92
+ description: "Board Priority fallback when none is inferred/given. Needs a Priority field on the board.",
93
+ default: "",
94
+ options: ["", ...PRIORITY],
95
+ },
96
+ {
97
+ key: "OKFFS_DEFAULT_EFFORT",
98
+ kind: "select",
99
+ description: "Board Effort fallback when none is inferred/given. Needs an Effort field on the board.",
100
+ default: "",
101
+ options: ["", ...EFFORT],
102
+ },
103
+ {
104
+ key: "OKFFS_DEFAULT_TYPE",
105
+ kind: "text",
106
+ description: "Native GitHub Issue Type fallback (org-level, e.g. Task/Bug/Feature). Blank = none.",
107
+ default: "",
108
+ placeholder: "Task",
109
+ },
110
+ {
111
+ key: "OKFFS_INFER_PRIORITY",
112
+ kind: "boolean",
113
+ description: "Have Claude read each new issue's title/description and decide its priority (Urgent/High/Medium/Low) for you, instead of you setting one. Falls back to the default above when it can't judge.",
114
+ default: "true",
115
+ },
116
+ {
117
+ key: "OKFFS_INFER_EFFORT",
118
+ kind: "boolean",
119
+ description: "Have Claude read each new issue and decide its effort (High/Medium/Low) for you, instead of you setting one. Falls back to the default above.",
120
+ default: "true",
121
+ },
122
+ {
123
+ key: "OKFFS_INFER_TYPE",
124
+ kind: "boolean",
125
+ description: "Have Claude read each new issue and decide its GitHub Issue Type (e.g. Bug/Feature/Task) for you, instead of you setting one. Falls back to the default above.",
126
+ default: "true",
127
+ },
128
+ ],
129
+ },
130
+ {
131
+ id: "prmerge",
132
+ title: "4. Pull requests & merging",
133
+ gated: true,
134
+ gatePrompt: "Configure PR & merge behaviour (auto-PR, merge methods, auto-merge)?",
135
+ vars: [
136
+ {
137
+ key: "OKFFS_AUTO_PR",
138
+ kind: "boolean",
139
+ description: "Open a draft PR at branch-creation time (via create_issue).",
140
+ default: "false",
141
+ },
142
+ {
143
+ key: "OKFFS_BASE_MERGE_METHOD",
144
+ kind: "select",
145
+ description: "PR merge method for the base tier (e.g. develop).",
146
+ default: "squash",
147
+ options: MERGE_METHODS,
148
+ },
149
+ {
150
+ key: "OKFFS_PROTECTED_MERGE_METHOD",
151
+ kind: "select",
152
+ description: "PR merge method for the protected tier (e.g. main). Config only — okffs never merges it autonomously.",
153
+ default: "merge",
154
+ options: MERGE_METHODS,
155
+ },
156
+ {
157
+ key: "OKFFS_AUTO_MERGE_BASE",
158
+ kind: "boolean",
159
+ description: "Let merge_pull_request autonomously merge a green, threads-resolved PR into the BASE branch. Heavily gated; never touches the protected branch.",
160
+ default: "false",
161
+ },
162
+ ],
163
+ },
164
+ {
165
+ id: "docs",
166
+ title: "5. Docs & changelog",
167
+ gated: true,
168
+ gatePrompt: "Configure auto doc updates (CHANGELOG fragments, SECURITY.md)?",
169
+ vars: [
170
+ {
171
+ key: "OKFFS_UPDATE_DOCS",
172
+ kind: "boolean",
173
+ description: "Auto-write doc updates (CHANGELOG fragment + SECURITY.md) onto the branch at create_pull_request time.",
174
+ default: "false",
175
+ },
176
+ {
177
+ key: "OKFFS_EXCLUDE_DOCS",
178
+ kind: "text",
179
+ description: "Comma-separated filenames to exclude from doc updates (valid: CHANGELOG.md, SECURITY.md).",
180
+ default: "",
181
+ placeholder: "SECURITY.md",
182
+ },
183
+ ],
184
+ },
185
+ {
186
+ id: "review",
187
+ title: "6. PR review",
188
+ gated: true,
189
+ gatePrompt: "Configure how okffs handles PR review feedback — e.g. from GitHub Copilot code review or human reviewers?",
190
+ vars: [
191
+ {
192
+ key: "OKFFS_RESOLVE_THREADS",
193
+ kind: "boolean",
194
+ description: "After Claude fixes a PR's review comments, automatically mark those review threads resolved — e.g. threads left by GitHub Copilot code review or a human reviewer. Off = you resolve them yourself.",
195
+ default: "false",
196
+ },
197
+ {
198
+ key: "OKFFS_UPDATE_GUIDANCE",
199
+ kind: "boolean",
200
+ description: "Nudge create_pull_request to keep CLAUDE.md's okffs-owned guidance in sync with functionality changes.",
201
+ default: "false",
202
+ },
203
+ ],
204
+ },
205
+ {
206
+ id: "projects",
207
+ title: "7. GitHub Projects v2 (board)",
208
+ gated: true,
209
+ gateKey: "OKFFS_PROJECT_ENABLED",
210
+ gatePrompt: "Enable the GitHub Projects v2 integration?",
211
+ vars: [
212
+ {
213
+ key: "OKFFS_PROJECT_ID",
214
+ kind: "text",
215
+ description: "The Project's GraphQL node ID (e.g. PVT_kwHO...). Required when Projects is enabled.",
216
+ default: "",
217
+ placeholder: "PVT_kwHO...",
218
+ },
219
+ {
220
+ key: "OKFFS_PROJECT_AUTO_ADD",
221
+ kind: "boolean",
222
+ description: "Fallback for boards without native auto-add: create_issue adds each new issue to the board.",
223
+ default: "false",
224
+ },
225
+ {
226
+ key: "OKFFS_PROJECT_INITIAL_STATUS",
227
+ kind: "text",
228
+ description: "Board Status column a freshly auto-added issue should land in (e.g. Backlog).",
229
+ default: "",
230
+ placeholder: "Backlog",
231
+ },
232
+ {
233
+ key: "OKFFS_CLASSIC_PAT",
234
+ kind: "boolean",
235
+ description: "Set true ONLY if GITHUB_TOKEN is a classic PAT with admin:org — unlocks org-level Issue Field Priority/Effort. SECURITY: broad token.",
236
+ default: "false",
237
+ },
238
+ ],
239
+ },
240
+ {
241
+ id: "promotion",
242
+ title: "8. Branch promotion & releases",
243
+ blurb: "promote_branch opens the issue-less base→protected promotion PR (e.g. develop→main).",
244
+ gated: true,
245
+ gatePrompt: "Configure the promotion gate (reviewers on the develop→main PR)?",
246
+ onlyIf: (v) => Boolean(v.OKFFS_PROTECTED_BRANCH),
247
+ vars: [
248
+ {
249
+ key: "OKFFS_PROMOTION_STATUS",
250
+ kind: "text",
251
+ description: "Board Status column the promotion PR card should land in (e.g. Review). Needs Projects enabled.",
252
+ default: "",
253
+ placeholder: "Review",
254
+ },
255
+ {
256
+ key: "OKFFS_PROMOTION_REVIEWERS",
257
+ kind: "text",
258
+ description: "Comma-separated reviewers requested on the promotion PR (e.g. copilot-pull-request-reviewer[bot]).",
259
+ default: "",
260
+ placeholder: "copilot-pull-request-reviewer[bot]",
261
+ },
262
+ {
263
+ key: "OKFFS_PROMOTION_AUTO_REVIEW",
264
+ kind: "boolean",
265
+ description: "Auto-request the reviewers above on the gate PR. COST: a billable reviewer (Copilot) is charged per new PR.",
266
+ default: "false",
267
+ },
268
+ ],
269
+ },
270
+ {
271
+ id: "misc",
272
+ title: "9. Misc",
273
+ gated: true,
274
+ gatePrompt: "Configure misc options (metadata tip)?",
275
+ vars: [
276
+ {
277
+ key: "OKFFS_PROMPT_METADATA",
278
+ kind: "boolean",
279
+ description: "After creating an issue, print a one-line reminder that you can also set assignees, labels, priority, etc. Turn off to silence that tip.",
280
+ default: "true",
281
+ },
282
+ ],
283
+ },
284
+ ];
285
+ /** Every var key the manifest knows about, in section order. */
286
+ export function allKeys() {
287
+ return SECTIONS.flatMap((s) => s.vars.map((v) => v.key)).concat(
288
+ // Gate keys that are real env vars (e.g. OKFFS_PROJECT_ENABLED) but not listed
289
+ // among their section's vars.
290
+ SECTIONS.filter((s) => s.gateKey).map((s) => s.gateKey));
291
+ }
292
+ /** Look up a var spec by key across all sections. */
293
+ export function findVar(key) {
294
+ for (const s of SECTIONS) {
295
+ const found = s.vars.find((v) => v.key === key);
296
+ if (found)
297
+ return found;
298
+ }
299
+ return undefined;
300
+ }
301
+ /** Keys that make up the Quick-setup subset (auth & repo + base branch). */
302
+ export const QUICK_KEYS = ["GITHUB_TOKEN", "GITHUB_OWNER", "GITHUB_REPO", "OKFFS_BASE_BRANCH"];
303
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/cli/manifest.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,uEAAuE;AA6CvE,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AACrD,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AACzC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAEpD,MAAM,CAAC,MAAM,QAAQ,GAAc;IACjC;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,sBAAsB;QAC7B,KAAK,EAAE,gJAAgJ;QACvJ,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,cAAc;gBACnB,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6DAA6D;oBAC7D,sFAAsF;oBACtF,kGAAkG;oBAClG,+DAA+D;gBACjE,OAAO,EAAE,EAAE;aACZ;YACD;gBACE,GAAG,EAAE,cAAc;gBACnB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,0EAA0E;gBACvF,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,UAAU;aACxB;YACD;gBACE,GAAG,EAAE,aAAa;gBAClB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,2DAA2D;gBACxE,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,OAAO;aACrB;SACF;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,iEAAiE;QAC7E,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,gFAAgF;gBAC7F,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,SAAS;aACvB;YACD;gBACE,GAAG,EAAE,wBAAwB;gBAC7B,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,8GAA8G;gBAC3H,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,MAAM;aACpB;YACD;gBACE,GAAG,EAAE,kBAAkB;gBACvB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,gFAAgF;gBAC7F,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,OAAO;aACrB;SACF;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,+BAA+B;QACtC,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,iFAAiF;QAC7F,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,gIAAgI;gBAC7I,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,gBAAgB;aAC9B;YACD;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,wDAAwD;gBACrE,OAAO,EAAE,EAAE;aACZ;YACD;gBACE,GAAG,EAAE,wBAAwB;gBAC7B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2FAA2F;gBACxG,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC;aAC3B;YACD;gBACE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wFAAwF;gBACrG,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC;aACzB;YACD;gBACE,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,qFAAqF;gBAClG,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,MAAM;aACpB;YACD;gBACE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,gMAAgM;gBAC7M,OAAO,EAAE,MAAM;aAChB;YACD;gBACE,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,+IAA+I;gBAC5J,OAAO,EAAE,MAAM;aAChB;YACD;gBACE,GAAG,EAAE,kBAAkB;gBACvB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,gKAAgK;gBAC7K,OAAO,EAAE,MAAM;aAChB;SACF;KACF;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,4BAA4B;QACnC,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,sEAAsE;QAClF,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,eAAe;gBACpB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,6DAA6D;gBAC1E,OAAO,EAAE,OAAO;aACjB;YACD;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,mDAAmD;gBAChE,OAAO,EAAE,QAAQ;gBACjB,OAAO,EAAE,aAAa;aACvB;YACD;gBACE,GAAG,EAAE,8BAA8B;gBACnC,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uGAAuG;gBACpH,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,aAAa;aACvB;YACD;gBACE,GAAG,EAAE,uBAAuB;gBAC5B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,iJAAiJ;gBAC9J,OAAO,EAAE,OAAO;aACjB;SACF;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,qBAAqB;QAC5B,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,gEAAgE;QAC5E,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,wGAAwG;gBACrH,OAAO,EAAE,OAAO;aACjB;YACD;gBACE,GAAG,EAAE,oBAAoB;gBACzB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,2FAA2F;gBACxG,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,aAAa;aAC3B;SACF;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,2GAA2G;QACvH,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,uBAAuB;gBAC5B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,qMAAqM;gBAClN,OAAO,EAAE,OAAO;aACjB;YACD;gBACE,GAAG,EAAE,uBAAuB;gBAC5B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,wGAAwG;gBACrH,OAAO,EAAE,OAAO;aACjB;SACF;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,+BAA+B;QACtC,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,uBAAuB;QAChC,UAAU,EAAE,4CAA4C;QACxD,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,kBAAkB;gBACvB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,sFAAsF;gBACnG,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,aAAa;aAC3B;YACD;gBACE,GAAG,EAAE,wBAAwB;gBAC7B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,6FAA6F;gBAC1G,OAAO,EAAE,OAAO;aACjB;YACD;gBACE,GAAG,EAAE,8BAA8B;gBACnC,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,+EAA+E;gBAC5F,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,SAAS;aACvB;YACD;gBACE,GAAG,EAAE,mBAAmB;gBACxB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,uIAAuI;gBACpJ,OAAO,EAAE,OAAO;aACjB;SACF;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,gCAAgC;QACvC,KAAK,EAAE,sFAAsF;QAC7F,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,kEAAkE;QAC9E,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;QAChD,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,wBAAwB;gBAC7B,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,iGAAiG;gBAC9G,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,QAAQ;aACtB;YACD;gBACE,GAAG,EAAE,2BAA2B;gBAChC,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,oGAAoG;gBACjH,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,oCAAoC;aAClD;YACD;gBACE,GAAG,EAAE,6BAA6B;gBAClC,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,6GAA6G;gBAC1H,OAAO,EAAE,OAAO;aACjB;SACF;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,wCAAwC;QACpD,IAAI,EAAE;YACJ;gBACE,GAAG,EAAE,uBAAuB;gBAC5B,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,0IAA0I;gBACvJ,OAAO,EAAE,MAAM;aAChB;SACF;KACF;CACF,CAAC;AAEF,gEAAgE;AAChE,MAAM,UAAU,OAAO;IACrB,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;IAC7D,+EAA+E;IAC/E,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAQ,CAAC,CACzD,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAChD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Resolve a token from an explicit value, else the GitHub CLI. Mirrors github.ts. */
2
+ export declare function resolveToken(explicit?: string): {
3
+ token: string | null;
4
+ source: "env" | "gh" | "none";
5
+ };
6
+ /** Resolve owner/repo from explicit values, else the origin remote. Mirrors github.ts. */
7
+ export declare function resolveOwnerRepo(explicitOwner?: string, explicitRepo?: string): {
8
+ owner?: string;
9
+ repo?: string;
10
+ };
11
+ export interface ApiResponse<T> {
12
+ ok: boolean;
13
+ status: number;
14
+ data: T | null;
15
+ scopes: string | null;
16
+ error?: string;
17
+ }
18
+ export declare function getUser(token: string): Promise<ApiResponse<{
19
+ login: string;
20
+ }>>;
21
+ export declare function getRepo(token: string, owner: string, repo: string): Promise<ApiResponse<{
22
+ default_branch: string;
23
+ full_name: string;
24
+ }>>;
25
+ export declare function getBranch(token: string, owner: string, repo: string, branch: string): Promise<ApiResponse<{
26
+ name: string;
27
+ }>>;
28
+ /** Resolve a Projects v2 node ID via GraphQL — confirms the id is real and readable. */
29
+ export declare function getProjectV2(token: string, projectId: string): Promise<ApiResponse<{
30
+ title: string;
31
+ }>>;
32
+ //# sourceMappingURL=probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/cli/probe.ts"],"names":[],"mappings":"AAwBA,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,CAAA;CAAE,CAIvG;AAOD,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAYjH;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwBD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAE9E;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAEvI;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAE5H;AAED,wFAAwF;AACxF,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAmB5G"}
@@ -0,0 +1,101 @@
1
+ // Standalone GitHub access for the setup wizard's sanity test.
2
+ //
3
+ // IMPORTANT: this does NOT import ../github.js on purpose. That module resolves
4
+ // the token and owner/repo at import time and THROWS if either is missing —
5
+ // which is exactly the state the wizard runs in. So we re-implement the small
6
+ // slice of resolution + REST/GraphQL we need here, driven by the values the
7
+ // wizard just collected rather than by process.env at import time.
8
+ import { execFileSync } from "node:child_process";
9
+ const BASE = "https://api.github.com";
10
+ function tryExec(cmd, args) {
11
+ try {
12
+ const out = execFileSync(cmd, args, {
13
+ encoding: "utf8",
14
+ stdio: ["ignore", "pipe", "ignore"],
15
+ }).trim();
16
+ return out || null;
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ /** Resolve a token from an explicit value, else the GitHub CLI. Mirrors github.ts. */
23
+ export function resolveToken(explicit) {
24
+ if (explicit && explicit.trim())
25
+ return { token: explicit.trim(), source: "env" };
26
+ const gh = tryExec("gh", ["auth", "token"]);
27
+ return gh ? { token: gh, source: "gh" } : { token: null, source: "none" };
28
+ }
29
+ function parseOwnerRepo(remoteUrl) {
30
+ const m = remoteUrl.match(/github\.com[:/]([^/]+)\/(.+?)(?:\.git)?$/);
31
+ return m ? { owner: m[1], repo: m[2] } : null;
32
+ }
33
+ /** Resolve owner/repo from explicit values, else the origin remote. Mirrors github.ts. */
34
+ export function resolveOwnerRepo(explicitOwner, explicitRepo) {
35
+ let owner = explicitOwner || undefined;
36
+ let repo = explicitRepo || undefined;
37
+ if (!owner || !repo) {
38
+ const remote = tryExec("git", ["remote", "get-url", "origin"]);
39
+ const parsed = remote ? parseOwnerRepo(remote) : null;
40
+ if (parsed) {
41
+ owner = owner || parsed.owner;
42
+ repo = repo || parsed.repo;
43
+ }
44
+ }
45
+ return { owner, repo };
46
+ }
47
+ async function rest(token, path) {
48
+ try {
49
+ const res = await fetch(`${BASE}${path}`, {
50
+ headers: {
51
+ Authorization: `Bearer ${token}`,
52
+ Accept: "application/vnd.github+json",
53
+ "X-GitHub-Api-Version": "2022-11-28",
54
+ },
55
+ });
56
+ const scopes = res.headers.get("x-oauth-scopes");
57
+ let data = null;
58
+ try {
59
+ data = (await res.json());
60
+ }
61
+ catch {
62
+ /* empty body */
63
+ }
64
+ return { ok: res.ok, status: res.status, data, scopes };
65
+ }
66
+ catch (err) {
67
+ return { ok: false, status: 0, data: null, scopes: null, error: err instanceof Error ? err.message : String(err) };
68
+ }
69
+ }
70
+ export function getUser(token) {
71
+ return rest(token, "/user");
72
+ }
73
+ export function getRepo(token, owner, repo) {
74
+ return rest(token, `/repos/${owner}/${repo}`);
75
+ }
76
+ export function getBranch(token, owner, repo, branch) {
77
+ return rest(token, `/repos/${owner}/${repo}/branches/${encodeURIComponent(branch)}`);
78
+ }
79
+ /** Resolve a Projects v2 node ID via GraphQL — confirms the id is real and readable. */
80
+ export async function getProjectV2(token, projectId) {
81
+ try {
82
+ const res = await fetch(`${BASE}/graphql`, {
83
+ method: "POST",
84
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
85
+ body: JSON.stringify({
86
+ query: `query($id:ID!){ node(id:$id){ ... on ProjectV2 { title } } }`,
87
+ variables: { id: projectId },
88
+ }),
89
+ });
90
+ const json = (await res.json());
91
+ if (json.errors) {
92
+ return { ok: false, status: res.status, data: null, scopes: null, error: JSON.stringify(json.errors) };
93
+ }
94
+ const node = json.data?.node ?? null;
95
+ return { ok: Boolean(node), status: res.status, data: node, scopes: null };
96
+ }
97
+ catch (err) {
98
+ return { ok: false, status: 0, data: null, scopes: null, error: err instanceof Error ? err.message : String(err) };
99
+ }
100
+ }
101
+ //# sourceMappingURL=probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/cli/probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type CheckStatus = "pass" | "warn" | "fail" | "skip";
2
+ export interface CheckResult {
3
+ label: string;
4
+ status: CheckStatus;
5
+ detail: string;
6
+ }
7
+ export interface SanityOutcome {
8
+ results: CheckResult[];
9
+ resolved: {
10
+ owner?: string;
11
+ repo?: string;
12
+ tokenSource: "env" | "gh" | "none";
13
+ };
14
+ }
15
+ export declare function runSanity(values: Record<string, string>): Promise<SanityOutcome>;
16
+ //# sourceMappingURL=sanity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanity.d.ts","sourceRoot":"","sources":["../../src/cli/sanity.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,QAAQ,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,CAAA;KAAE,CAAC;CACjF;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CA2FtF"}
@@ -0,0 +1,99 @@
1
+ // The post-write sanity test. Non-fatal by contract: it reports pass/warn/fail
2
+ // per check but never blocks or reverts the .env that was just written — the
3
+ // wizard prints the results and exits 0 regardless.
4
+ import { resolveToken, resolveOwnerRepo, getUser, getRepo, getBranch, getProjectV2, } from "./probe.js";
5
+ export async function runSanity(values) {
6
+ const results = [];
7
+ const { token, source } = resolveToken(values.GITHUB_TOKEN);
8
+ const { owner, repo } = resolveOwnerRepo(values.GITHUB_OWNER, values.GITHUB_REPO);
9
+ const resolved = { owner, repo, tokenSource: source };
10
+ // 1. Token resolves + is valid.
11
+ if (!token) {
12
+ results.push({
13
+ label: "Token",
14
+ status: "fail",
15
+ detail: "No token: GITHUB_TOKEN unset and `gh auth token` returned nothing. Set a PAT or run `gh auth login`.",
16
+ });
17
+ return { results, resolved }; // nothing else is checkable without a token
18
+ }
19
+ const user = await getUser(token);
20
+ if (user.ok && user.data) {
21
+ results.push({ label: "Token", status: "pass", detail: `authenticated as ${user.data.login} (via ${source === "env" ? "GITHUB_TOKEN" : "gh CLI"})` });
22
+ }
23
+ else {
24
+ results.push({ label: "Token", status: "fail", detail: `GET /user failed (${user.status}). The token may be invalid or expired.` });
25
+ return { results, resolved };
26
+ }
27
+ // 2. Repo access.
28
+ if (!owner || !repo) {
29
+ results.push({ label: "Repository", status: "fail", detail: "Could not resolve owner/repo. Set GITHUB_OWNER/GITHUB_REPO or run inside a repo with a GitHub origin remote." });
30
+ }
31
+ else {
32
+ const repoRes = await getRepo(token, owner, repo);
33
+ if (repoRes.ok && repoRes.data) {
34
+ const def = repoRes.data.default_branch;
35
+ results.push({ label: "Repository", status: "pass", detail: `${owner}/${repo} reachable (default branch: ${def})` });
36
+ // 2b. Compare configured branches against the repo default — warn, never fail.
37
+ const base = values.OKFFS_BASE_BRANCH;
38
+ if (base && base !== def) {
39
+ results.push({
40
+ label: "Base branch",
41
+ status: "warn",
42
+ detail: `OKFFS_BASE_BRANCH="${base}" is not the repo default ("${def}"). Supported (Closes #N won't auto-close on merge into a non-default base — use close_issue).`,
43
+ });
44
+ }
45
+ // 3. Configured branches exist.
46
+ for (const [key, label] of [["OKFFS_BASE_BRANCH", "Base branch"], ["OKFFS_PROTECTED_BRANCH", "Protected branch"]]) {
47
+ const branch = values[key];
48
+ if (!branch)
49
+ continue;
50
+ const br = await getBranch(token, owner, repo, branch);
51
+ if (br.ok) {
52
+ results.push({ label, status: "pass", detail: `"${branch}" exists` });
53
+ }
54
+ else if (br.status === 404) {
55
+ results.push({ label, status: "warn", detail: `${key}="${branch}" not found on the remote — create it, or fix the value.` });
56
+ }
57
+ else {
58
+ results.push({ label, status: "warn", detail: `Could not verify ${key}="${branch}" (${br.status}).` });
59
+ }
60
+ }
61
+ }
62
+ else {
63
+ results.push({ label: "Repository", status: "fail", detail: `GET /repos/${owner}/${repo} failed (${repoRes.status}). Check the name and the token's repo access.` });
64
+ }
65
+ }
66
+ // 4. Projects v2 id resolves (only when enabled).
67
+ if (values.OKFFS_PROJECT_ENABLED === "true") {
68
+ const pid = values.OKFFS_PROJECT_ID;
69
+ if (!pid) {
70
+ results.push({ label: "Projects v2", status: "warn", detail: "OKFFS_PROJECT_ENABLED=true but OKFFS_PROJECT_ID is unset — Projects features stay inert." });
71
+ }
72
+ else {
73
+ const proj = await getProjectV2(token, pid);
74
+ if (proj.ok && proj.data) {
75
+ results.push({ label: "Projects v2", status: "pass", detail: `board "${proj.data.title}" resolved` });
76
+ }
77
+ else {
78
+ results.push({ label: "Projects v2", status: "warn", detail: `Could not resolve OKFFS_PROJECT_ID via GraphQL (${proj.error ?? proj.status}). Check the node ID and the token's Projects scope.` });
79
+ }
80
+ }
81
+ }
82
+ // 5. Classic PAT scope check.
83
+ if (values.OKFFS_CLASSIC_PAT === "true") {
84
+ // Re-fetch /user for the scopes header (getUser above didn't surface it here).
85
+ const scoped = await getUser(token);
86
+ const scopes = scoped.scopes;
87
+ if (scopes === null) {
88
+ results.push({ label: "Classic PAT", status: "warn", detail: "OKFFS_CLASSIC_PAT=true but no X-OAuth-Scopes header — this looks like a fine-grained PAT, not a classic admin:org token." });
89
+ }
90
+ else if (scopes.split(",").map((s) => s.trim()).includes("admin:org")) {
91
+ results.push({ label: "Classic PAT", status: "pass", detail: "token carries the admin:org scope" });
92
+ }
93
+ else {
94
+ results.push({ label: "Classic PAT", status: "warn", detail: `OKFFS_CLASSIC_PAT=true but the token scopes (${scopes || "none"}) do not include admin:org.` });
95
+ }
96
+ }
97
+ return { results, resolved };
98
+ }
99
+ //# sourceMappingURL=sanity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanity.js","sourceRoot":"","sources":["../../src/cli/sanity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(argv: string[]): Promise<number>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAkBA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyE9D"}