@cliangdev/flux-plugin 0.3.1-dev.ee3b5ee → 0.4.0-dev.0892a21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliangdev/flux-plugin",
3
- "version": "0.3.1-dev.ee3b5ee",
3
+ "version": "0.4.0-dev.0892a21",
4
4
  "description": "Claude Code plugin for AI-first workflow orchestration with MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",
@@ -284,7 +284,7 @@ function makeAdapter() {
284
284
  },
285
285
  };
286
286
 
287
- (adapter as any).client.rest.request = async (url: string, params: any) => {
287
+ (adapter as any).client.rest.request = async (url: string, _params: any) => {
288
288
  if (url.includes("sub_issues") && url.startsWith("GET")) {
289
289
  return { data: [] };
290
290
  }
@@ -16,7 +16,7 @@ let mockGraphqlFn: (
16
16
  variables?: Record<string, unknown>,
17
17
  ) => Promise<unknown> = async () => ({});
18
18
  let lastCreateParams: any = null;
19
- let lastUpdateParams: any = null;
19
+ let _lastUpdateParams: any = null;
20
20
  let lastUpdateByNumberParams: Record<number, any> = {};
21
21
  let lastPutParams: any = null;
22
22
  let issueNodeIdCounter = 0;
@@ -46,10 +46,10 @@ mock.module("@octokit/rest", () => ({
46
46
  update: async (params: any) => {
47
47
  const num = params.issue_number;
48
48
  lastUpdateByNumberParams[num] = params;
49
- lastUpdateParams = params;
49
+ _lastUpdateParams = params;
50
50
  return { data: mockIssuesUpdate ?? mockIssuesCreate };
51
51
  },
52
- get: async (params: any) => {
52
+ get: async (_params: any) => {
53
53
  if (mockIssuesGet === null) {
54
54
  const err: any = new Error("Not Found");
55
55
  err.status = 404;
@@ -122,7 +122,7 @@ function makeAdapter() {
122
122
  update: async (params: any) => {
123
123
  const num = params.issue_number;
124
124
  lastUpdateByNumberParams[num] = params;
125
- lastUpdateParams = params;
125
+ _lastUpdateParams = params;
126
126
  if (mockIssuesUpdate !== null) {
127
127
  return { data: mockIssuesUpdate };
128
128
  }
@@ -244,9 +244,9 @@ describe("prd status mappers", () => {
244
244
  "COMPLETED",
245
245
  ] as const;
246
246
  for (const status of statuses) {
247
- const label = prdStatusToLabel(status)!;
247
+ const label = prdStatusToLabel(status);
248
248
  expect(label).not.toBeNull();
249
- const result = labelToPrdStatus([label], false);
249
+ const result = labelToPrdStatus([label as string], false);
250
250
  expect(result).toBe(status);
251
251
  }
252
252
  });
@@ -280,7 +280,7 @@ describe("GitHubAdapter PRD CRUD", () => {
280
280
  mockSubIssues = {};
281
281
  mockGetContent = null;
282
282
  lastCreateParams = null;
283
- lastUpdateParams = null;
283
+ _lastUpdateParams = null;
284
284
  lastUpdateByNumberParams = {};
285
285
  lastPutParams = null;
286
286
  issueNodeIdCounter = 0;
@@ -378,7 +378,7 @@ describe("GitHubAdapter PRD CRUD", () => {
378
378
  await adapter.createPrd({ title: "Board PRD" });
379
379
 
380
380
  expect(capturedMutation).not.toBeNull();
381
- expect(capturedMutation!).toContain("addProjectV2ItemById");
381
+ expect(String(capturedMutation)).toContain("addProjectV2ItemById");
382
382
  expect(capturedVariables?.contentId).toBe("NODE_10");
383
383
  expect(capturedVariables?.projectId).toBe("PVT_kwDO123");
384
384
  });
@@ -50,9 +50,27 @@ import {
50
50
  } from "./mappers/index.js";
51
51
  import { GITHUB_LABELS, type GitHubConfig } from "./types.js";
52
52
 
53
- function issueToPrd(issue: any, config: GitHubConfig): Prd {
53
+ interface GitHubIssue {
54
+ number: number;
55
+ id: number;
56
+ node_id: string;
57
+ title: string;
58
+ body: string | null;
59
+ state: string;
60
+ labels: Array<{ name: string }>;
61
+ created_at: string;
62
+ updated_at: string;
63
+ }
64
+
65
+ interface GitHubDirectoryEntry {
66
+ type: string;
67
+ name: string;
68
+ path: string;
69
+ }
70
+
71
+ function issueToPrd(issue: GitHubIssue, config: GitHubConfig): Prd {
54
72
  const meta = decodeMeta(issue.body || "");
55
- const labels = issue.labels.map((l: any) => l.name as string);
73
+ const labels = issue.labels.map((l) => l.name);
56
74
  const ref = meta?.ref ?? `${config.refPrefix}-P${issue.number}`;
57
75
  const refSlug = ref.toLowerCase().replace(":", "-");
58
76
  const tag = labelToTag(labels) ?? meta?.tag;
@@ -122,7 +140,7 @@ export class GitHubAdapter implements BackendAdapter {
122
140
  body: string | null;
123
141
  }>;
124
142
  for (const issue of issues) {
125
- if (issue.body && issue.body.includes(`"ref":"${ref}"`)) {
143
+ if (issue.body?.includes(`"ref":"${ref}"`)) {
126
144
  await this.addToIndex(ref, issue.number);
127
145
  return issue.number;
128
146
  }
@@ -166,7 +184,7 @@ export class GitHubAdapter implements BackendAdapter {
166
184
  labels,
167
185
  });
168
186
 
169
- const createdIssue = createResponse.data as any;
187
+ const createdIssue = createResponse.data as GitHubIssue;
170
188
  const issueNumber = createdIssue.number;
171
189
  const ref = `${this.config.refPrefix}-P${issueNumber}`;
172
190
 
@@ -195,7 +213,7 @@ export class GitHubAdapter implements BackendAdapter {
195
213
  issue_number: issueNumber,
196
214
  });
197
215
 
198
- return issueToPrd(getResponse.data, this.config);
216
+ return issueToPrd(getResponse.data as GitHubIssue, this.config);
199
217
  }
200
218
 
201
219
  async updatePrd(ref: string, input: UpdatePrdInput): Promise<Prd> {
@@ -209,10 +227,8 @@ export class GitHubAdapter implements BackendAdapter {
209
227
  repo: this.config.repo,
210
228
  issue_number: issueNumber,
211
229
  });
212
- const existingIssue = getResponse.data as any;
213
- const existingLabels: string[] = existingIssue.labels.map(
214
- (l: any) => l.name as string,
215
- );
230
+ const existingIssue = getResponse.data as GitHubIssue;
231
+ const existingLabels: string[] = existingIssue.labels.map((l) => l.name);
216
232
 
217
233
  const statusLabels = new Set(getAllStatusLabels());
218
234
  const baseLabels = existingLabels.filter(
@@ -251,7 +267,7 @@ export class GitHubAdapter implements BackendAdapter {
251
267
  ? `${cleanDescription}\n\n${updatedMeta}`
252
268
  : updatedMeta;
253
269
 
254
- const updateParams: any = {
270
+ const updateParams: Record<string, unknown> = {
255
271
  owner: this.config.owner,
256
272
  repo: this.config.repo,
257
273
  issue_number: issueNumber,
@@ -267,9 +283,11 @@ export class GitHubAdapter implements BackendAdapter {
267
283
  updateParams.state = "closed";
268
284
  }
269
285
 
270
- const updateResponse = await this.client.rest.issues.update(updateParams);
286
+ const updateResponse = await this.client.rest.issues.update(
287
+ updateParams as Parameters<typeof this.client.rest.issues.update>[0],
288
+ );
271
289
 
272
- return issueToPrd(updateResponse.data, this.config);
290
+ return issueToPrd(updateResponse.data as GitHubIssue, this.config);
273
291
  }
274
292
 
275
293
  async getPrd(ref: string): Promise<Prd | null> {
@@ -282,7 +300,7 @@ export class GitHubAdapter implements BackendAdapter {
282
300
  issue_number: issueNumber,
283
301
  });
284
302
 
285
- return issueToPrd(response.data, this.config);
303
+ return issueToPrd(response.data as GitHubIssue, this.config);
286
304
  }
287
305
 
288
306
  async listPrds(
@@ -312,7 +330,7 @@ export class GitHubAdapter implements BackendAdapter {
312
330
  page: 1,
313
331
  });
314
332
 
315
- const allIssues = response.data as any[];
333
+ const allIssues = response.data as GitHubIssue[];
316
334
  const total = allIssues.length;
317
335
  const paginated = allIssues.slice(offset, offset + limit);
318
336
 
@@ -344,7 +362,7 @@ export class GitHubAdapter implements BackendAdapter {
344
362
  per_page: 100,
345
363
  });
346
364
 
347
- const epics = (epicsResponse.data as any[]).filter((issue: any) => {
365
+ const epics = (epicsResponse.data as GitHubIssue[]).filter((issue) => {
348
366
  const meta = decodeMeta(issue.body || "");
349
367
  return meta?.prd_ref === ref;
350
368
  });
@@ -362,7 +380,7 @@ export class GitHubAdapter implements BackendAdapter {
362
380
  per_page: 100,
363
381
  });
364
382
 
365
- const tasks = (tasksResponse.data as any[]).filter((issue: any) => {
383
+ const tasks = (tasksResponse.data as GitHubIssue[]).filter((issue) => {
366
384
  const meta = decodeMeta(issue.body || "");
367
385
  return meta?.epic_ref === epicRef;
368
386
  });
@@ -411,9 +429,9 @@ export class GitHubAdapter implements BackendAdapter {
411
429
  };
412
430
  }
413
431
 
414
- private issueToEpic(issue: any): Epic {
432
+ private issueToEpic(issue: GitHubIssue): Epic {
415
433
  const meta = decodeMeta(issue.body || "");
416
- const labels = issue.labels.map((l: any) => l.name as string);
434
+ const labels = issue.labels.map((l) => l.name);
417
435
  return {
418
436
  id: String(issue.number),
419
437
  prdId: meta?.prd_ref || "",
@@ -426,9 +444,9 @@ export class GitHubAdapter implements BackendAdapter {
426
444
  };
427
445
  }
428
446
 
429
- private issueToTask(issue: any): Task {
447
+ private issueToTask(issue: GitHubIssue): Task {
430
448
  const meta = decodeMeta(issue.body || "");
431
- const labels = issue.labels.map((l: any) => l.name as string);
449
+ const labels = issue.labels.map((l) => l.name);
432
450
  return {
433
451
  id: String(issue.number),
434
452
  epicId: meta?.epic_ref || "",
@@ -466,7 +484,7 @@ export class GitHubAdapter implements BackendAdapter {
466
484
  labels,
467
485
  });
468
486
 
469
- const createdIssue = createResponse.data as any;
487
+ const createdIssue = createResponse.data as GitHubIssue;
470
488
  const issueNumber = createdIssue.number;
471
489
  const ref = `${this.config.refPrefix}-E${issueNumber}`;
472
490
 
@@ -515,7 +533,7 @@ export class GitHubAdapter implements BackendAdapter {
515
533
  issue_number: issueNumber,
516
534
  });
517
535
 
518
- return this.issueToEpic(getResponse.data);
536
+ return this.issueToEpic(getResponse.data as GitHubIssue);
519
537
  }
520
538
 
521
539
  async updateEpic(ref: string, input: UpdateEpicInput): Promise<Epic> {
@@ -529,10 +547,8 @@ export class GitHubAdapter implements BackendAdapter {
529
547
  repo: this.config.repo,
530
548
  issue_number: issueNumber,
531
549
  });
532
- const existingIssue = getResponse.data as any;
533
- const existingLabels: string[] = existingIssue.labels.map(
534
- (l: any) => l.name as string,
535
- );
550
+ const existingIssue = getResponse.data as GitHubIssue;
551
+ const existingLabels: string[] = existingIssue.labels.map((l) => l.name);
536
552
 
537
553
  const statusLabelToRemove = GITHUB_LABELS.STATUS_IN_PROGRESS;
538
554
  const baseLabels = existingLabels.filter((l) => l !== statusLabelToRemove);
@@ -562,7 +578,7 @@ export class GitHubAdapter implements BackendAdapter {
562
578
  ? `${cleanDescription}\n\n${updatedMeta}`
563
579
  : updatedMeta;
564
580
 
565
- const updateParams: any = {
581
+ const updateParams: Record<string, unknown> = {
566
582
  owner: this.config.owner,
567
583
  repo: this.config.repo,
568
584
  issue_number: issueNumber,
@@ -578,9 +594,11 @@ export class GitHubAdapter implements BackendAdapter {
578
594
  updateParams.state = "closed";
579
595
  }
580
596
 
581
- const updateResponse = await this.client.rest.issues.update(updateParams);
597
+ const updateResponse = await this.client.rest.issues.update(
598
+ updateParams as Parameters<typeof this.client.rest.issues.update>[0],
599
+ );
582
600
 
583
- return this.issueToEpic(updateResponse.data);
601
+ return this.issueToEpic(updateResponse.data as GitHubIssue);
584
602
  }
585
603
 
586
604
  async getEpic(ref: string): Promise<Epic | null> {
@@ -593,7 +611,7 @@ export class GitHubAdapter implements BackendAdapter {
593
611
  issue_number: issueNumber,
594
612
  });
595
613
 
596
- return this.issueToEpic(response.data);
614
+ return this.issueToEpic(response.data as GitHubIssue);
597
615
  }
598
616
 
599
617
  async listEpics(
@@ -603,7 +621,7 @@ export class GitHubAdapter implements BackendAdapter {
603
621
  const limit = pagination?.limit ?? 50;
604
622
  const offset = pagination?.offset ?? 0;
605
623
 
606
- let allIssues: any[];
624
+ let allIssues: GitHubIssue[];
607
625
 
608
626
  if (filters?.prdRef) {
609
627
  const response = await this.client.rest.issues.listForRepo({
@@ -613,7 +631,7 @@ export class GitHubAdapter implements BackendAdapter {
613
631
  state: "all",
614
632
  per_page: 100,
615
633
  });
616
- allIssues = (response.data as any[]).filter((issue: any) => {
634
+ allIssues = (response.data as GitHubIssue[]).filter((issue) => {
617
635
  const meta = decodeMeta(issue.body || "");
618
636
  return meta?.prd_ref === filters.prdRef;
619
637
  });
@@ -634,12 +652,12 @@ export class GitHubAdapter implements BackendAdapter {
634
652
  per_page: 100,
635
653
  page: 1,
636
654
  });
637
- allIssues = response.data as any[];
655
+ allIssues = response.data as GitHubIssue[];
638
656
  }
639
657
 
640
658
  if (filters?.status) {
641
- allIssues = allIssues.filter((issue: any) => {
642
- const labels = issue.labels.map((l: any) => l.name as string);
659
+ allIssues = allIssues.filter((issue) => {
660
+ const labels = issue.labels.map((l) => l.name);
643
661
  return (
644
662
  labelToEpicStatus(labels, issue.state === "closed") === filters.status
645
663
  );
@@ -676,7 +694,7 @@ export class GitHubAdapter implements BackendAdapter {
676
694
  per_page: 100,
677
695
  });
678
696
 
679
- const tasks = (tasksResponse.data as any[]).filter((issue: any) => {
697
+ const tasks = (tasksResponse.data as GitHubIssue[]).filter((issue) => {
680
698
  const meta = decodeMeta(issue.body || "");
681
699
  return meta?.epic_ref === ref;
682
700
  });
@@ -729,7 +747,7 @@ export class GitHubAdapter implements BackendAdapter {
729
747
  repo: this.config.repo,
730
748
  issue_number: epicIssueNum,
731
749
  });
732
- const epicData = epicResponse.data as any;
750
+ const epicData = epicResponse.data as GitHubIssue;
733
751
  const epicMeta = decodeMeta(epicData.body || "");
734
752
  const prdRef = epicMeta?.prd_ref || "";
735
753
 
@@ -757,7 +775,7 @@ export class GitHubAdapter implements BackendAdapter {
757
775
  labels,
758
776
  });
759
777
 
760
- const createdIssue = createResponse.data as any;
778
+ const createdIssue = createResponse.data as GitHubIssue;
761
779
  const issueNumber = createdIssue.number;
762
780
  const ref = `${this.config.refPrefix}-T${issueNumber}`;
763
781
 
@@ -808,7 +826,7 @@ export class GitHubAdapter implements BackendAdapter {
808
826
  issue_number: issueNumber,
809
827
  });
810
828
 
811
- return this.issueToTask(getResponse.data);
829
+ return this.issueToTask(getResponse.data as GitHubIssue);
812
830
  }
813
831
 
814
832
  async updateTask(ref: string, input: UpdateTaskInput): Promise<Task> {
@@ -822,10 +840,8 @@ export class GitHubAdapter implements BackendAdapter {
822
840
  repo: this.config.repo,
823
841
  issue_number: issueNumber,
824
842
  });
825
- const existingIssue = getResponse.data as any;
826
- const existingLabels: string[] = existingIssue.labels.map(
827
- (l: any) => l.name as string,
828
- );
843
+ const existingIssue = getResponse.data as GitHubIssue;
844
+ const existingLabels: string[] = existingIssue.labels.map((l) => l.name);
829
845
 
830
846
  const priorityLabels = new Set<string>([
831
847
  GITHUB_LABELS.PRIORITY_LOW,
@@ -866,7 +882,7 @@ export class GitHubAdapter implements BackendAdapter {
866
882
  ? `${cleanDescription}\n\n${updatedMeta}`
867
883
  : updatedMeta;
868
884
 
869
- const updateParams: any = {
885
+ const updateParams: Record<string, unknown> = {
870
886
  owner: this.config.owner,
871
887
  repo: this.config.repo,
872
888
  issue_number: issueNumber,
@@ -882,9 +898,11 @@ export class GitHubAdapter implements BackendAdapter {
882
898
  updateParams.state = "closed";
883
899
  }
884
900
 
885
- const updateResponse = await this.client.rest.issues.update(updateParams);
901
+ const updateResponse = await this.client.rest.issues.update(
902
+ updateParams as Parameters<typeof this.client.rest.issues.update>[0],
903
+ );
886
904
 
887
- return this.issueToTask(updateResponse.data);
905
+ return this.issueToTask(updateResponse.data as GitHubIssue);
888
906
  }
889
907
 
890
908
  async getTask(ref: string): Promise<Task | null> {
@@ -897,7 +915,7 @@ export class GitHubAdapter implements BackendAdapter {
897
915
  issue_number: issueNumber,
898
916
  });
899
917
 
900
- return this.issueToTask(response.data);
918
+ return this.issueToTask(response.data as GitHubIssue);
901
919
  }
902
920
 
903
921
  async listTasks(
@@ -907,7 +925,7 @@ export class GitHubAdapter implements BackendAdapter {
907
925
  const limit = pagination?.limit ?? 50;
908
926
  const offset = pagination?.offset ?? 0;
909
927
 
910
- let allIssues: any[];
928
+ let allIssues: GitHubIssue[];
911
929
 
912
930
  if (filters?.epicRef) {
913
931
  const response = await this.client.rest.issues.listForRepo({
@@ -917,7 +935,7 @@ export class GitHubAdapter implements BackendAdapter {
917
935
  state: "all",
918
936
  per_page: 100,
919
937
  });
920
- allIssues = (response.data as any[]).filter((issue: any) => {
938
+ allIssues = (response.data as GitHubIssue[]).filter((issue) => {
921
939
  const meta = decodeMeta(issue.body || "");
922
940
  return meta?.epic_ref === filters.epicRef;
923
941
  });
@@ -941,12 +959,12 @@ export class GitHubAdapter implements BackendAdapter {
941
959
  per_page: 100,
942
960
  page: 1,
943
961
  });
944
- allIssues = response.data as any[];
962
+ allIssues = response.data as GitHubIssue[];
945
963
  }
946
964
 
947
965
  if (filters?.status) {
948
- allIssues = allIssues.filter((issue: any) => {
949
- const labels = issue.labels.map((l: any) => l.name as string);
966
+ allIssues = allIssues.filter((issue) => {
967
+ const labels = issue.labels.map((l) => l.name);
950
968
  return (
951
969
  labelToTaskStatus(labels, issue.state === "closed") === filters.status
952
970
  );
@@ -1009,7 +1027,7 @@ export class GitHubAdapter implements BackendAdapter {
1009
1027
  if (body.includes("<!-- flux-meta")) {
1010
1028
  return body.replace(/<!--\s*flux-meta[\s\S]*?-->/, newMetaBlock);
1011
1029
  }
1012
- return body + "\n\n" + newMetaBlock;
1030
+ return `${body}\n\n${newMetaBlock}`;
1013
1031
  }
1014
1032
 
1015
1033
  async addCriterion(input: AddCriterionInput): Promise<AcceptanceCriterion> {
@@ -1024,7 +1042,7 @@ export class GitHubAdapter implements BackendAdapter {
1024
1042
  repo: this.config.repo,
1025
1043
  issue_number: issueNumber,
1026
1044
  });
1027
- const currentBody = (getResponse.data as any).body ?? "";
1045
+ const currentBody = (getResponse.data as GitHubIssue).body ?? "";
1028
1046
 
1029
1047
  const newBody = addCriterionToDescription(currentBody, input.criteria);
1030
1048
 
@@ -1046,7 +1064,7 @@ export class GitHubAdapter implements BackendAdapter {
1046
1064
  }
1047
1065
 
1048
1066
  async markCriterionMet(criterionId: string): Promise<AcceptanceCriterion> {
1049
- const allIssues: any[] = [];
1067
+ const allIssues: GitHubIssue[] = [];
1050
1068
 
1051
1069
  const epicResponse = await this.client.rest.issues.listForRepo({
1052
1070
  owner: this.config.owner,
@@ -1055,7 +1073,7 @@ export class GitHubAdapter implements BackendAdapter {
1055
1073
  state: "open",
1056
1074
  per_page: 100,
1057
1075
  });
1058
- allIssues.push(...(epicResponse.data as any[]));
1076
+ allIssues.push(...(epicResponse.data as GitHubIssue[]));
1059
1077
 
1060
1078
  const taskResponse = await this.client.rest.issues.listForRepo({
1061
1079
  owner: this.config.owner,
@@ -1064,7 +1082,7 @@ export class GitHubAdapter implements BackendAdapter {
1064
1082
  state: "open",
1065
1083
  per_page: 100,
1066
1084
  });
1067
- allIssues.push(...(taskResponse.data as any[]));
1085
+ allIssues.push(...(taskResponse.data as GitHubIssue[]));
1068
1086
 
1069
1087
  for (const issue of allIssues) {
1070
1088
  const body = issue.body ?? "";
@@ -1079,7 +1097,7 @@ export class GitHubAdapter implements BackendAdapter {
1079
1097
  body: newBody,
1080
1098
  });
1081
1099
 
1082
- const labels: string[] = issue.labels.map((l: any) => l.name as string);
1100
+ const labels: string[] = issue.labels.map((l) => l.name);
1083
1101
  const parentType = labels.includes(GITHUB_LABELS.ENTITY_EPIC)
1084
1102
  ? "epic"
1085
1103
  : "task";
@@ -1110,7 +1128,7 @@ export class GitHubAdapter implements BackendAdapter {
1110
1128
  repo: this.config.repo,
1111
1129
  issue_number: issueNumber,
1112
1130
  });
1113
- const body = (response.data as any).body ?? "";
1131
+ const body = (response.data as GitHubIssue).body ?? "";
1114
1132
  const parsed = parseCriteriaFromDescription(body);
1115
1133
  const parentType = this.getParentType(parentRef);
1116
1134
 
@@ -1155,7 +1173,7 @@ export class GitHubAdapter implements BackendAdapter {
1155
1173
  repo: this.config.repo,
1156
1174
  issue_number: issueNumber,
1157
1175
  });
1158
- const currentBody = (getResponse.data as any).body ?? "";
1176
+ const currentBody = (getResponse.data as GitHubIssue).body ?? "";
1159
1177
  const meta = decodeMeta(currentBody);
1160
1178
 
1161
1179
  if (!meta) {
@@ -1188,7 +1206,7 @@ export class GitHubAdapter implements BackendAdapter {
1188
1206
  repo: this.config.repo,
1189
1207
  issue_number: issueNumber,
1190
1208
  });
1191
- const currentBody = (getResponse.data as any).body ?? "";
1209
+ const currentBody = (getResponse.data as GitHubIssue).body ?? "";
1192
1210
  const meta = decodeMeta(currentBody);
1193
1211
 
1194
1212
  if (!meta) {
@@ -1220,7 +1238,7 @@ export class GitHubAdapter implements BackendAdapter {
1220
1238
  repo: this.config.repo,
1221
1239
  issue_number: issueNumber,
1222
1240
  });
1223
- const body = (response.data as any).body ?? "";
1241
+ const body = (response.data as GitHubIssue).body ?? "";
1224
1242
  const meta = decodeMeta(body);
1225
1243
 
1226
1244
  return meta?.dependencies ?? [];
@@ -1243,8 +1261,8 @@ export class GitHubAdapter implements BackendAdapter {
1243
1261
  });
1244
1262
  const data = response.data as { sha: string };
1245
1263
  return data.sha;
1246
- } catch (err: any) {
1247
- if (err.status === 404) return null;
1264
+ } catch (err: unknown) {
1265
+ if ((err as { status?: number }).status === 404) return null;
1248
1266
  throw err;
1249
1267
  }
1250
1268
  }
@@ -1314,7 +1332,11 @@ export class GitHubAdapter implements BackendAdapter {
1314
1332
  putParams.sha = existingSha;
1315
1333
  }
1316
1334
 
1317
- await this.client.rest.repos.createOrUpdateFileContents(putParams as any);
1335
+ await this.client.rest.repos.createOrUpdateFileContents(
1336
+ putParams as Parameters<
1337
+ typeof this.client.rest.repos.createOrUpdateFileContents
1338
+ >[0],
1339
+ );
1318
1340
 
1319
1341
  const blobUrl = this.blobUrl(filePath);
1320
1342
 
@@ -1323,7 +1345,7 @@ export class GitHubAdapter implements BackendAdapter {
1323
1345
  repo: this.config.repo,
1324
1346
  issue_number: issueNumber,
1325
1347
  });
1326
- const currentBody = (issueResponse.data as any).body ?? "";
1348
+ const currentBody = (issueResponse.data as GitHubIssue).body ?? "";
1327
1349
  const updatedBody = this.addDocumentLink(
1328
1350
  currentBody,
1329
1351
  doc.filename,
@@ -1344,21 +1366,21 @@ export class GitHubAdapter implements BackendAdapter {
1344
1366
  const slug = this.refSlug(prdRef);
1345
1367
  const dirPath = `prds/${slug}`;
1346
1368
 
1347
- let entries: any[];
1369
+ let entries: GitHubDirectoryEntry[];
1348
1370
  try {
1349
1371
  const response = await this.client.rest.repos.getContent({
1350
1372
  owner: this.config.owner,
1351
1373
  repo: this.config.repo,
1352
1374
  path: dirPath,
1353
1375
  });
1354
- entries = response.data as any[];
1355
- } catch (err: any) {
1356
- if (err.status === 404) return [];
1376
+ entries = response.data as GitHubDirectoryEntry[];
1377
+ } catch (err: unknown) {
1378
+ if ((err as { status?: number }).status === 404) return [];
1357
1379
  throw err;
1358
1380
  }
1359
1381
 
1360
1382
  const mdFiles = entries.filter(
1361
- (entry: any) => entry.type === "file" && entry.name.endsWith(".md"),
1383
+ (entry) => entry.type === "file" && entry.name.endsWith(".md"),
1362
1384
  );
1363
1385
 
1364
1386
  const documents: Document[] = [];
@@ -1396,7 +1418,7 @@ export class GitHubAdapter implements BackendAdapter {
1396
1418
  const sha = await this.getFileSha(filePath);
1397
1419
 
1398
1420
  if (sha !== null) {
1399
- await (this.client.rest.repos as any).deleteFile({
1421
+ await this.client.rest.repos.deleteFile({
1400
1422
  owner: this.config.owner,
1401
1423
  repo: this.config.repo,
1402
1424
  path: filePath,
@@ -1410,7 +1432,7 @@ export class GitHubAdapter implements BackendAdapter {
1410
1432
  repo: this.config.repo,
1411
1433
  issue_number: issueNumber,
1412
1434
  });
1413
- const currentBody = (issueResponse.data as any).body ?? "";
1435
+ const currentBody = (issueResponse.data as GitHubIssue).body ?? "";
1414
1436
  const updatedBody = this.removeDocumentLink(currentBody, filename);
1415
1437
 
1416
1438
  await this.client.rest.issues.update({
@@ -1474,12 +1496,12 @@ export class GitHubAdapter implements BackendAdapter {
1474
1496
  }),
1475
1497
  ]);
1476
1498
 
1477
- const openPrdIssues = openPrds.data as any[];
1478
- const closedPrdIssues = closedPrds.data as any[];
1479
- const openEpicIssues = openEpics.data as any[];
1480
- const closedEpicIssues = closedEpics.data as any[];
1481
- const openTaskIssues = openTasks.data as any[];
1482
- const closedTaskIssues = closedTasks.data as any[];
1499
+ const openPrdIssues = openPrds.data as GitHubIssue[];
1500
+ const closedPrdIssues = closedPrds.data as GitHubIssue[];
1501
+ const openEpicIssues = openEpics.data as GitHubIssue[];
1502
+ const closedEpicIssues = closedEpics.data as GitHubIssue[];
1503
+ const openTaskIssues = openTasks.data as GitHubIssue[];
1504
+ const closedTaskIssues = closedTasks.data as GitHubIssue[];
1483
1505
 
1484
1506
  const prdStats = {
1485
1507
  total: openPrdIssues.length,
@@ -1493,7 +1515,7 @@ export class GitHubAdapter implements BackendAdapter {
1493
1515
  };
1494
1516
 
1495
1517
  for (const issue of openPrdIssues) {
1496
- const labels = issue.labels.map((l: any) => l.name as string);
1518
+ const labels = issue.labels.map((l) => l.name);
1497
1519
  if (labels.includes(GITHUB_LABELS.STATUS_COMPLETED)) {
1498
1520
  prdStats.completed++;
1499
1521
  } else if (labels.includes(GITHUB_LABELS.STATUS_BREAKDOWN_READY)) {
@@ -1509,25 +1531,25 @@ export class GitHubAdapter implements BackendAdapter {
1509
1531
  }
1510
1532
  }
1511
1533
 
1512
- const epicPending = openEpicIssues.filter((issue: any) => {
1513
- const labels = issue.labels.map((l: any) => l.name as string);
1534
+ const epicPending = openEpicIssues.filter((issue) => {
1535
+ const labels = issue.labels.map((l) => l.name);
1514
1536
  return !labels.includes(GITHUB_LABELS.STATUS_IN_PROGRESS);
1515
1537
  }).length;
1516
1538
 
1517
- const epicInProgress = openEpicIssues.filter((issue: any) => {
1518
- const labels = issue.labels.map((l: any) => l.name as string);
1539
+ const epicInProgress = openEpicIssues.filter((issue) => {
1540
+ const labels = issue.labels.map((l) => l.name);
1519
1541
  return labels.includes(GITHUB_LABELS.STATUS_IN_PROGRESS);
1520
1542
  }).length;
1521
1543
 
1522
1544
  const epicCompleted = closedEpicIssues.length;
1523
1545
 
1524
- const taskPending = openTaskIssues.filter((issue: any) => {
1525
- const labels = issue.labels.map((l: any) => l.name as string);
1546
+ const taskPending = openTaskIssues.filter((issue) => {
1547
+ const labels = issue.labels.map((l) => l.name);
1526
1548
  return !labels.includes(GITHUB_LABELS.STATUS_IN_PROGRESS);
1527
1549
  }).length;
1528
1550
 
1529
- const taskInProgress = openTaskIssues.filter((issue: any) => {
1530
- const labels = issue.labels.map((l: any) => l.name as string);
1551
+ const taskInProgress = openTaskIssues.filter((issue) => {
1552
+ const labels = issue.labels.map((l) => l.name);
1531
1553
  return labels.includes(GITHUB_LABELS.STATUS_IN_PROGRESS);
1532
1554
  }).length;
1533
1555
 
@@ -21,10 +21,11 @@ export class GitHubClient {
21
21
  ): Promise<T> {
22
22
  try {
23
23
  return await this.gql<T>(query, variables);
24
- } catch (error: any) {
25
- if (error.status === 401 || error.status === 403) {
24
+ } catch (error: unknown) {
25
+ const err = error as { status?: number };
26
+ if (err.status === 401 || err.status === 403) {
26
27
  throw new Error(
27
- `GitHub API auth error: token may lack 'repo' scope (HTTP ${error.status})`,
28
+ `GitHub API auth error: token may lack 'repo' scope (HTTP ${err.status})`,
28
29
  );
29
30
  }
30
31
  throw error;