@jonit-dev/night-watch-cli 1.7.1 → 1.7.4

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 (68) hide show
  1. package/dist/board/factory.d.ts +3 -0
  2. package/dist/board/factory.d.ts.map +1 -0
  3. package/dist/board/factory.js +10 -0
  4. package/dist/board/factory.js.map +1 -0
  5. package/dist/board/providers/github-graphql.d.ts +16 -0
  6. package/dist/board/providers/github-graphql.d.ts.map +1 -0
  7. package/dist/board/providers/github-graphql.js +43 -0
  8. package/dist/board/providers/github-graphql.js.map +1 -0
  9. package/dist/board/providers/github-projects.d.ts +33 -0
  10. package/dist/board/providers/github-projects.d.ts.map +1 -0
  11. package/dist/board/providers/github-projects.js +443 -0
  12. package/dist/board/providers/github-projects.js.map +1 -0
  13. package/dist/board/types.d.ts +59 -0
  14. package/dist/board/types.d.ts.map +1 -0
  15. package/dist/board/types.js +4 -0
  16. package/dist/board/types.js.map +1 -0
  17. package/dist/commands/board.d.ts +9 -0
  18. package/dist/commands/board.d.ts.map +1 -0
  19. package/dist/commands/board.js +254 -0
  20. package/dist/commands/board.js.map +1 -0
  21. package/dist/commands/cancel.d.ts +1 -1
  22. package/dist/commands/cancel.d.ts.map +1 -1
  23. package/dist/commands/cancel.js +6 -7
  24. package/dist/commands/cancel.js.map +1 -1
  25. package/dist/commands/review.d.ts +4 -0
  26. package/dist/commands/review.d.ts.map +1 -1
  27. package/dist/commands/review.js +51 -19
  28. package/dist/commands/review.js.map +1 -1
  29. package/dist/commands/run.d.ts +6 -1
  30. package/dist/commands/run.d.ts.map +1 -1
  31. package/dist/commands/run.js +65 -21
  32. package/dist/commands/run.js.map +1 -1
  33. package/dist/config.d.ts.map +1 -1
  34. package/dist/config.js +22 -1
  35. package/dist/config.js.map +1 -1
  36. package/dist/constants.d.ts +2 -0
  37. package/dist/constants.d.ts.map +1 -1
  38. package/dist/constants.js +5 -0
  39. package/dist/constants.js.map +1 -1
  40. package/dist/server/index.d.ts.map +1 -1
  41. package/dist/server/index.js +185 -4
  42. package/dist/server/index.js.map +1 -1
  43. package/dist/types.d.ts +3 -0
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/utils/github.d.ts +10 -0
  46. package/dist/utils/github.d.ts.map +1 -1
  47. package/dist/utils/github.js +48 -26
  48. package/dist/utils/github.js.map +1 -1
  49. package/dist/utils/script-result.d.ts +12 -0
  50. package/dist/utils/script-result.d.ts.map +1 -0
  51. package/dist/utils/script-result.js +46 -0
  52. package/dist/utils/script-result.js.map +1 -0
  53. package/dist/utils/shell.d.ts +14 -0
  54. package/dist/utils/shell.d.ts.map +1 -1
  55. package/dist/utils/shell.js +21 -1
  56. package/dist/utils/shell.js.map +1 -1
  57. package/dist/utils/status-data.d.ts +2 -0
  58. package/dist/utils/status-data.d.ts.map +1 -1
  59. package/dist/utils/status-data.js +30 -1
  60. package/dist/utils/status-data.js.map +1 -1
  61. package/package.json +1 -1
  62. package/scripts/night-watch-cron.sh +143 -18
  63. package/scripts/night-watch-helpers.sh +39 -0
  64. package/scripts/night-watch-pr-reviewer-cron.sh +23 -2
  65. package/web/dist/assets/index-BCMat9cx.js +350 -0
  66. package/web/dist/assets/{index-Dx_ZY5CY.css → index-BW6hS5jr.css} +1 -1
  67. package/web/dist/index.html +2 -2
  68. package/web/dist/assets/index-Cogy7oRw.js +0 -350
@@ -0,0 +1,3 @@
1
+ import { IBoardProvider, IBoardProviderConfig } from "./types.js";
2
+ export declare function createBoardProvider(config: IBoardProviderConfig, cwd: string): IBoardProvider;
3
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/board/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAO7F"}
@@ -0,0 +1,10 @@
1
+ import { GitHubProjectsProvider } from "./providers/github-projects.js";
2
+ export function createBoardProvider(config, cwd) {
3
+ switch (config.provider) {
4
+ case "github":
5
+ return new GitHubProjectsProvider(config, cwd);
6
+ default:
7
+ throw new Error(`Unsupported board provider: ${config.provider}. Supported: github`);
8
+ }
9
+ }
10
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/board/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,MAAM,UAAU,mBAAmB,CAAC,MAA4B,EAAE,GAAW;IAC3E,QAAQ,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,KAAK,QAAQ;YACX,OAAO,IAAI,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjD;YACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,QAAQ,qBAAqB,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Execute a GraphQL query/mutation against the GitHub API using the `gh` CLI.
3
+ *
4
+ * Variables with numeric values are passed using `-F` (capital F) so the GitHub
5
+ * API receives them as numbers rather than strings. All other values use `-f`.
6
+ */
7
+ export declare function graphql<T>(query: string, variables: Record<string, unknown>, cwd: string): T;
8
+ /**
9
+ * Return the "owner/repo" name for the current working directory using `gh repo view`.
10
+ */
11
+ export declare function getRepoNwo(cwd: string): string;
12
+ /**
13
+ * Return the authenticated GitHub user's login.
14
+ */
15
+ export declare function getViewerLogin(cwd: string): string;
16
+ //# sourceMappingURL=github-graphql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-graphql.d.ts","sourceRoot":"","sources":["../../../src/board/providers/github-graphql.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,GAAG,EAAE,MAAM,GACV,CAAC,CA2BH;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlD"}
@@ -0,0 +1,43 @@
1
+ import { execFileSync } from "child_process";
2
+ /**
3
+ * Execute a GraphQL query/mutation against the GitHub API using the `gh` CLI.
4
+ *
5
+ * Variables with numeric values are passed using `-F` (capital F) so the GitHub
6
+ * API receives them as numbers rather than strings. All other values use `-f`.
7
+ */
8
+ export function graphql(query, variables, cwd) {
9
+ const args = ["api", "graphql", "-f", `query=${query}`];
10
+ for (const [key, value] of Object.entries(variables)) {
11
+ if (typeof value === "number") {
12
+ args.push("-F", `${key}=${String(value)}`);
13
+ }
14
+ else {
15
+ args.push("-f", `${key}=${String(value)}`);
16
+ }
17
+ }
18
+ const output = execFileSync("gh", args, {
19
+ cwd,
20
+ encoding: "utf-8",
21
+ stdio: ["pipe", "pipe", "pipe"],
22
+ });
23
+ const parsed = JSON.parse(output);
24
+ if (parsed.errors?.length) {
25
+ throw new Error(`GraphQL error: ${parsed.errors[0].message}`);
26
+ }
27
+ return parsed.data;
28
+ }
29
+ /**
30
+ * Return the "owner/repo" name for the current working directory using `gh repo view`.
31
+ */
32
+ export function getRepoNwo(cwd) {
33
+ const output = execFileSync("gh", ["repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner"], { cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
34
+ return output.trim();
35
+ }
36
+ /**
37
+ * Return the authenticated GitHub user's login.
38
+ */
39
+ export function getViewerLogin(cwd) {
40
+ const result = graphql(`query { viewer { login } }`, {}, cwd);
41
+ return result.viewer.login;
42
+ }
43
+ //# sourceMappingURL=github-graphql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-graphql.js","sourceRoot":"","sources":["../../../src/board/providers/github-graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CACrB,KAAa,EACb,SAAkC,EAClC,GAAW;IAEX,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IAExD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;QACtC,GAAG;QACH,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAG/B,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,MAAM,CAAC,IAAS,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,MAAM,GAAG,YAAY,CACzB,IAAI,EACJ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,CAAC,EACnE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAC5D,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,MAAM,GAAG,OAAO,CACpB,4BAA4B,EAC5B,EAAE,EACF,GAAG,CACJ,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { BoardColumnName, IBoardColumn, IBoardInfo, IBoardIssue, IBoardProvider, IBoardProviderConfig, ICreateIssueInput } from "../../board/types.js";
2
+ export declare class GitHubProjectsProvider implements IBoardProvider {
3
+ private readonly config;
4
+ private readonly cwd;
5
+ private cachedProjectId;
6
+ private cachedFieldId;
7
+ private cachedOptionIds;
8
+ constructor(config: IBoardProviderConfig, cwd: string);
9
+ private getRepo;
10
+ /**
11
+ * Fetch and cache the project node ID, Status field ID, and option IDs.
12
+ * Throws if the project cannot be found or has no Status field.
13
+ */
14
+ private ensureProjectCache;
15
+ /** Try user query first, fall back to org query. */
16
+ private fetchProjectNode;
17
+ /**
18
+ * Parse a raw project item node into IBoardIssue, returning null for items
19
+ * that are not issues.
20
+ */
21
+ private parseItem;
22
+ setupBoard(title: string): Promise<IBoardInfo>;
23
+ getBoard(): Promise<IBoardInfo | null>;
24
+ getColumns(): Promise<IBoardColumn[]>;
25
+ createIssue(input: ICreateIssueInput): Promise<IBoardIssue>;
26
+ getIssue(issueNumber: number): Promise<IBoardIssue | null>;
27
+ getIssuesByColumn(column: BoardColumnName): Promise<IBoardIssue[]>;
28
+ getAllIssues(): Promise<IBoardIssue[]>;
29
+ moveIssue(issueNumber: number, targetColumn: BoardColumnName): Promise<void>;
30
+ closeIssue(issueNumber: number): Promise<void>;
31
+ commentOnIssue(issueNumber: number, body: string): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=github-projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-projects.d.ts","sourceRoot":"","sources":["../../../src/board/providers/github-projects.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,eAAe,EACf,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AA8G1B,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,eAAe,CAAkC;gBAE7C,MAAM,EAAE,oBAAoB,EAAE,GAAG,EAAE,MAAM;IASrD,OAAO,CAAC,OAAO;IAIf;;;OAGG;YACW,kBAAkB;IA0EhC,oDAAoD;IACpD,OAAO,CAAC,gBAAgB;IAmDxB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAmCX,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA8D9C,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkBtC,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAQrC,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;IA6F3D,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA+C1D,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAKlE,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAoDtC,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,IAAI,CAAC;IAyEV,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQvE"}
@@ -0,0 +1,443 @@
1
+ import { execFileSync } from "child_process";
2
+ import { BOARD_COLUMNS, } from "../../board/types.js";
3
+ import { getRepoNwo, getViewerLogin, graphql } from "./github-graphql.js";
4
+ // ---------------------------------------------------------------------------
5
+ // GitHubProjectsProvider
6
+ // ---------------------------------------------------------------------------
7
+ export class GitHubProjectsProvider {
8
+ config;
9
+ cwd;
10
+ cachedProjectId = null;
11
+ cachedFieldId = null;
12
+ cachedOptionIds = new Map();
13
+ constructor(config, cwd) {
14
+ this.config = config;
15
+ this.cwd = cwd;
16
+ }
17
+ // -------------------------------------------------------------------------
18
+ // Helpers
19
+ // -------------------------------------------------------------------------
20
+ getRepo() {
21
+ return this.config.repo ?? getRepoNwo(this.cwd);
22
+ }
23
+ /**
24
+ * Fetch and cache the project node ID, Status field ID, and option IDs.
25
+ * Throws if the project cannot be found or has no Status field.
26
+ */
27
+ async ensureProjectCache() {
28
+ if (this.cachedProjectId !== null &&
29
+ this.cachedFieldId !== null &&
30
+ this.cachedOptionIds.size > 0) {
31
+ return {
32
+ projectId: this.cachedProjectId,
33
+ fieldId: this.cachedFieldId,
34
+ optionIds: this.cachedOptionIds,
35
+ };
36
+ }
37
+ const projectNumber = this.config.projectNumber;
38
+ if (!projectNumber) {
39
+ throw new Error("No projectNumber configured. Run `night-watch board setup` first.");
40
+ }
41
+ const login = getViewerLogin(this.cwd);
42
+ const projectNode = await this.fetchProjectNode(login, projectNumber);
43
+ if (!projectNode) {
44
+ throw new Error(`GitHub Project #${projectNumber} not found for login "${login}".`);
45
+ }
46
+ this.cachedProjectId = projectNode.id;
47
+ // Fetch Status field
48
+ const fieldData = graphql(`query GetStatusField($projectId: ID!) {
49
+ node(id: $projectId) {
50
+ ... on ProjectV2 {
51
+ field(name: "Status") {
52
+ ... on ProjectV2SingleSelectField {
53
+ id
54
+ options {
55
+ id
56
+ name
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }`, { projectId: projectNode.id }, this.cwd);
63
+ const field = fieldData.node?.field;
64
+ if (!field) {
65
+ throw new Error(`Status field not found on project #${projectNumber}. ` +
66
+ `Run \`night-watch board setup\` to create it.`);
67
+ }
68
+ this.cachedFieldId = field.id;
69
+ this.cachedOptionIds = new Map(field.options.map((o) => [o.name, o.id]));
70
+ return {
71
+ projectId: this.cachedProjectId,
72
+ fieldId: this.cachedFieldId,
73
+ optionIds: this.cachedOptionIds,
74
+ };
75
+ }
76
+ /** Try user query first, fall back to org query. */
77
+ fetchProjectNode(login, projectNumber) {
78
+ try {
79
+ const userData = graphql(`query GetProject($login: String!, $number: Int!) {
80
+ user(login: $login) {
81
+ projectV2(number: $number) {
82
+ id
83
+ title
84
+ url
85
+ }
86
+ }
87
+ }`, { login, number: projectNumber }, this.cwd);
88
+ if (userData.user?.projectV2) {
89
+ return userData.user.projectV2;
90
+ }
91
+ }
92
+ catch {
93
+ // Swallow — try org query next
94
+ }
95
+ try {
96
+ const orgData = graphql(`query GetOrgProject($login: String!, $number: Int!) {
97
+ organization(login: $login) {
98
+ projectV2(number: $number) {
99
+ id
100
+ title
101
+ url
102
+ }
103
+ }
104
+ }`, { login, number: projectNumber }, this.cwd);
105
+ if (orgData.organization?.projectV2) {
106
+ return orgData.organization.projectV2;
107
+ }
108
+ }
109
+ catch {
110
+ // Swallow
111
+ }
112
+ return null;
113
+ }
114
+ /**
115
+ * Parse a raw project item node into IBoardIssue, returning null for items
116
+ * that are not issues.
117
+ */
118
+ parseItem(item) {
119
+ const content = item.content;
120
+ if (!content || content.number === undefined) {
121
+ return null;
122
+ }
123
+ // Find the Status column value from the field values
124
+ let column = null;
125
+ for (const fv of item.fieldValues.nodes) {
126
+ if (fv.field?.name === "Status" && fv.name) {
127
+ const candidate = fv.name;
128
+ if (BOARD_COLUMNS.includes(candidate)) {
129
+ column = candidate;
130
+ }
131
+ }
132
+ }
133
+ return {
134
+ id: content.id ?? item.id,
135
+ number: content.number,
136
+ title: content.title ?? "",
137
+ body: content.body ?? "",
138
+ url: content.url ?? "",
139
+ column,
140
+ labels: content.labels?.nodes.map((l) => l.name) ?? [],
141
+ assignees: content.assignees?.nodes.map((a) => a.login) ?? [],
142
+ };
143
+ }
144
+ // -------------------------------------------------------------------------
145
+ // IBoardProvider implementation
146
+ // -------------------------------------------------------------------------
147
+ async setupBoard(title) {
148
+ // Resolve the authenticated user/org node ID
149
+ const viewerData = graphql(`query { viewer { id login } }`, {}, this.cwd);
150
+ const ownerId = viewerData.viewer.id;
151
+ // Create the project
152
+ const createData = graphql(`mutation CreateProject($ownerId: ID!, $title: String!) {
153
+ createProjectV2(input: { ownerId: $ownerId, title: $title }) {
154
+ projectV2 {
155
+ id
156
+ number
157
+ url
158
+ title
159
+ }
160
+ }
161
+ }`, { ownerId, title }, this.cwd);
162
+ const project = createData.createProjectV2.projectV2;
163
+ this.cachedProjectId = project.id;
164
+ // Create the Status field with the five lifecycle columns
165
+ const createFieldData = graphql(`mutation CreateStatusField($projectId: ID!) {
166
+ createProjectV2Field(input: {
167
+ projectId: $projectId,
168
+ dataType: SINGLE_SELECT,
169
+ name: "Status",
170
+ singleSelectOptions: [
171
+ { name: "Draft", color: GRAY, description: "" },
172
+ { name: "Ready", color: BLUE, description: "" },
173
+ { name: "In Progress", color: YELLOW, description: "" },
174
+ { name: "Review", color: ORANGE, description: "" },
175
+ { name: "Done", color: GREEN, description: "" }
176
+ ]
177
+ }) {
178
+ projectV2Field {
179
+ ... on ProjectV2SingleSelectField {
180
+ id
181
+ options { id name }
182
+ }
183
+ }
184
+ }
185
+ }`, { projectId: project.id }, this.cwd);
186
+ const field = createFieldData.createProjectV2Field.projectV2Field;
187
+ this.cachedFieldId = field.id;
188
+ this.cachedOptionIds = new Map(field.options.map((o) => [o.name, o.id]));
189
+ return { id: project.id, title: project.title, url: project.url };
190
+ }
191
+ async getBoard() {
192
+ const projectNumber = this.config.projectNumber;
193
+ if (!projectNumber) {
194
+ return null;
195
+ }
196
+ try {
197
+ const login = getViewerLogin(this.cwd);
198
+ const node = this.fetchProjectNode(login, projectNumber);
199
+ if (!node) {
200
+ return null;
201
+ }
202
+ return { id: node.id, title: node.title, url: node.url };
203
+ }
204
+ catch {
205
+ return null;
206
+ }
207
+ }
208
+ async getColumns() {
209
+ const { fieldId, optionIds } = await this.ensureProjectCache();
210
+ return BOARD_COLUMNS.map((name) => ({
211
+ id: optionIds.get(name) ?? fieldId,
212
+ name,
213
+ }));
214
+ }
215
+ async createIssue(input) {
216
+ const repo = this.getRepo();
217
+ const { projectId, fieldId, optionIds } = await this.ensureProjectCache();
218
+ // Create the issue via gh CLI (REST is simpler here)
219
+ const issueArgs = [
220
+ "issue",
221
+ "create",
222
+ "--title",
223
+ input.title,
224
+ "--body",
225
+ input.body,
226
+ "--repo",
227
+ repo,
228
+ "--json",
229
+ "number,id,url",
230
+ ];
231
+ if (input.labels && input.labels.length > 0) {
232
+ issueArgs.push("--label", input.labels.join(","));
233
+ }
234
+ const issueOutput = execFileSync("gh", issueArgs, {
235
+ cwd: this.cwd,
236
+ encoding: "utf-8",
237
+ stdio: ["pipe", "pipe", "pipe"],
238
+ });
239
+ const issueJson = JSON.parse(issueOutput);
240
+ // Add the issue to the project board
241
+ const addData = graphql(`mutation AddProjectItem($projectId: ID!, $contentId: ID!) {
242
+ addProjectV2ItemById(input: { projectId: $projectId, contentId: $contentId }) {
243
+ item {
244
+ id
245
+ }
246
+ }
247
+ }`, { projectId, contentId: issueJson.id }, this.cwd);
248
+ const itemId = addData.addProjectV2ItemById.item.id;
249
+ const targetColumn = input.column ?? "Draft";
250
+ const optionId = optionIds.get(targetColumn);
251
+ if (optionId) {
252
+ graphql(`mutation UpdateItemField(
253
+ $projectId: ID!,
254
+ $itemId: ID!,
255
+ $fieldId: ID!,
256
+ $optionId: String!
257
+ ) {
258
+ updateProjectV2ItemFieldValue(input: {
259
+ projectId: $projectId,
260
+ itemId: $itemId,
261
+ fieldId: $fieldId,
262
+ value: { singleSelectOptionId: $optionId }
263
+ }) {
264
+ projectV2Item {
265
+ id
266
+ }
267
+ }
268
+ }`, { projectId, itemId, fieldId, optionId }, this.cwd);
269
+ }
270
+ // Fetch the full issue details so we can return a complete IBoardIssue
271
+ const fullIssue = await this.getIssue(issueJson.number);
272
+ if (fullIssue) {
273
+ return { ...fullIssue, column: targetColumn };
274
+ }
275
+ return {
276
+ id: issueJson.id,
277
+ number: issueJson.number,
278
+ title: input.title,
279
+ body: input.body,
280
+ url: issueJson.url,
281
+ column: targetColumn,
282
+ labels: input.labels ?? [],
283
+ assignees: [],
284
+ };
285
+ }
286
+ async getIssue(issueNumber) {
287
+ const repo = this.getRepo();
288
+ let rawIssue;
289
+ try {
290
+ const output = execFileSync("gh", [
291
+ "issue",
292
+ "view",
293
+ String(issueNumber),
294
+ "--repo",
295
+ repo,
296
+ "--json",
297
+ "number,title,body,url,id,labels,assignees",
298
+ ], { cwd: this.cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
299
+ rawIssue = JSON.parse(output);
300
+ }
301
+ catch {
302
+ return null;
303
+ }
304
+ // Find which column this issue sits in by scanning all board items
305
+ let column = null;
306
+ try {
307
+ const allIssues = await this.getAllIssues();
308
+ const match = allIssues.find((i) => i.number === issueNumber);
309
+ if (match) {
310
+ column = match.column;
311
+ }
312
+ }
313
+ catch {
314
+ // Column stays null
315
+ }
316
+ return {
317
+ id: rawIssue.id,
318
+ number: rawIssue.number,
319
+ title: rawIssue.title,
320
+ body: rawIssue.body,
321
+ url: rawIssue.url,
322
+ column,
323
+ labels: rawIssue.labels.map((l) => l.name),
324
+ assignees: rawIssue.assignees.map((a) => a.login),
325
+ };
326
+ }
327
+ async getIssuesByColumn(column) {
328
+ const all = await this.getAllIssues();
329
+ return all.filter((issue) => issue.column === column);
330
+ }
331
+ async getAllIssues() {
332
+ const { projectId } = await this.ensureProjectCache();
333
+ const data = graphql(`query GetProjectItems($projectId: ID!) {
334
+ node(id: $projectId) {
335
+ ... on ProjectV2 {
336
+ items(first: 100) {
337
+ nodes {
338
+ id
339
+ content {
340
+ ... on Issue {
341
+ number
342
+ title
343
+ body
344
+ url
345
+ id
346
+ labels(first: 10) { nodes { name } }
347
+ assignees(first: 10) { nodes { login } }
348
+ }
349
+ }
350
+ fieldValues(first: 10) {
351
+ nodes {
352
+ ... on ProjectV2ItemFieldSingleSelectValue {
353
+ name
354
+ field {
355
+ ... on ProjectV2SingleSelectField {
356
+ name
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ }
365
+ }
366
+ }`, { projectId }, this.cwd);
367
+ const results = [];
368
+ for (const item of data.node.items.nodes) {
369
+ const parsed = this.parseItem(item);
370
+ if (parsed) {
371
+ results.push(parsed);
372
+ }
373
+ }
374
+ return results;
375
+ }
376
+ async moveIssue(issueNumber, targetColumn) {
377
+ const { projectId, fieldId, optionIds } = await this.ensureProjectCache();
378
+ // Fetch project items to find the item node ID for the target issue
379
+ const data = graphql(`query GetProjectItems($projectId: ID!) {
380
+ node(id: $projectId) {
381
+ ... on ProjectV2 {
382
+ items(first: 100) {
383
+ nodes {
384
+ id
385
+ content {
386
+ ... on Issue {
387
+ number
388
+ }
389
+ }
390
+ fieldValues(first: 10) {
391
+ nodes {
392
+ ... on ProjectV2ItemFieldSingleSelectValue {
393
+ name
394
+ field {
395
+ ... on ProjectV2SingleSelectField {
396
+ name
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
404
+ }
405
+ }
406
+ }`, { projectId }, this.cwd);
407
+ // Find the project item for this issue number
408
+ const itemNode = data.node.items.nodes.find((n) => n.content?.number === issueNumber);
409
+ if (!itemNode) {
410
+ throw new Error(`Issue #${issueNumber} not found on the project board.`);
411
+ }
412
+ const optionId = optionIds.get(targetColumn);
413
+ if (!optionId) {
414
+ throw new Error(`Column "${targetColumn}" not found on the project board.`);
415
+ }
416
+ graphql(`mutation UpdateItemField(
417
+ $projectId: ID!,
418
+ $itemId: ID!,
419
+ $fieldId: ID!,
420
+ $optionId: String!
421
+ ) {
422
+ updateProjectV2ItemFieldValue(input: {
423
+ projectId: $projectId,
424
+ itemId: $itemId,
425
+ fieldId: $fieldId,
426
+ value: { singleSelectOptionId: $optionId }
427
+ }) {
428
+ projectV2Item {
429
+ id
430
+ }
431
+ }
432
+ }`, { projectId, itemId: itemNode.id, fieldId, optionId }, this.cwd);
433
+ }
434
+ async closeIssue(issueNumber) {
435
+ const repo = this.getRepo();
436
+ execFileSync("gh", ["issue", "close", String(issueNumber), "--repo", repo], { cwd: this.cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
437
+ }
438
+ async commentOnIssue(issueNumber, body) {
439
+ const repo = this.getRepo();
440
+ execFileSync("gh", ["issue", "comment", String(issueNumber), "--repo", repo, "--body", body], { cwd: this.cwd, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
441
+ }
442
+ }
443
+ //# sourceMappingURL=github-projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-projects.js","sourceRoot":"","sources":["../../../src/board/providers/github-projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export type BoardColumnName = "Draft" | "Ready" | "In Progress" | "Review" | "Done";
2
+ export declare const BOARD_COLUMNS: BoardColumnName[];
3
+ export interface IBoardInfo {
4
+ id: string;
5
+ title: string;
6
+ url: string;
7
+ }
8
+ export interface IBoardColumn {
9
+ id: string;
10
+ name: BoardColumnName;
11
+ }
12
+ export interface IBoardIssue {
13
+ id: string;
14
+ number: number;
15
+ title: string;
16
+ body: string;
17
+ url: string;
18
+ column: BoardColumnName | null;
19
+ labels: string[];
20
+ assignees: string[];
21
+ }
22
+ export interface ICreateIssueInput {
23
+ title: string;
24
+ body: string;
25
+ column?: BoardColumnName;
26
+ labels?: string[];
27
+ }
28
+ export interface IBoardProvider {
29
+ /** Create a new project board with lifecycle columns. Returns board info. */
30
+ setupBoard(title: string): Promise<IBoardInfo>;
31
+ /** Get the configured board. Returns null if not set up. */
32
+ getBoard(): Promise<IBoardInfo | null>;
33
+ /** List all columns on the board. */
34
+ getColumns(): Promise<IBoardColumn[]>;
35
+ /** Create a GitHub issue and add it to the board in the specified column. */
36
+ createIssue(input: ICreateIssueInput): Promise<IBoardIssue>;
37
+ /** Get a single issue by number. */
38
+ getIssue(issueNumber: number): Promise<IBoardIssue | null>;
39
+ /** List issues in a specific column, ordered by priority. */
40
+ getIssuesByColumn(column: BoardColumnName): Promise<IBoardIssue[]>;
41
+ /** List all issues on the board. */
42
+ getAllIssues(): Promise<IBoardIssue[]>;
43
+ /** Move an issue to a different column. */
44
+ moveIssue(issueNumber: number, targetColumn: BoardColumnName): Promise<void>;
45
+ /** Close an issue (e.g., when done). */
46
+ closeIssue(issueNumber: number): Promise<void>;
47
+ /** Add a comment to an issue. */
48
+ commentOnIssue(issueNumber: number, body: string): Promise<void>;
49
+ }
50
+ export type BoardProviderType = "github" | "jira" | "linear";
51
+ export interface IBoardProviderConfig {
52
+ enabled: boolean;
53
+ provider: BoardProviderType;
54
+ /** GitHub Projects V2 project number (set after `board setup`) */
55
+ projectNumber?: number;
56
+ /** Repository owner/name (auto-detected from git remote) */
57
+ repo?: string;
58
+ }
59
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/board/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpF,eAAO,MAAM,aAAa,EAAE,eAAe,EAE1C,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE/C,4DAA4D;IAC5D,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAEvC,qCAAqC;IACrC,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEtC,6EAA6E;IAC7E,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE5D,oCAAoC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE3D,6DAA6D;IAC7D,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEnE,oCAAoC;IACpC,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEvC,2CAA2C;IAC3C,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7E,wCAAwC;IACxC,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,iCAAiC;IACjC,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,4 @@
1
+ export const BOARD_COLUMNS = [
2
+ "Draft", "Ready", "In Progress", "Review", "Done"
3
+ ];
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/board/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAsB;IAC9C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM;CAClD,CAAC"}