@zibby/skills 0.1.88 → 0.1.90

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/dist/github.d.ts CHANGED
@@ -45,7 +45,11 @@ export namespace githubSkill {
45
45
  comments?: undefined;
46
46
  branch?: undefined;
47
47
  path?: undefined;
48
+ since?: undefined;
49
+ until?: undefined;
50
+ page?: undefined;
48
51
  sha?: undefined;
52
+ includePrs?: undefined;
49
53
  ref?: undefined;
50
54
  head?: undefined;
51
55
  base?: undefined;
@@ -56,7 +60,6 @@ export namespace githubSkill {
56
60
  commitMessage?: undefined;
57
61
  state?: undefined;
58
62
  labels?: undefined;
59
- since?: undefined;
60
63
  assignee?: undefined;
61
64
  stateReason?: undefined;
62
65
  mode?: undefined;
@@ -106,7 +109,11 @@ export namespace githubSkill {
106
109
  comments?: undefined;
107
110
  branch?: undefined;
108
111
  path?: undefined;
112
+ since?: undefined;
113
+ until?: undefined;
114
+ page?: undefined;
109
115
  sha?: undefined;
116
+ includePrs?: undefined;
110
117
  ref?: undefined;
111
118
  head?: undefined;
112
119
  base?: undefined;
@@ -117,7 +124,6 @@ export namespace githubSkill {
117
124
  commitMessage?: undefined;
118
125
  state?: undefined;
119
126
  labels?: undefined;
120
- since?: undefined;
121
127
  assignee?: undefined;
122
128
  stateReason?: undefined;
123
129
  mode?: undefined;
@@ -155,7 +161,11 @@ export namespace githubSkill {
155
161
  comments?: undefined;
156
162
  branch?: undefined;
157
163
  path?: undefined;
164
+ since?: undefined;
165
+ until?: undefined;
166
+ page?: undefined;
158
167
  sha?: undefined;
168
+ includePrs?: undefined;
159
169
  ref?: undefined;
160
170
  head?: undefined;
161
171
  base?: undefined;
@@ -166,7 +176,6 @@ export namespace githubSkill {
166
176
  commitMessage?: undefined;
167
177
  state?: undefined;
168
178
  labels?: undefined;
169
- since?: undefined;
170
179
  assignee?: undefined;
171
180
  stateReason?: undefined;
172
181
  mode?: undefined;
@@ -201,7 +210,11 @@ export namespace githubSkill {
201
210
  comments?: undefined;
202
211
  branch?: undefined;
203
212
  path?: undefined;
213
+ since?: undefined;
214
+ until?: undefined;
215
+ page?: undefined;
204
216
  sha?: undefined;
217
+ includePrs?: undefined;
205
218
  ref?: undefined;
206
219
  head?: undefined;
207
220
  base?: undefined;
@@ -212,7 +225,6 @@ export namespace githubSkill {
212
225
  commitMessage?: undefined;
213
226
  state?: undefined;
214
227
  labels?: undefined;
215
- since?: undefined;
216
228
  assignee?: undefined;
217
229
  stateReason?: undefined;
218
230
  mode?: undefined;
@@ -253,7 +265,11 @@ export namespace githubSkill {
253
265
  comments?: undefined;
254
266
  branch?: undefined;
255
267
  path?: undefined;
268
+ since?: undefined;
269
+ until?: undefined;
270
+ page?: undefined;
256
271
  sha?: undefined;
272
+ includePrs?: undefined;
257
273
  ref?: undefined;
258
274
  head?: undefined;
259
275
  base?: undefined;
@@ -264,7 +280,6 @@ export namespace githubSkill {
264
280
  commitMessage?: undefined;
265
281
  state?: undefined;
266
282
  labels?: undefined;
267
- since?: undefined;
268
283
  assignee?: undefined;
269
284
  stateReason?: undefined;
270
285
  mode?: undefined;
@@ -302,7 +317,11 @@ export namespace githubSkill {
302
317
  comments?: undefined;
303
318
  branch?: undefined;
304
319
  path?: undefined;
320
+ since?: undefined;
321
+ until?: undefined;
322
+ page?: undefined;
305
323
  sha?: undefined;
324
+ includePrs?: undefined;
306
325
  ref?: undefined;
307
326
  head?: undefined;
308
327
  base?: undefined;
@@ -313,7 +332,6 @@ export namespace githubSkill {
313
332
  commitMessage?: undefined;
314
333
  state?: undefined;
315
334
  labels?: undefined;
316
- since?: undefined;
317
335
  assignee?: undefined;
318
336
  stateReason?: undefined;
319
337
  mode?: undefined;
@@ -354,7 +372,11 @@ export namespace githubSkill {
354
372
  comments?: undefined;
355
373
  branch?: undefined;
356
374
  path?: undefined;
375
+ since?: undefined;
376
+ until?: undefined;
377
+ page?: undefined;
357
378
  sha?: undefined;
379
+ includePrs?: undefined;
358
380
  ref?: undefined;
359
381
  head?: undefined;
360
382
  base?: undefined;
@@ -365,7 +387,6 @@ export namespace githubSkill {
365
387
  commitMessage?: undefined;
366
388
  state?: undefined;
367
389
  labels?: undefined;
368
- since?: undefined;
369
390
  assignee?: undefined;
370
391
  stateReason?: undefined;
371
392
  mode?: undefined;
@@ -409,7 +430,11 @@ export namespace githubSkill {
409
430
  comments?: undefined;
410
431
  branch?: undefined;
411
432
  path?: undefined;
433
+ since?: undefined;
434
+ until?: undefined;
435
+ page?: undefined;
412
436
  sha?: undefined;
437
+ includePrs?: undefined;
413
438
  ref?: undefined;
414
439
  head?: undefined;
415
440
  base?: undefined;
@@ -420,7 +445,6 @@ export namespace githubSkill {
420
445
  commitMessage?: undefined;
421
446
  state?: undefined;
422
447
  labels?: undefined;
423
- since?: undefined;
424
448
  assignee?: undefined;
425
449
  stateReason?: undefined;
426
450
  mode?: undefined;
@@ -461,7 +485,11 @@ export namespace githubSkill {
461
485
  comments?: undefined;
462
486
  branch?: undefined;
463
487
  path?: undefined;
488
+ since?: undefined;
489
+ until?: undefined;
490
+ page?: undefined;
464
491
  sha?: undefined;
492
+ includePrs?: undefined;
465
493
  ref?: undefined;
466
494
  head?: undefined;
467
495
  base?: undefined;
@@ -472,7 +500,6 @@ export namespace githubSkill {
472
500
  commitMessage?: undefined;
473
501
  state?: undefined;
474
502
  labels?: undefined;
475
- since?: undefined;
476
503
  assignee?: undefined;
477
504
  stateReason?: undefined;
478
505
  mode?: undefined;
@@ -543,7 +570,11 @@ export namespace githubSkill {
543
570
  commentId?: undefined;
544
571
  branch?: undefined;
545
572
  path?: undefined;
573
+ since?: undefined;
574
+ until?: undefined;
575
+ page?: undefined;
546
576
  sha?: undefined;
577
+ includePrs?: undefined;
547
578
  ref?: undefined;
548
579
  head?: undefined;
549
580
  base?: undefined;
@@ -554,7 +585,6 @@ export namespace githubSkill {
554
585
  commitMessage?: undefined;
555
586
  state?: undefined;
556
587
  labels?: undefined;
557
- since?: undefined;
558
588
  assignee?: undefined;
559
589
  stateReason?: undefined;
560
590
  mode?: undefined;
@@ -587,6 +617,18 @@ export namespace githubSkill {
587
617
  type: string;
588
618
  description: string;
589
619
  };
620
+ since: {
621
+ type: string;
622
+ description: string;
623
+ };
624
+ until: {
625
+ type: string;
626
+ description: string;
627
+ };
628
+ page: {
629
+ type: string;
630
+ description: string;
631
+ };
590
632
  query?: undefined;
591
633
  type?: undefined;
592
634
  sort?: undefined;
@@ -599,6 +641,7 @@ export namespace githubSkill {
599
641
  event?: undefined;
600
642
  comments?: undefined;
601
643
  sha?: undefined;
644
+ includePrs?: undefined;
602
645
  ref?: undefined;
603
646
  head?: undefined;
604
647
  base?: undefined;
@@ -609,7 +652,6 @@ export namespace githubSkill {
609
652
  commitMessage?: undefined;
610
653
  state?: undefined;
611
654
  labels?: undefined;
612
- since?: undefined;
613
655
  assignee?: undefined;
614
656
  stateReason?: undefined;
615
657
  mode?: undefined;
@@ -634,6 +676,10 @@ export namespace githubSkill {
634
676
  type: string;
635
677
  description: string;
636
678
  };
679
+ includePrs: {
680
+ type: string;
681
+ description: string;
682
+ };
637
683
  query?: undefined;
638
684
  type?: undefined;
639
685
  sort?: undefined;
@@ -648,6 +694,9 @@ export namespace githubSkill {
648
694
  comments?: undefined;
649
695
  branch?: undefined;
650
696
  path?: undefined;
697
+ since?: undefined;
698
+ until?: undefined;
699
+ page?: undefined;
651
700
  ref?: undefined;
652
701
  head?: undefined;
653
702
  base?: undefined;
@@ -658,7 +707,6 @@ export namespace githubSkill {
658
707
  commitMessage?: undefined;
659
708
  state?: undefined;
660
709
  labels?: undefined;
661
- since?: undefined;
662
710
  assignee?: undefined;
663
711
  stateReason?: undefined;
664
712
  mode?: undefined;
@@ -700,7 +748,11 @@ export namespace githubSkill {
700
748
  event?: undefined;
701
749
  comments?: undefined;
702
750
  branch?: undefined;
751
+ since?: undefined;
752
+ until?: undefined;
753
+ page?: undefined;
703
754
  sha?: undefined;
755
+ includePrs?: undefined;
704
756
  head?: undefined;
705
757
  base?: undefined;
706
758
  title?: undefined;
@@ -710,7 +762,6 @@ export namespace githubSkill {
710
762
  commitMessage?: undefined;
711
763
  state?: undefined;
712
764
  labels?: undefined;
713
- since?: undefined;
714
765
  assignee?: undefined;
715
766
  stateReason?: undefined;
716
767
  mode?: undefined;
@@ -764,14 +815,17 @@ export namespace githubSkill {
764
815
  comments?: undefined;
765
816
  branch?: undefined;
766
817
  path?: undefined;
818
+ since?: undefined;
819
+ until?: undefined;
820
+ page?: undefined;
767
821
  sha?: undefined;
822
+ includePrs?: undefined;
768
823
  ref?: undefined;
769
824
  mergeMethod?: undefined;
770
825
  commitTitle?: undefined;
771
826
  commitMessage?: undefined;
772
827
  state?: undefined;
773
828
  labels?: undefined;
774
- since?: undefined;
775
829
  assignee?: undefined;
776
830
  stateReason?: undefined;
777
831
  mode?: undefined;
@@ -822,7 +876,11 @@ export namespace githubSkill {
822
876
  comments?: undefined;
823
877
  branch?: undefined;
824
878
  path?: undefined;
879
+ since?: undefined;
880
+ until?: undefined;
881
+ page?: undefined;
825
882
  sha?: undefined;
883
+ includePrs?: undefined;
826
884
  ref?: undefined;
827
885
  head?: undefined;
828
886
  base?: undefined;
@@ -830,7 +888,6 @@ export namespace githubSkill {
830
888
  draft?: undefined;
831
889
  state?: undefined;
832
890
  labels?: undefined;
833
- since?: undefined;
834
891
  assignee?: undefined;
835
892
  stateReason?: undefined;
836
893
  mode?: undefined;
@@ -872,7 +929,11 @@ export namespace githubSkill {
872
929
  comments?: undefined;
873
930
  branch?: undefined;
874
931
  path?: undefined;
932
+ since?: undefined;
933
+ until?: undefined;
934
+ page?: undefined;
875
935
  sha?: undefined;
936
+ includePrs?: undefined;
876
937
  ref?: undefined;
877
938
  head?: undefined;
878
939
  base?: undefined;
@@ -882,7 +943,6 @@ export namespace githubSkill {
882
943
  commitMessage?: undefined;
883
944
  state?: undefined;
884
945
  labels?: undefined;
885
- since?: undefined;
886
946
  assignee?: undefined;
887
947
  stateReason?: undefined;
888
948
  mode?: undefined;
@@ -948,7 +1008,10 @@ export namespace githubSkill {
948
1008
  comments?: undefined;
949
1009
  branch?: undefined;
950
1010
  path?: undefined;
1011
+ until?: undefined;
1012
+ page?: undefined;
951
1013
  sha?: undefined;
1014
+ includePrs?: undefined;
952
1015
  ref?: undefined;
953
1016
  head?: undefined;
954
1017
  base?: undefined;
@@ -996,7 +1059,11 @@ export namespace githubSkill {
996
1059
  comments?: undefined;
997
1060
  branch?: undefined;
998
1061
  path?: undefined;
1062
+ since?: undefined;
1063
+ until?: undefined;
1064
+ page?: undefined;
999
1065
  sha?: undefined;
1066
+ includePrs?: undefined;
1000
1067
  ref?: undefined;
1001
1068
  head?: undefined;
1002
1069
  base?: undefined;
@@ -1007,7 +1074,6 @@ export namespace githubSkill {
1007
1074
  commitMessage?: undefined;
1008
1075
  state?: undefined;
1009
1076
  labels?: undefined;
1010
- since?: undefined;
1011
1077
  assignee?: undefined;
1012
1078
  stateReason?: undefined;
1013
1079
  mode?: undefined;
@@ -1050,7 +1116,11 @@ export namespace githubSkill {
1050
1116
  comments?: undefined;
1051
1117
  branch?: undefined;
1052
1118
  path?: undefined;
1119
+ since?: undefined;
1120
+ until?: undefined;
1121
+ page?: undefined;
1053
1122
  sha?: undefined;
1123
+ includePrs?: undefined;
1054
1124
  ref?: undefined;
1055
1125
  head?: undefined;
1056
1126
  base?: undefined;
@@ -1061,7 +1131,6 @@ export namespace githubSkill {
1061
1131
  commitMessage?: undefined;
1062
1132
  state?: undefined;
1063
1133
  labels?: undefined;
1064
- since?: undefined;
1065
1134
  assignee?: undefined;
1066
1135
  mode?: undefined;
1067
1136
  };
@@ -1110,7 +1179,11 @@ export namespace githubSkill {
1110
1179
  comments?: undefined;
1111
1180
  branch?: undefined;
1112
1181
  path?: undefined;
1182
+ since?: undefined;
1183
+ until?: undefined;
1184
+ page?: undefined;
1113
1185
  sha?: undefined;
1186
+ includePrs?: undefined;
1114
1187
  ref?: undefined;
1115
1188
  head?: undefined;
1116
1189
  base?: undefined;
@@ -1120,7 +1193,6 @@ export namespace githubSkill {
1120
1193
  commitTitle?: undefined;
1121
1194
  commitMessage?: undefined;
1122
1195
  state?: undefined;
1123
- since?: undefined;
1124
1196
  assignee?: undefined;
1125
1197
  stateReason?: undefined;
1126
1198
  };
package/dist/github.js CHANGED
@@ -1,4 +1,4 @@
1
- import{existsSync as E}from"fs";import{fileURLToPath as G}from"url";import{dirname as I,resolve as J}from"path";import{resolveIntegrationToken as T}from"@zibby/core/backend-client.js";var A=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),x=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});import{spawn as U,execSync as D}from"child_process";import{existsSync as F,mkdirSync as B,readdirSync as z,statSync as K,readFileSync as W}from"fs";import{resolve as V,join as Y,basename as Z}from"path";function P(b,a,t,i,s="clone"){try{b(`git -C "${a}" remote set-url origin "${t}"`,{stdio:"pipe"})}catch(e){let r=String(e?.message||e);i&&(r=r.split(i).join("***")),console.error(`[${s}] WARNING: failed to strip token from .git/config: ${r}`)}}function C(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let b=I(G(import.meta.url)),a=J(b,"..","bin","mcp-skill.mjs");return E(a)?a:null}async function u(b,a={}){let{token:t}=await T("github"),i=b.startsWith("https://")?b:`https://api.github.com${b}`,s={Authorization:`Bearer ${t}`,Accept:a.accept||"application/vnd.github.v3+json","User-Agent":"Zibby-App",...a.body?{"Content-Type":"application/json"}:{}},e=await fetch(i,{method:a.method||"GET",headers:s,body:a.body?JSON.stringify(a.body):void 0});if(!e.ok){let r=await e.text().catch(()=>"");throw new Error(`GitHub API ${e.status}: ${r.slice(0,300)}`)}return a.raw?e.text():e.json()}var oe={id:"github",serverName:"github",allowedTools:["mcp__github__*"],requiresIntegration:A.GITHUB,envKeys:["GITHUB_TOKEN"],description:"GitHub \u2014 issues, PRs, commits, code search, file reading",promptFragment:`## GitHub (connected)
1
+ import{existsSync as E}from"fs";import{fileURLToPath as I}from"url";import{dirname as G,resolve as C}from"path";import{resolveIntegrationToken as T}from"@zibby/core/backend-client.js";var A=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),x=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});import{spawn as U,execSync as M}from"child_process";import{existsSync as F,mkdirSync as B,readdirSync as z,statSync as K,readFileSync as W}from"fs";import{resolve as V,join as Y,basename as Z}from"path";function P(b,a,t,i,n="clone"){try{b(`git -C "${a}" remote set-url origin "${t}"`,{stdio:"pipe"})}catch(e){let r=String(e?.message||e);i&&(r=r.split(i).join("***")),console.error(`[${n}] WARNING: failed to strip token from .git/config: ${r}`)}}function J(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let b=G(I(import.meta.url)),a=C(b,"..","bin","mcp-skill.mjs");return E(a)?a:null}async function d(b,a={}){let{token:t}=await T("github"),i=b.startsWith("https://")?b:`https://api.github.com${b}`,n={Authorization:`Bearer ${t}`,Accept:a.accept||"application/vnd.github.v3+json","User-Agent":"Zibby-App",...a.body?{"Content-Type":"application/json"}:{}},e=await fetch(i,{method:a.method||"GET",headers:n,body:a.body?JSON.stringify(a.body):void 0});if(!e.ok){let r=await e.text().catch(()=>"");throw new Error(`GitHub API ${e.status}: ${r.slice(0,300)}`)}return a.raw?e.text():e.json()}var oe={id:"github",serverName:"github",allowedTools:["mcp__github__*"],requiresIntegration:A.GITHUB,envKeys:["GITHUB_TOKEN"],description:"GitHub \u2014 issues, PRs, commits, code search, file reading",promptFragment:`## GitHub (connected)
2
2
  You have access to the user's GitHub repositories. Available tools:
3
3
 
4
4
  ### Discovery
@@ -41,6 +41,6 @@ When user says "check out repo-name" or "clone repo-name":
41
41
  3. STOP. Do not offer to inspect files or ask what to do next.
42
42
 
43
43
  When user just wants to "look at" or "read" files (not clone):
44
- - Use github_get_file to read individual files via API`,resolve(){let b=C();if(!b)return{command:null,args:[],env:{},description:this.description};let a={};for(let t of this.envKeys)process.env[t]&&(a[t]=process.env[t]);return{type:"stdio",command:"node",args:[b,"../dist/github.js","githubSkill"],env:a,description:this.description,alwaysLoad:!0}},async handleToolCall(b,a){try{switch(b){case"github_search_issues":{let t=a.query;if(!t)return JSON.stringify({error:"query is required"});let i=await u(`/search/issues?q=${encodeURIComponent(t)}&per_page=${a.limit||20}`),s=(i.items||[]).map(e=>({number:e.number,title:e.title,state:e.state,repo:e.repository_url?.split("/").slice(-2).join("/"),url:e.html_url,user:e.user?.login,isPR:!!e.pull_request,labels:(e.labels||[]).map(r=>r.name),createdAt:e.created_at}));return JSON.stringify({total:i.total_count,items:s})}case"github_search_code":{let t=a.query;if(!t)return JSON.stringify({error:"query is required"});let i=a.repo?`+repo:${a.repo}`:"",s=a.language?`+language:${a.language}`:"",e=await u(`/search/code?q=${encodeURIComponent(t)}${i}${s}&per_page=${a.limit||15}`),r=(e.items||[]).map(n=>({name:n.name,path:n.path,repo:n.repository?.full_name,url:n.html_url,score:n.score}));return JSON.stringify({total:e.total_count,items:r})}case"github_get_pr":{let{owner:t,repo:i,number:s}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/pulls/${s}`);return JSON.stringify({number:e.number,title:e.title,state:e.state,merged:e.merged,body:e.body?.slice(0,5e3),user:e.user?.login,branch:e.head?.ref,headSha:e.head?.sha,base:e.base?.ref,changedFiles:e.changed_files,additions:e.additions,deletions:e.deletions,createdAt:e.created_at,mergedAt:e.merged_at,url:e.html_url,labels:(e.labels||[]).map(r=>r.name)})}case"github_get_pr_diff":{let{owner:t,repo:i,number:s}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/pulls/${s}`,{accept:"application/vnd.github.v3.diff",raw:!0}),r=e.length>15e3;return JSON.stringify({number:s,diff:r?e.slice(0,15e3):e,truncated:r,totalLength:e.length})}case"github_list_pr_files":{let{owner:t,repo:i,number:s}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/pulls/${s}/files?per_page=100`);return JSON.stringify({total:e.length,files:e.map(r=>({filename:r.filename,status:r.status,additions:r.additions,deletions:r.deletions,patch:r.patch?.slice(0,3e3)}))})}case"github_list_pr_comments":{let{owner:t,repo:i,number:s}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/pulls/${s}/comments?per_page=50`),r=await u(`/repos/${t}/${i}/issues/${s}/comments?per_page=50`),n=[...e.map(o=>({type:"review",user:o.user?.login,body:o.body?.slice(0,1e3),path:o.path,line:o.line,createdAt:o.created_at})),...r.map(o=>({type:"issue",user:o.user?.login,body:o.body?.slice(0,1e3),createdAt:o.created_at}))].sort((o,d)=>new Date(o.createdAt)-new Date(d.createdAt));return JSON.stringify({total:n.length,comments:n})}case"github_get_review_thread":{let{owner:t,repo:i,number:s,commentId:e}=a||{};if(!t||!i||!s||!e)return JSON.stringify({error:"owner, repo, number, and commentId are required"});let r=await u(`/repos/${t}/${i}/pulls/comments/${e}`),n=r.in_reply_to_id||r.id,o=[];try{o=await u(`/repos/${t}/${i}/pulls/${s}/comments?per_page=100`)}catch{o=[r]}(!Array.isArray(o)||o.length===0)&&(o=[r]);let d=o.filter(c=>c.id===n||c.in_reply_to_id===n).sort((c,y)=>new Date(c.created_at)-new Date(y.created_at)),l=d.length?d:[r],p=l.find(c=>c.id===n)||l[0];return JSON.stringify({rootCommentId:n,path:p.path,line:p.line??p.original_line??null,side:p.side||"RIGHT",diffHunk:typeof p.diff_hunk=="string"?p.diff_hunk.slice(0,3e3):null,commitId:p.commit_id||p.original_commit_id||null,notes:l.map(c=>({id:c.id,user:c.user?.login,body:(c.body||"").slice(0,4e3),createdAt:c.created_at,isRoot:c.id===n,url:c.html_url}))})}case"github_reply_review_thread":{let{owner:t,repo:i,number:s,commentId:e,body:r}=a||{};if(!t||!i||!s||!e||!r)return JSON.stringify({error:"owner, repo, number, commentId, and body are required"});let n=await u(`/repos/${t}/${i}/pulls/${s}/comments/${e}/replies`,{method:"POST",body:{body:String(r)}});return JSON.stringify({ok:!0,id:n.id,url:n.html_url,inReplyTo:n.in_reply_to_id})}case"github_reply_issue_comment":{let{owner:t,repo:i,number:s,body:e}=a||{};if(!t||!i||!s||!e)return JSON.stringify({error:"owner, repo, number, and body are required"});let r=await u(`/repos/${t}/${i}/issues/${s}/comments`,{method:"POST",body:{body:String(e)}});return JSON.stringify({ok:!0,id:r.id,url:r.html_url})}case"github_create_review":{let{owner:t,repo:i,number:s,body:e,event:r,comments:n}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let o=(r||"COMMENT").toUpperCase();if(!["COMMENT","APPROVE","REQUEST_CHANGES"].includes(o))return JSON.stringify({error:`event must be COMMENT, APPROVE, or REQUEST_CHANGES (got ${r})`});let d=Array.isArray(n)?n.filter(c=>c&&c.path&&c.body&&(c.line!=null||c.position!=null)).map(c=>{let y={path:c.path,body:String(c.body)};return c.line!=null?(y.line=Number(c.line),y.side=c.side==="LEFT"?"LEFT":"RIGHT"):y.position=Number(c.position),y}):[];if(o!=="APPROVE"&&!e&&d.length===0)return JSON.stringify({error:"a COMMENT or REQUEST_CHANGES review needs a body and/or inline comments"});let l={event:o};e&&(l.body=String(e)),d.length>0&&(l.comments=d);let p=await u(`/repos/${t}/${i}/pulls/${s}/reviews`,{method:"POST",body:l});return JSON.stringify({ok:!0,id:p.id,state:p.state,event:o,commentsPosted:d.length,url:p.html_url})}case"github_list_commits":{let{owner:t,repo:i,branch:s,path:e,limit:r}=a;if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let n=`/repos/${t}/${i}/commits?per_page=${r||20}`;s&&(n+=`&sha=${encodeURIComponent(s)}`),e&&(n+=`&path=${encodeURIComponent(e)}`);let o=await u(n);return JSON.stringify({total:o.length,commits:o.map(d=>({sha:d.sha?.slice(0,8),fullSha:d.sha,message:d.commit?.message?.slice(0,300),author:d.commit?.author?.name,date:d.commit?.author?.date,url:d.html_url}))})}case"github_get_commit":{let{owner:t,repo:i,sha:s}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and sha are required"});let e=await u(`/repos/${t}/${i}/commits/${s}`);return JSON.stringify({sha:e.sha?.slice(0,8),message:e.commit?.message,author:e.commit?.author?.name,date:e.commit?.author?.date,stats:e.stats,files:(e.files||[]).map(r=>({filename:r.filename,status:r.status,additions:r.additions,deletions:r.deletions,patch:r.patch?.slice(0,3e3)}))})}case"github_get_file":{let{owner:t,repo:i,path:s,ref:e}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and path are required"});let r=`/repos/${t}/${i}/contents/${encodeURIComponent(s)}`;e&&(r+=`?ref=${encodeURIComponent(e)}`);let n=await u(r);if(n.type!=="file")return Array.isArray(n)?JSON.stringify({type:"directory",path:s,entries:n.map(l=>({name:l.name,type:l.type,size:l.size,path:l.path}))}):JSON.stringify({error:`Not a file: ${n.type}`});let o=Buffer.from(n.content||"","base64").toString("utf-8"),d=o.length>2e4;return JSON.stringify({path:n.path,size:n.size,sha:n.sha?.slice(0,8),content:d?o.slice(0,2e4):o,truncated:d})}case"github_get_user":try{let t=await u("/installation/repositories?per_page=1");if(t.repositories&&t.repositories.length>0){let i=t.repositories[0],s=i.owner.login,e=i.owner.type,r=e==="Organization"?`/orgs/${s}`:`/users/${s}`,n=await u(r);return JSON.stringify({login:n.login,name:n.name||n.login,avatar:n.avatar_url,bio:n.bio||n.description,type:e,isOrg:e==="Organization",publicRepos:n.public_repos,message:"Showing GitHub App installation owner (GitHub Apps cannot access /user endpoint)"})}return JSON.stringify({error:"No repositories accessible to this GitHub App installation"})}catch(t){return JSON.stringify({error:`GitHub App cannot access /user endpoint. Use github_list_repos instead. (${t.message})`})}case"github_list_orgs":try{let i=(await u("/installation/repositories?per_page=100")).repositories||[],s=new Map;for(let r of i)r.owner.type==="Organization"&&(s.has(r.owner.login)||s.set(r.owner.login,{login:r.owner.login,description:null,url:r.owner.url}));let e=Array.from(s.values());return JSON.stringify({count:e.length,orgs:e,message:"Extracted from accessible repositories (GitHub Apps cannot access /user/orgs directly)"})}catch(t){return JSON.stringify({error:`GitHub App cannot list orgs via /user/orgs. Error: ${t.message}`})}case"github_clone":{let g=function(w){let m=w.replace(/^~(?=$|\/|\\)/,y);return n(m)},{owner:t,repo:i,destination:s}=a;if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let{execSync:e}=await import("child_process"),{join:r,resolve:n}=await import("path"),{existsSync:o,mkdirSync:d}=await import("fs"),{homedir:l,platform:p}=await import("os"),{token:c}=await T("github"),y=l(),_=s?g(s):r(y,"zibby-repos"),f=r(_,i);if(d(_,{recursive:!0}),o(f))return JSON.stringify({error:`Directory ${f} already exists. Remove it first or use a different destination.`,existingPath:f});let R=`https://x-access-token:${c}@github.com/${t}/${i}.git`;try{e(`git clone ${R} "${f}"`,{stdio:"pipe"});let w=`https://github.com/${t}/${i}.git`;P(e,f,w,c,"github_clone");let m=p()==="win32",h;return m?h=e(`dir "${f}"`,{encoding:"utf-8",shell:"cmd.exe"}):h=e(`ls -la "${f}"`,{encoding:"utf-8"}),JSON.stringify({success:!0,path:f,message:`Cloned ${t}/${i} to ${f}`,contents:h.split(`
44
+ - Use github_get_file to read individual files via API`,resolve(){let b=J();if(!b)return{command:null,args:[],env:{},description:this.description};let a={};for(let t of this.envKeys)process.env[t]&&(a[t]=process.env[t]);return{type:"stdio",command:"node",args:[b,"../dist/github.js","githubSkill"],env:a,description:this.description,alwaysLoad:!0}},async handleToolCall(b,a){try{switch(b){case"github_search_issues":{let t=a.query;if(!t)return JSON.stringify({error:"query is required"});let i=await d(`/search/issues?q=${encodeURIComponent(t)}&per_page=${a.limit||20}`),n=(i.items||[]).map(e=>({number:e.number,title:e.title,state:e.state,repo:e.repository_url?.split("/").slice(-2).join("/"),url:e.html_url,user:e.user?.login,isPR:!!e.pull_request,labels:(e.labels||[]).map(r=>r.name),createdAt:e.created_at}));return JSON.stringify({total:i.total_count,items:n})}case"github_search_code":{let t=a.query;if(!t)return JSON.stringify({error:"query is required"});let i=a.repo?`+repo:${a.repo}`:"",n=a.language?`+language:${a.language}`:"",e=await d(`/search/code?q=${encodeURIComponent(t)}${i}${n}&per_page=${a.limit||15}`),r=(e.items||[]).map(s=>({name:s.name,path:s.path,repo:s.repository?.full_name,url:s.html_url,score:s.score}));return JSON.stringify({total:e.total_count,items:r})}case"github_get_pr":{let{owner:t,repo:i,number:n}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/pulls/${n}`);return JSON.stringify({number:e.number,title:e.title,state:e.state,merged:e.merged,body:e.body?.slice(0,5e3),user:e.user?.login,branch:e.head?.ref,headSha:e.head?.sha,base:e.base?.ref,changedFiles:e.changed_files,additions:e.additions,deletions:e.deletions,createdAt:e.created_at,mergedAt:e.merged_at,url:e.html_url,labels:(e.labels||[]).map(r=>r.name)})}case"github_get_pr_diff":{let{owner:t,repo:i,number:n}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/pulls/${n}`,{accept:"application/vnd.github.v3.diff",raw:!0}),r=e.length>15e3;return JSON.stringify({number:n,diff:r?e.slice(0,15e3):e,truncated:r,totalLength:e.length})}case"github_list_pr_files":{let{owner:t,repo:i,number:n}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/pulls/${n}/files?per_page=100`);return JSON.stringify({total:e.length,files:e.map(r=>({filename:r.filename,status:r.status,additions:r.additions,deletions:r.deletions,patch:r.patch?.slice(0,3e3)}))})}case"github_list_pr_comments":{let{owner:t,repo:i,number:n}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/pulls/${n}/comments?per_page=50`),r=await d(`/repos/${t}/${i}/issues/${n}/comments?per_page=50`),s=[...e.map(o=>({type:"review",user:o.user?.login,body:o.body?.slice(0,1e3),path:o.path,line:o.line,createdAt:o.created_at})),...r.map(o=>({type:"issue",user:o.user?.login,body:o.body?.slice(0,1e3),createdAt:o.created_at}))].sort((o,u)=>new Date(o.createdAt)-new Date(u.createdAt));return JSON.stringify({total:s.length,comments:s})}case"github_get_review_thread":{let{owner:t,repo:i,number:n,commentId:e}=a||{};if(!t||!i||!n||!e)return JSON.stringify({error:"owner, repo, number, and commentId are required"});let r=await d(`/repos/${t}/${i}/pulls/comments/${e}`),s=r.in_reply_to_id||r.id,o=[];try{o=await d(`/repos/${t}/${i}/pulls/${n}/comments?per_page=100`)}catch{o=[r]}(!Array.isArray(o)||o.length===0)&&(o=[r]);let u=o.filter(c=>c.id===s||c.in_reply_to_id===s).sort((c,g)=>new Date(c.created_at)-new Date(g.created_at)),l=u.length?u:[r],p=l.find(c=>c.id===s)||l[0];return JSON.stringify({rootCommentId:s,path:p.path,line:p.line??p.original_line??null,side:p.side||"RIGHT",diffHunk:typeof p.diff_hunk=="string"?p.diff_hunk.slice(0,3e3):null,commitId:p.commit_id||p.original_commit_id||null,notes:l.map(c=>({id:c.id,user:c.user?.login,body:(c.body||"").slice(0,4e3),createdAt:c.created_at,isRoot:c.id===s,url:c.html_url}))})}case"github_reply_review_thread":{let{owner:t,repo:i,number:n,commentId:e,body:r}=a||{};if(!t||!i||!n||!e||!r)return JSON.stringify({error:"owner, repo, number, commentId, and body are required"});let s=await d(`/repos/${t}/${i}/pulls/${n}/comments/${e}/replies`,{method:"POST",body:{body:String(r)}});return JSON.stringify({ok:!0,id:s.id,url:s.html_url,inReplyTo:s.in_reply_to_id})}case"github_reply_issue_comment":{let{owner:t,repo:i,number:n,body:e}=a||{};if(!t||!i||!n||!e)return JSON.stringify({error:"owner, repo, number, and body are required"});let r=await d(`/repos/${t}/${i}/issues/${n}/comments`,{method:"POST",body:{body:String(e)}});return JSON.stringify({ok:!0,id:r.id,url:r.html_url})}case"github_create_review":{let{owner:t,repo:i,number:n,body:e,event:r,comments:s}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let o=(r||"COMMENT").toUpperCase();if(!["COMMENT","APPROVE","REQUEST_CHANGES"].includes(o))return JSON.stringify({error:`event must be COMMENT, APPROVE, or REQUEST_CHANGES (got ${r})`});let u=Array.isArray(s)?s.filter(c=>c&&c.path&&c.body&&(c.line!=null||c.position!=null)).map(c=>{let g={path:c.path,body:String(c.body)};return c.line!=null?(g.line=Number(c.line),g.side=c.side==="LEFT"?"LEFT":"RIGHT"):g.position=Number(c.position),g}):[];if(o!=="APPROVE"&&!e&&u.length===0)return JSON.stringify({error:"a COMMENT or REQUEST_CHANGES review needs a body and/or inline comments"});let l={event:o};e&&(l.body=String(e)),u.length>0&&(l.comments=u);let p=await d(`/repos/${t}/${i}/pulls/${n}/reviews`,{method:"POST",body:l});return JSON.stringify({ok:!0,id:p.id,state:p.state,event:o,commentsPosted:u.length,url:p.html_url})}case"github_list_commits":{let{owner:t,repo:i,branch:n,path:e,limit:r,since:s,until:o,page:u}=a;if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let l=Math.min(Number(r)||20,100),p=`/repos/${t}/${i}/commits?per_page=${l}&page=${Number(u)||1}`;n&&(p+=`&sha=${encodeURIComponent(n)}`),e&&(p+=`&path=${encodeURIComponent(e)}`),s&&(p+=`&since=${encodeURIComponent(s)}`),o&&(p+=`&until=${encodeURIComponent(o)}`);let c=await d(p);return JSON.stringify({total:c.length,page:Number(u)||1,hasMore:c.length>=l,commits:c.map(g=>({sha:g.sha?.slice(0,8),fullSha:g.sha,message:g.commit?.message?.slice(0,300),author:g.commit?.author?.name,authorEmail:g.commit?.author?.email,date:g.commit?.author?.date,url:g.html_url}))})}case"github_get_commit":{let{owner:t,repo:i,sha:n,includePrs:e}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and sha are required"});let r=await d(`/repos/${t}/${i}/commits/${n}`),s;if(e)try{let o=await d(`/repos/${t}/${i}/commits/${n}/pulls`);s=(Array.isArray(o)?o:[]).map(u=>({number:u.number,title:u.title,state:u.state,merged:!!u.merged_at,webUrl:u.html_url}))}catch{s=[]}return JSON.stringify({sha:r.sha?.slice(0,8),message:r.commit?.message,author:r.commit?.author?.name,date:r.commit?.author?.date,stats:r.stats,files:(r.files||[]).map(o=>({filename:o.filename,status:o.status,additions:o.additions,deletions:o.deletions,patch:o.patch?.slice(0,3e3)})),...s?{pullRequests:s}:{}})}case"github_get_file":{let{owner:t,repo:i,path:n,ref:e}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and path are required"});let r=`/repos/${t}/${i}/contents/${encodeURIComponent(n)}`;e&&(r+=`?ref=${encodeURIComponent(e)}`);let s=await d(r);if(s.type!=="file")return Array.isArray(s)?JSON.stringify({type:"directory",path:n,entries:s.map(l=>({name:l.name,type:l.type,size:l.size,path:l.path}))}):JSON.stringify({error:`Not a file: ${s.type}`});let o=Buffer.from(s.content||"","base64").toString("utf-8"),u=o.length>2e4;return JSON.stringify({path:s.path,size:s.size,sha:s.sha?.slice(0,8),content:u?o.slice(0,2e4):o,truncated:u})}case"github_get_user":try{let t=await d("/installation/repositories?per_page=1");if(t.repositories&&t.repositories.length>0){let i=t.repositories[0],n=i.owner.login,e=i.owner.type,r=e==="Organization"?`/orgs/${n}`:`/users/${n}`,s=await d(r);return JSON.stringify({login:s.login,name:s.name||s.login,avatar:s.avatar_url,bio:s.bio||s.description,type:e,isOrg:e==="Organization",publicRepos:s.public_repos,message:"Showing GitHub App installation owner (GitHub Apps cannot access /user endpoint)"})}return JSON.stringify({error:"No repositories accessible to this GitHub App installation"})}catch(t){return JSON.stringify({error:`GitHub App cannot access /user endpoint. Use github_list_repos instead. (${t.message})`})}case"github_list_orgs":try{let i=(await d("/installation/repositories?per_page=100")).repositories||[],n=new Map;for(let r of i)r.owner.type==="Organization"&&(n.has(r.owner.login)||n.set(r.owner.login,{login:r.owner.login,description:null,url:r.owner.url}));let e=Array.from(n.values());return JSON.stringify({count:e.length,orgs:e,message:"Extracted from accessible repositories (GitHub Apps cannot access /user/orgs directly)"})}catch(t){return JSON.stringify({error:`GitHub App cannot list orgs via /user/orgs. Error: ${t.message}`})}case"github_clone":{let h=function(w){let m=w.replace(/^~(?=$|\/|\\)/,g);return s(m)},{owner:t,repo:i,destination:n}=a;if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let{execSync:e}=await import("child_process"),{join:r,resolve:s}=await import("path"),{existsSync:o,mkdirSync:u}=await import("fs"),{homedir:l,platform:p}=await import("os"),{token:c}=await T("github"),g=l(),_=n?h(n):r(g,"zibby-repos"),f=r(_,i);if(u(_,{recursive:!0}),o(f))return JSON.stringify({error:`Directory ${f} already exists. Remove it first or use a different destination.`,existingPath:f});let R=`https://x-access-token:${c}@github.com/${t}/${i}.git`;try{e(`git clone ${R} "${f}"`,{stdio:"pipe"});let w=`https://github.com/${t}/${i}.git`;P(e,f,w,c,"github_clone");let m=p()==="win32",y;return m?y=e(`dir "${f}"`,{encoding:"utf-8",shell:"cmd.exe"}):y=e(`ls -la "${f}"`,{encoding:"utf-8"}),JSON.stringify({success:!0,path:f,message:`Cloned ${t}/${i} to ${f}`,contents:y.split(`
45
45
  `).slice(0,30).join(`
46
- `),instructions:"IMPORTANT: Show the contents field to the user - it contains the directory listing."})}catch(w){let h=String(w.message||w).split(c).join("***").replace(/x-access-token:[^@]*@/g,"x-access-token:***@");return JSON.stringify({error:`Clone failed: ${h}`})}}case"github_search_repos":{let{query:t,limit:i}=a;if(!t)return JSON.stringify({error:"query is required"});let s=await this.handleToolCall("github_list_repos",{limit:200},{}),e=JSON.parse(s);if(e.error)return JSON.stringify(e);let r=t.toLowerCase(),n=e.repos.filter(o=>o.name.toLowerCase().includes(r)||o.fullName.toLowerCase().includes(r)||o.description&&o.description.toLowerCase().includes(r));return JSON.stringify({query:t,count:n.length,repos:n.slice(0,i||20)})}case"github_list_repos":{let{owner:t,type:i,sort:s,direction:e,limit:r,query:n}=a,o=100,d=r||200,l=[],p=m=>({name:m.name,fullName:m.full_name,private:m.private,description:m.description,language:m.language,defaultBranch:m.default_branch,updatedAt:m.updated_at,stars:m.stargazers_count,url:m.html_url,fullPath:m.full_name,webUrl:m.html_url,visibility:m.visibility||(m.private?"private":"public")}),c=m=>{if(!n)return!0;let h=String(n).toLowerCase();return m.name&&m.name.toLowerCase().includes(h)||m.fullName&&m.fullName.toLowerCase().includes(h)||m.description&&m.description.toLowerCase().includes(h)};if(!t){let m=1,h=!0;for(;h&&l.length<d;){let v=`/installation/repositories?per_page=${o}&page=${m}`,O=(await u(v)).repositories||[];if(O.length===0)break;l=l.concat(O),h=O.length===o,m++}let S=l.map(p).filter(c),$=S.slice(0,d),q=S.length>$.length,N=$.filter(v=>v.private).length,k=$.filter(v=>!v.private).length;return JSON.stringify({count:$.length,repos:$,truncated:q,privateCount:N,publicCount:k,message:`Found ${N} private and ${k} public repos`})}let y=await u(`/orgs/${t}`).then(()=>!0).catch(()=>!1),g=1,_=!0;for(;_&&l.length<d;){let m;y?m=`/orgs/${t}/repos?per_page=${o}&page=${g}&type=${i||"all"}&sort=${s||"updated"}&direction=${e||"desc"}`:m=`/users/${t}/repos?per_page=${o}&page=${g}&type=${i||"all"}&sort=${s||"updated"}&direction=${e||"desc"}`;let h=await u(m),S=Array.isArray(h)?h:[];if(S.length===0)break;l=l.concat(S),_=S.length===o,g++}let f=l.map(p).filter(c),R=f.slice(0,d),w=f.length>R.length;return JSON.stringify({count:R.length,repos:R,truncated:w})}case"github_create_pr":{let{owner:t,repo:i,head:s,title:e}=a||{};if(!t||!i||!s||!e)return JSON.stringify({error:"owner, repo, head (source branch), and title are required"});let r=a.base;if(!r)try{r=(await u(`/repos/${t}/${i}`)).default_branch||"main"}catch{r="main"}let n={title:String(e),head:String(s),base:String(r),body:a.body?String(a.body):"",draft:!!a.draft};try{let o=await u(`/repos/${t}/${i}/pulls`,{method:"POST",body:n});return JSON.stringify({success:!0,pr_url:o.html_url,number:o.number,branch:s,base:r,repo:`${t}/${i}`,provider:"github",draft:!!o.draft,state:o.state})}catch(o){let d=String(o.message||o);if(/GitHub API 422/.test(d))return JSON.stringify({success:!1,branch:s,base:r,repo:`${t}/${i}`,provider:"github",skippedReason:d});throw o}}case"github_merge_pr":{let{owner:t,repo:i,number:s}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=a.mergeMethod||"squash";if(!["merge","squash","rebase"].includes(e))return JSON.stringify({error:`mergeMethod must be merge, squash, or rebase (got ${e})`});let r={merge_method:e};a.commitTitle&&(r.commit_title=String(a.commitTitle)),a.commitMessage&&(r.commit_message=String(a.commitMessage));try{let n=await u(`/repos/${t}/${i}/pulls/${s}/merge`,{method:"PUT",body:r});return JSON.stringify({success:!0,merged:!0,sha:n.sha,number:s,provider:"github"})}catch(n){let o=String(n.message||n);if(/GitHub API (405|409|404)/.test(o))return JSON.stringify({success:!1,number:s,provider:"github",skippedReason:o});throw n}}case"github_create_issue":{let{owner:t,repo:i,title:s,body:e}=a;if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and title are required"});let r=await u(`/repos/${t}/${i}/issues`,{method:"POST",body:{title:s,body:e||""}});return JSON.stringify({number:r.number,url:r.html_url,title:r.title})}case"github_list_issues":{let{owner:t,repo:i,state:s,labels:e,since:r,assignee:n,sort:o,direction:d,limit:l}=a||{};if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let p=new URLSearchParams;p.set("state",s||"open"),p.set("per_page",String(l||30)),p.set("sort",o||"updated"),p.set("direction",d||"desc"),e&&p.set("labels",Array.isArray(e)?e.join(","):e),r&&p.set("since",r),n&&p.set("assignee",n);let c=await u(`/repos/${t}/${i}/issues?${p.toString()}`),y=(Array.isArray(c)?c:[]).filter(g=>!g.pull_request).map(g=>({number:g.number,title:g.title,state:g.state,labels:(g.labels||[]).map(_=>typeof _=="string"?_:_.name),assignee:g.assignee?.login||null,assignees:(g.assignees||[]).map(_=>_.login),user:g.user?.login,comments:g.comments,url:g.html_url,createdAt:g.created_at,updatedAt:g.updated_at}));return JSON.stringify({count:y.length,issues:y})}case"github_get_issue":{let{owner:t,repo:i,number:s}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/issues/${s}`);return e.pull_request?JSON.stringify({error:`#${s} is a pull request, not an issue`,isPR:!0}):JSON.stringify({number:e.number,title:e.title,body:e.body||"",state:e.state,stateReason:e.state_reason||null,labels:(e.labels||[]).map(r=>typeof r=="string"?r:r.name),assignee:e.assignee?.login||null,assignees:(e.assignees||[]).map(r=>r.login),user:e.user?.login,milestone:e.milestone?.title||null,comments:e.comments,url:e.html_url,createdAt:e.created_at,updatedAt:e.updated_at,closedAt:e.closed_at})}case"github_get_issue_comments":{let{owner:t,repo:i,number:s,limit:e}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let r=await u(`/repos/${t}/${i}/issues/${s}/comments?per_page=${e||100}`),n=(Array.isArray(r)?r:[]).map(o=>({id:o.id,user:o.user?.login,body:o.body||"",createdAt:o.created_at,updatedAt:o.updated_at,url:o.html_url}));return JSON.stringify({count:n.length,comments:n})}case"github_add_issue_comment":{let{owner:t,repo:i,number:s,body:e}=a||{};if(!t||!i||!s||!e)return JSON.stringify({error:"owner, repo, number, and body are required"});let r=await u(`/repos/${t}/${i}/issues/${s}/comments`,{method:"POST",body:{body:e}});return JSON.stringify({ok:!0,id:r.id,url:r.html_url})}case"github_close_issue":{let{owner:t,repo:i,number:s,stateReason:e}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let r={state:"closed"};e&&(r.state_reason=e);let n=await u(`/repos/${t}/${i}/issues/${s}`,{method:"PATCH",body:r});return JSON.stringify({ok:!0,number:n.number,state:n.state,stateReason:n.state_reason||null,url:n.html_url})}case"github_reopen_issue":{let{owner:t,repo:i,number:s}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let e=await u(`/repos/${t}/${i}/issues/${s}`,{method:"PATCH",body:{state:"open"}});return JSON.stringify({ok:!0,number:e.number,state:e.state,url:e.html_url})}case"github_label_issue":{let{owner:t,repo:i,number:s,labels:e,mode:r}=a||{};if(!t||!i||!s)return JSON.stringify({error:"owner, repo, and number are required"});let n=Array.isArray(e)?e:e?[e]:[];if(!n.length)return JSON.stringify({error:"labels (string or array) is required"});let o=r||"add";if(o==="set"){let l=await u(`/repos/${t}/${i}/issues/${s}`,{method:"PATCH",body:{labels:n}});return JSON.stringify({ok:!0,number:l.number,labels:(l.labels||[]).map(p=>typeof p=="string"?p:p.name)})}if(o==="remove"){for(let p of n)await u(`/repos/${t}/${i}/issues/${s}/labels/${encodeURIComponent(p)}`,{method:"DELETE"});let l=await u(`/repos/${t}/${i}/issues/${s}`);return JSON.stringify({ok:!0,number:l.number,labels:(l.labels||[]).map(p=>typeof p=="string"?p:p.name)})}let d=await u(`/repos/${t}/${i}/issues/${s}/labels`,{method:"POST",body:{labels:n}});return JSON.stringify({ok:!0,number:s,labels:(Array.isArray(d)?d:[]).map(l=>typeof l=="string"?l:l.name)})}default:return JSON.stringify({error:`Unknown tool: ${b}`})}}catch(t){return JSON.stringify({error:t.message})}},tools:[{name:"github_get_user",description:"Get the authenticated GitHub user profile and their organizations",input_schema:{type:"object",properties:{}}},{name:"github_list_orgs",description:"List GitHub organizations the authenticated user belongs to",input_schema:{type:"object",properties:{}}},{name:"github_list_repos",description:"List the repositories this token/installation can access (omit owner) \u2014 or a specific user/org's repos (pass owner). Use this to discover a RELATED repo worth cloning when a change's correctness depends on another accessible repo. Each repo carries a normalized { fullPath, name, webUrl, defaultBranch, visibility } shape (identical to gitlab_list_projects) alongside legacy fields, plus a truncated flag.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Org or user login. Omit to list every repo your token/installation can access."},query:{type:"string",description:"Optional term matched against repo name/full-name/description"},type:{type:"string",enum:["all","public","private","forks","sources","member"],description:"Filter by type (default: all)"},sort:{type:"string",enum:["created","updated","pushed","full_name"],description:"Sort field (default: updated)"},direction:{type:"string",enum:["asc","desc"],description:"Sort direction (default: desc)"},limit:{type:"number",description:"Max repos to return (default: 200, hard-capped at the fetch ceiling)"}}}},{name:"github_clone",description:'Clone a GitHub repository to the local filesystem. Use when user says "check out" or "clone" a repo.',input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner (user or org name)"},repo:{type:"string",description:"Repository name"},destination:{type:"string",description:"Destination directory. Accepts absolute paths, ~-prefixed paths, or relative names. Defaults to ~/zibby-repos/<repo>."}},required:["owner","repo"]}},{name:"github_search_repos",description:"Search accessible repositories by name or description. Use this when the user asks to find a specific repo.",input_schema:{type:"object",properties:{query:{type:"string",description:'Search term to match against repo name or description (e.g., "electron", "my-app")'},limit:{type:"number",description:"Max results (default: 20)"}},required:["query"]}},{name:"github_search_issues",description:"Search GitHub issues and pull requests",input_schema:{type:"object",properties:{query:{type:"string",description:'GitHub search query (e.g. "SCRUM-123", "login bug repo:org/app")'},limit:{type:"number",description:"Max results (default: 20)"}},required:["query"]}},{name:"github_search_code",description:"Search code across GitHub repositories by keyword",input_schema:{type:"object",properties:{query:{type:"string",description:'Code search query (e.g. "handleLogin", "class AuthService")'},repo:{type:"string",description:'Scope to a specific repo (e.g. "org/app"). Optional.'},language:{type:"string",description:'Filter by language (e.g. "javascript", "python"). Optional.'},limit:{type:"number",description:"Max results (default: 15)"}},required:["query"]}},{name:"github_get_pr",description:"Get details of a pull request \u2014 title, description, branch, stats",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_get_pr_diff",description:"Get the unified diff of a pull request \u2014 the actual code changes",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_list_pr_files",description:"List files changed in a PR with per-file patches",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_list_pr_comments",description:"Get all review and issue comments on a PR",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_get_review_thread",description:"Read a PR review-comment THREAD given any comment id in it: the root review comment + all its replies, plus the anchored diff context (file, line, the original diff hunk). Use this to understand a human's reply to a previous review comment before replying in-thread.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},commentId:{type:"number",description:"Any review-comment id in the thread (the root or any reply)"}},required:["owner","repo","number","commentId"]}},{name:"github_reply_review_thread",description:"Reply IN-THREAD to an existing PR review-comment thread (a conversational reply nested under the thread the human commented on \u2014 NOT a fresh full review). Pass any comment id in the thread.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},commentId:{type:"number",description:"Any review-comment id in the thread to reply to"},body:{type:"string",description:"The reply text (markdown)"}},required:["owner","repo","number","commentId","body"]}},{name:"github_reply_issue_comment",description:"Post a reply on a PR's top-level conversation (a new issue comment on the PR). Use when the human replied to a non-inline/summary comment rather than an inline review thread. Quote or @-mention for context since issue comments are not threaded.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},body:{type:"string",description:"The reply text (markdown)"}},required:["owner","repo","number","body"]}},{name:"github_create_review",description:"Post a review on a pull request: a summary body plus optional inline comments anchored to file/line, with an event (COMMENT, APPROVE, or REQUEST_CHANGES). Use this to deliver a code review back to the PR.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},body:{type:"string",description:"The review summary (markdown). Shown as the top-level review comment."},event:{type:"string",enum:["COMMENT","APPROVE","REQUEST_CHANGES"],description:"Review verdict. Default COMMENT (no approval state). Use REQUEST_CHANGES for blocking issues."},comments:{type:"array",description:"Optional inline comments, each anchored to a changed line.",items:{type:"object",properties:{path:{type:"string",description:"File path as it appears in the diff"},line:{type:"number",description:"Line number in the file's NEW version (the right side of the diff)"},side:{type:"string",enum:["LEFT","RIGHT"],description:"RIGHT (new) or LEFT (old). Default RIGHT."},body:{type:"string",description:"The inline comment text (markdown)"}},required:["path","line","body"]}}},required:["owner","repo","number"]}},{name:"github_list_commits",description:"List recent commits on a branch, optionally filtered by file path",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},branch:{type:"string",description:"Branch name (default: repo default branch)"},path:{type:"string",description:"Filter commits touching this file path"},limit:{type:"number",description:"Max commits (default: 20)"}},required:["owner","repo"]}},{name:"github_get_commit",description:"Get details of a specific commit \u2014 message, stats, file diffs",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},sha:{type:"string",description:"Commit SHA (full or short)"}},required:["owner","repo","sha"]}},{name:"github_get_file",description:"Read a file (or list a directory) from a GitHub repo. Works on any branch/ref.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},path:{type:"string",description:'File or directory path (e.g. "src/auth/login.ts")'},ref:{type:"string",description:"Branch, tag, or commit SHA (default: repo default branch)"}},required:["owner","repo","path"]}},{name:"github_create_pr",description:"Open a pull request on GitHub (POST /repos/{owner}/{repo}/pulls). The head (source) branch must already be pushed. Returns the REAL pr_url from GitHub \u2014 never fabricate a PR url. Expected business outcomes (no commits between base and head, a PR already exists for this branch, base==head, missing head) return { success:false, skippedReason } rather than erroring.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},head:{type:"string",description:'Source branch to merge FROM (must already be pushed). For a cross-fork PR use "fork-owner:branch".'},base:{type:"string",description:"Target branch to merge INTO (default: the repo's default branch)"},title:{type:"string",description:"PR title"},body:{type:"string",description:"PR description (markdown)"},draft:{type:"boolean",description:"Open as a draft PR (default: false)"}},required:["owner","repo","head","title"]}},{name:"github_merge_pr",description:"Merge a pull request on GitHub (PUT /repos/{owner}/{repo}/pulls/{number}/merge). mergeMethod is merge | squash | rebase (default squash). Returns { success:true, merged:true, sha } with the REAL merge SHA from GitHub. Expected non-mergeable outcomes (405 = draft / failing checks / branch protection, 409 = head sha moved / conflict, 404 = not found) return { success:false, skippedReason } rather than erroring.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number to merge"},mergeMethod:{type:"string",enum:["merge","squash","rebase"],description:"How to merge (default: squash)"},commitTitle:{type:"string",description:"Title for the merge/squash commit (optional)"},commitMessage:{type:"string",description:"Body for the merge/squash commit (optional)"}},required:["owner","repo","number"]}},{name:"github_create_issue",description:"Create a GitHub issue",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},title:{type:"string",description:"Issue title"},body:{type:"string",description:"Issue body (markdown)"}},required:["owner","repo","title"]}},{name:"github_list_issues",description:"List issues in a repo (excludes pull requests). Filter by state, labels, and an updated-since cursor for polling.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},state:{type:"string",enum:["open","closed","all"],description:"Filter by state (default: open)"},labels:{type:"array",items:{type:"string"},description:"Only issues carrying ALL of these labels"},since:{type:"string",description:"ISO-8601 timestamp; only issues updated at/after this (polling cursor)"},assignee:{type:"string",description:'Filter by assignee login, "none", or "*"'},sort:{type:"string",enum:["created","updated","comments"],description:"Sort field (default: updated)"},direction:{type:"string",enum:["asc","desc"],description:"Sort direction (default: desc)"},limit:{type:"number",description:"Max issues (default: 30, max 100 per page)"}},required:["owner","repo"]}},{name:"github_get_issue",description:"Get a single GitHub issue with full detail (title, body, state, labels, assignee, url)",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"}},required:["owner","repo","number"]}},{name:"github_get_issue_comments",description:"Get the comment thread on a GitHub issue (chronological)",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},limit:{type:"number",description:"Max comments (default: 100)"}},required:["owner","repo","number"]}},{name:"github_add_issue_comment",description:"Add a comment to a GitHub issue. Also the way to record a PR link on an issue (post a markdown link).",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},body:{type:"string",description:"Comment body (markdown)"}},required:["owner","repo","number","body"]}},{name:"github_close_issue",description:"Close a GitHub issue. Optionally set the close reason (completed or not_planned).",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},stateReason:{type:"string",enum:["completed","not_planned"],description:"Why the issue was closed (optional)"}},required:["owner","repo","number"]}},{name:"github_reopen_issue",description:"Reopen a closed GitHub issue",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"}},required:["owner","repo","number"]}},{name:"github_label_issue",description:"Add, set (replace all), or remove labels on a GitHub issue. Labels back state-like transitions on GitHub.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},labels:{type:"array",items:{type:"string"},description:"Label name(s)"},mode:{type:"string",enum:["add","set","remove"],description:"add appends, set replaces all, remove deletes (default: add)"}},required:["owner","repo","number","labels"]}}]};export{u as ghFetch,oe as githubSkill};
46
+ `),instructions:"IMPORTANT: Show the contents field to the user - it contains the directory listing."})}catch(w){let y=String(w.message||w).split(c).join("***").replace(/x-access-token:[^@]*@/g,"x-access-token:***@");return JSON.stringify({error:`Clone failed: ${y}`})}}case"github_search_repos":{let{query:t,limit:i}=a;if(!t)return JSON.stringify({error:"query is required"});let n=await this.handleToolCall("github_list_repos",{limit:200},{}),e=JSON.parse(n);if(e.error)return JSON.stringify(e);let r=t.toLowerCase(),s=e.repos.filter(o=>o.name.toLowerCase().includes(r)||o.fullName.toLowerCase().includes(r)||o.description&&o.description.toLowerCase().includes(r));return JSON.stringify({query:t,count:s.length,repos:s.slice(0,i||20)})}case"github_list_repos":{let{owner:t,type:i,sort:n,direction:e,limit:r,query:s}=a,o=100,u=r||200,l=[],p=m=>({name:m.name,fullName:m.full_name,private:m.private,description:m.description,language:m.language,defaultBranch:m.default_branch,updatedAt:m.updated_at,stars:m.stargazers_count,url:m.html_url,fullPath:m.full_name,webUrl:m.html_url,visibility:m.visibility||(m.private?"private":"public")}),c=m=>{if(!s)return!0;let y=String(s).toLowerCase();return m.name&&m.name.toLowerCase().includes(y)||m.fullName&&m.fullName.toLowerCase().includes(y)||m.description&&m.description.toLowerCase().includes(y)};if(!t){let m=1,y=!0;for(;y&&l.length<u;){let O=`/installation/repositories?per_page=${o}&page=${m}`,v=(await d(O)).repositories||[];if(v.length===0)break;l=l.concat(v),y=v.length===o,m++}let S=l.map(p).filter(c),$=S.slice(0,u),q=S.length>$.length,N=$.filter(O=>O.private).length,k=$.filter(O=>!O.private).length;return JSON.stringify({count:$.length,repos:$,truncated:q,privateCount:N,publicCount:k,message:`Found ${N} private and ${k} public repos`})}let g=await d(`/orgs/${t}`).then(()=>!0).catch(()=>!1),h=1,_=!0;for(;_&&l.length<u;){let m;g?m=`/orgs/${t}/repos?per_page=${o}&page=${h}&type=${i||"all"}&sort=${n||"updated"}&direction=${e||"desc"}`:m=`/users/${t}/repos?per_page=${o}&page=${h}&type=${i||"all"}&sort=${n||"updated"}&direction=${e||"desc"}`;let y=await d(m),S=Array.isArray(y)?y:[];if(S.length===0)break;l=l.concat(S),_=S.length===o,h++}let f=l.map(p).filter(c),R=f.slice(0,u),w=f.length>R.length;return JSON.stringify({count:R.length,repos:R,truncated:w})}case"github_create_pr":{let{owner:t,repo:i,head:n,title:e}=a||{};if(!t||!i||!n||!e)return JSON.stringify({error:"owner, repo, head (source branch), and title are required"});let r=a.base;if(!r)try{r=(await d(`/repos/${t}/${i}`)).default_branch||"main"}catch{r="main"}let s={title:String(e),head:String(n),base:String(r),body:a.body?String(a.body):"",draft:!!a.draft};try{let o=await d(`/repos/${t}/${i}/pulls`,{method:"POST",body:s});return JSON.stringify({success:!0,pr_url:o.html_url,number:o.number,branch:n,base:r,repo:`${t}/${i}`,provider:"github",draft:!!o.draft,state:o.state})}catch(o){let u=String(o.message||o);if(/GitHub API 422/.test(u))return JSON.stringify({success:!1,branch:n,base:r,repo:`${t}/${i}`,provider:"github",skippedReason:u});throw o}}case"github_merge_pr":{let{owner:t,repo:i,number:n}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=a.mergeMethod||"squash";if(!["merge","squash","rebase"].includes(e))return JSON.stringify({error:`mergeMethod must be merge, squash, or rebase (got ${e})`});let r={merge_method:e};a.commitTitle&&(r.commit_title=String(a.commitTitle)),a.commitMessage&&(r.commit_message=String(a.commitMessage));try{let s=await d(`/repos/${t}/${i}/pulls/${n}/merge`,{method:"PUT",body:r});return JSON.stringify({success:!0,merged:!0,sha:s.sha,number:n,provider:"github"})}catch(s){let o=String(s.message||s);if(/GitHub API (405|409|404)/.test(o))return JSON.stringify({success:!1,number:n,provider:"github",skippedReason:o});throw s}}case"github_create_issue":{let{owner:t,repo:i,title:n,body:e}=a;if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and title are required"});let r=await d(`/repos/${t}/${i}/issues`,{method:"POST",body:{title:n,body:e||""}});return JSON.stringify({number:r.number,url:r.html_url,title:r.title})}case"github_list_issues":{let{owner:t,repo:i,state:n,labels:e,since:r,assignee:s,sort:o,direction:u,limit:l}=a||{};if(!t||!i)return JSON.stringify({error:"owner and repo are required"});let p=new URLSearchParams;p.set("state",n||"open"),p.set("per_page",String(l||30)),p.set("sort",o||"updated"),p.set("direction",u||"desc"),e&&p.set("labels",Array.isArray(e)?e.join(","):e),r&&p.set("since",r),s&&p.set("assignee",s);let c=await d(`/repos/${t}/${i}/issues?${p.toString()}`),g=(Array.isArray(c)?c:[]).filter(h=>!h.pull_request).map(h=>({number:h.number,title:h.title,state:h.state,labels:(h.labels||[]).map(_=>typeof _=="string"?_:_.name),assignee:h.assignee?.login||null,assignees:(h.assignees||[]).map(_=>_.login),user:h.user?.login,comments:h.comments,url:h.html_url,createdAt:h.created_at,updatedAt:h.updated_at}));return JSON.stringify({count:g.length,issues:g})}case"github_get_issue":{let{owner:t,repo:i,number:n}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/issues/${n}`);return e.pull_request?JSON.stringify({error:`#${n} is a pull request, not an issue`,isPR:!0}):JSON.stringify({number:e.number,title:e.title,body:e.body||"",state:e.state,stateReason:e.state_reason||null,labels:(e.labels||[]).map(r=>typeof r=="string"?r:r.name),assignee:e.assignee?.login||null,assignees:(e.assignees||[]).map(r=>r.login),user:e.user?.login,milestone:e.milestone?.title||null,comments:e.comments,url:e.html_url,createdAt:e.created_at,updatedAt:e.updated_at,closedAt:e.closed_at})}case"github_get_issue_comments":{let{owner:t,repo:i,number:n,limit:e}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let r=await d(`/repos/${t}/${i}/issues/${n}/comments?per_page=${e||100}`),s=(Array.isArray(r)?r:[]).map(o=>({id:o.id,user:o.user?.login,body:o.body||"",createdAt:o.created_at,updatedAt:o.updated_at,url:o.html_url}));return JSON.stringify({count:s.length,comments:s})}case"github_add_issue_comment":{let{owner:t,repo:i,number:n,body:e}=a||{};if(!t||!i||!n||!e)return JSON.stringify({error:"owner, repo, number, and body are required"});let r=await d(`/repos/${t}/${i}/issues/${n}/comments`,{method:"POST",body:{body:e}});return JSON.stringify({ok:!0,id:r.id,url:r.html_url})}case"github_close_issue":{let{owner:t,repo:i,number:n,stateReason:e}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let r={state:"closed"};e&&(r.state_reason=e);let s=await d(`/repos/${t}/${i}/issues/${n}`,{method:"PATCH",body:r});return JSON.stringify({ok:!0,number:s.number,state:s.state,stateReason:s.state_reason||null,url:s.html_url})}case"github_reopen_issue":{let{owner:t,repo:i,number:n}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let e=await d(`/repos/${t}/${i}/issues/${n}`,{method:"PATCH",body:{state:"open"}});return JSON.stringify({ok:!0,number:e.number,state:e.state,url:e.html_url})}case"github_label_issue":{let{owner:t,repo:i,number:n,labels:e,mode:r}=a||{};if(!t||!i||!n)return JSON.stringify({error:"owner, repo, and number are required"});let s=Array.isArray(e)?e:e?[e]:[];if(!s.length)return JSON.stringify({error:"labels (string or array) is required"});let o=r||"add";if(o==="set"){let l=await d(`/repos/${t}/${i}/issues/${n}`,{method:"PATCH",body:{labels:s}});return JSON.stringify({ok:!0,number:l.number,labels:(l.labels||[]).map(p=>typeof p=="string"?p:p.name)})}if(o==="remove"){for(let p of s)await d(`/repos/${t}/${i}/issues/${n}/labels/${encodeURIComponent(p)}`,{method:"DELETE"});let l=await d(`/repos/${t}/${i}/issues/${n}`);return JSON.stringify({ok:!0,number:l.number,labels:(l.labels||[]).map(p=>typeof p=="string"?p:p.name)})}let u=await d(`/repos/${t}/${i}/issues/${n}/labels`,{method:"POST",body:{labels:s}});return JSON.stringify({ok:!0,number:n,labels:(Array.isArray(u)?u:[]).map(l=>typeof l=="string"?l:l.name)})}default:return JSON.stringify({error:`Unknown tool: ${b}`})}}catch(t){return JSON.stringify({error:t.message})}},tools:[{name:"github_get_user",description:"Get the authenticated GitHub user profile and their organizations",input_schema:{type:"object",properties:{}}},{name:"github_list_orgs",description:"List GitHub organizations the authenticated user belongs to",input_schema:{type:"object",properties:{}}},{name:"github_list_repos",description:"List the repositories this token/installation can access (omit owner) \u2014 or a specific user/org's repos (pass owner). Use this to discover a RELATED repo worth cloning when a change's correctness depends on another accessible repo. Each repo carries a normalized { fullPath, name, webUrl, defaultBranch, visibility } shape (identical to gitlab_list_projects) alongside legacy fields, plus a truncated flag.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Org or user login. Omit to list every repo your token/installation can access."},query:{type:"string",description:"Optional term matched against repo name/full-name/description"},type:{type:"string",enum:["all","public","private","forks","sources","member"],description:"Filter by type (default: all)"},sort:{type:"string",enum:["created","updated","pushed","full_name"],description:"Sort field (default: updated)"},direction:{type:"string",enum:["asc","desc"],description:"Sort direction (default: desc)"},limit:{type:"number",description:"Max repos to return (default: 200, hard-capped at the fetch ceiling)"}}}},{name:"github_clone",description:'Clone a GitHub repository to the local filesystem. Use when user says "check out" or "clone" a repo.',input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner (user or org name)"},repo:{type:"string",description:"Repository name"},destination:{type:"string",description:"Destination directory. Accepts absolute paths, ~-prefixed paths, or relative names. Defaults to ~/zibby-repos/<repo>."}},required:["owner","repo"]}},{name:"github_search_repos",description:"Search accessible repositories by name or description. Use this when the user asks to find a specific repo.",input_schema:{type:"object",properties:{query:{type:"string",description:'Search term to match against repo name or description (e.g., "electron", "my-app")'},limit:{type:"number",description:"Max results (default: 20)"}},required:["query"]}},{name:"github_search_issues",description:"Search GitHub issues and pull requests",input_schema:{type:"object",properties:{query:{type:"string",description:'GitHub search query (e.g. "SCRUM-123", "login bug repo:org/app")'},limit:{type:"number",description:"Max results (default: 20)"}},required:["query"]}},{name:"github_search_code",description:"Search code across GitHub repositories by keyword",input_schema:{type:"object",properties:{query:{type:"string",description:'Code search query (e.g. "handleLogin", "class AuthService")'},repo:{type:"string",description:'Scope to a specific repo (e.g. "org/app"). Optional.'},language:{type:"string",description:'Filter by language (e.g. "javascript", "python"). Optional.'},limit:{type:"number",description:"Max results (default: 15)"}},required:["query"]}},{name:"github_get_pr",description:"Get details of a pull request \u2014 title, description, branch, stats",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_get_pr_diff",description:"Get the unified diff of a pull request \u2014 the actual code changes",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_list_pr_files",description:"List files changed in a PR with per-file patches",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_list_pr_comments",description:"Get all review and issue comments on a PR",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"}},required:["owner","repo","number"]}},{name:"github_get_review_thread",description:"Read a PR review-comment THREAD given any comment id in it: the root review comment + all its replies, plus the anchored diff context (file, line, the original diff hunk). Use this to understand a human's reply to a previous review comment before replying in-thread.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},commentId:{type:"number",description:"Any review-comment id in the thread (the root or any reply)"}},required:["owner","repo","number","commentId"]}},{name:"github_reply_review_thread",description:"Reply IN-THREAD to an existing PR review-comment thread (a conversational reply nested under the thread the human commented on \u2014 NOT a fresh full review). Pass any comment id in the thread.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},commentId:{type:"number",description:"Any review-comment id in the thread to reply to"},body:{type:"string",description:"The reply text (markdown)"}},required:["owner","repo","number","commentId","body"]}},{name:"github_reply_issue_comment",description:"Post a reply on a PR's top-level conversation (a new issue comment on the PR). Use when the human replied to a non-inline/summary comment rather than an inline review thread. Quote or @-mention for context since issue comments are not threaded.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},body:{type:"string",description:"The reply text (markdown)"}},required:["owner","repo","number","body"]}},{name:"github_create_review",description:"Post a review on a pull request: a summary body plus optional inline comments anchored to file/line, with an event (COMMENT, APPROVE, or REQUEST_CHANGES). Use this to deliver a code review back to the PR.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number"},body:{type:"string",description:"The review summary (markdown). Shown as the top-level review comment."},event:{type:"string",enum:["COMMENT","APPROVE","REQUEST_CHANGES"],description:"Review verdict. Default COMMENT (no approval state). Use REQUEST_CHANGES for blocking issues."},comments:{type:"array",description:"Optional inline comments, each anchored to a changed line.",items:{type:"object",properties:{path:{type:"string",description:"File path as it appears in the diff"},line:{type:"number",description:"Line number in the file's NEW version (the right side of the diff)"},side:{type:"string",enum:["LEFT","RIGHT"],description:"RIGHT (new) or LEFT (old). Default RIGHT."},body:{type:"string",description:"The inline comment text (markdown)"}},required:["path","line","body"]}}},required:["owner","repo","number"]}},{name:"github_list_commits",description:"List commits on a branch \u2014 optionally bounded by since/until ISO dates (date-window listing) and paginated (keep calling with page+1 while hasMore is true). Optionally filtered by file path.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},branch:{type:"string",description:"Branch name (default: repo default branch)"},path:{type:"string",description:"Filter commits touching this file path"},limit:{type:"number",description:"Commits per page, max 100 (default: 20)"},since:{type:"string",description:'Only commits after this ISO-8601 date/time, e.g. "2026-01-01T00:00:00Z"'},until:{type:"string",description:"Only commits before this ISO-8601 date/time"},page:{type:"number",description:"Page number, 1-based (default 1)"}},required:["owner","repo"]}},{name:"github_get_commit",description:"Get details of a specific commit \u2014 message, stats, file diffs",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},sha:{type:"string",description:"Commit SHA (full or short)"},includePrs:{type:"boolean",description:"Also return the pull request(s) containing this commit ({number,title,state,merged,webUrl}) \u2014 the evidence link for contribution records (default false)"}},required:["owner","repo","sha"]}},{name:"github_get_file",description:"Read a file (or list a directory) from a GitHub repo. Works on any branch/ref.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},path:{type:"string",description:'File or directory path (e.g. "src/auth/login.ts")'},ref:{type:"string",description:"Branch, tag, or commit SHA (default: repo default branch)"}},required:["owner","repo","path"]}},{name:"github_create_pr",description:"Open a pull request on GitHub (POST /repos/{owner}/{repo}/pulls). The head (source) branch must already be pushed. Returns the REAL pr_url from GitHub \u2014 never fabricate a PR url. Expected business outcomes (no commits between base and head, a PR already exists for this branch, base==head, missing head) return { success:false, skippedReason } rather than erroring.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},head:{type:"string",description:'Source branch to merge FROM (must already be pushed). For a cross-fork PR use "fork-owner:branch".'},base:{type:"string",description:"Target branch to merge INTO (default: the repo's default branch)"},title:{type:"string",description:"PR title"},body:{type:"string",description:"PR description (markdown)"},draft:{type:"boolean",description:"Open as a draft PR (default: false)"}},required:["owner","repo","head","title"]}},{name:"github_merge_pr",description:"Merge a pull request on GitHub (PUT /repos/{owner}/{repo}/pulls/{number}/merge). mergeMethod is merge | squash | rebase (default squash). Returns { success:true, merged:true, sha } with the REAL merge SHA from GitHub. Expected non-mergeable outcomes (405 = draft / failing checks / branch protection, 409 = head sha moved / conflict, 404 = not found) return { success:false, skippedReason } rather than erroring.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"PR number to merge"},mergeMethod:{type:"string",enum:["merge","squash","rebase"],description:"How to merge (default: squash)"},commitTitle:{type:"string",description:"Title for the merge/squash commit (optional)"},commitMessage:{type:"string",description:"Body for the merge/squash commit (optional)"}},required:["owner","repo","number"]}},{name:"github_create_issue",description:"Create a GitHub issue",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},title:{type:"string",description:"Issue title"},body:{type:"string",description:"Issue body (markdown)"}},required:["owner","repo","title"]}},{name:"github_list_issues",description:"List issues in a repo (excludes pull requests). Filter by state, labels, and an updated-since cursor for polling.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},state:{type:"string",enum:["open","closed","all"],description:"Filter by state (default: open)"},labels:{type:"array",items:{type:"string"},description:"Only issues carrying ALL of these labels"},since:{type:"string",description:"ISO-8601 timestamp; only issues updated at/after this (polling cursor)"},assignee:{type:"string",description:'Filter by assignee login, "none", or "*"'},sort:{type:"string",enum:["created","updated","comments"],description:"Sort field (default: updated)"},direction:{type:"string",enum:["asc","desc"],description:"Sort direction (default: desc)"},limit:{type:"number",description:"Max issues (default: 30, max 100 per page)"}},required:["owner","repo"]}},{name:"github_get_issue",description:"Get a single GitHub issue with full detail (title, body, state, labels, assignee, url)",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"}},required:["owner","repo","number"]}},{name:"github_get_issue_comments",description:"Get the comment thread on a GitHub issue (chronological)",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},limit:{type:"number",description:"Max comments (default: 100)"}},required:["owner","repo","number"]}},{name:"github_add_issue_comment",description:"Add a comment to a GitHub issue. Also the way to record a PR link on an issue (post a markdown link).",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},body:{type:"string",description:"Comment body (markdown)"}},required:["owner","repo","number","body"]}},{name:"github_close_issue",description:"Close a GitHub issue. Optionally set the close reason (completed or not_planned).",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},stateReason:{type:"string",enum:["completed","not_planned"],description:"Why the issue was closed (optional)"}},required:["owner","repo","number"]}},{name:"github_reopen_issue",description:"Reopen a closed GitHub issue",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"}},required:["owner","repo","number"]}},{name:"github_label_issue",description:"Add, set (replace all), or remove labels on a GitHub issue. Labels back state-like transitions on GitHub.",input_schema:{type:"object",properties:{owner:{type:"string",description:"Repository owner"},repo:{type:"string",description:"Repository name"},number:{type:"number",description:"Issue number"},labels:{type:"array",items:{type:"string"},description:"Label name(s)"},mode:{type:"string",enum:["add","set","remove"],description:"add appends, set replaces all, remove deletes (default: add)"}},required:["owner","repo","number","labels"]}}]};export{d as ghFetch,oe as githubSkill};