@morphllm/morphsdk 0.2.103 → 0.2.105

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/client.cjs CHANGED
@@ -3648,6 +3648,284 @@ function formatResult(result) {
3648
3648
  return lines.join("\n");
3649
3649
  }
3650
3650
 
3651
+ // tools/github/types.ts
3652
+ var GitHubError = class extends Error {
3653
+ /** HTTP status code */
3654
+ status;
3655
+ /** Error code from API */
3656
+ code;
3657
+ constructor(message, status, code) {
3658
+ super(message);
3659
+ this.name = "GitHubError";
3660
+ this.status = status;
3661
+ this.code = code;
3662
+ }
3663
+ };
3664
+ var NoInstallationError = class extends GitHubError {
3665
+ constructor(message = "No GitHub installation found. Connect GitHub at morphllm.com/dashboard/integrations/github") {
3666
+ super(message, 404, "NO_INSTALLATION");
3667
+ }
3668
+ };
3669
+ var NotFoundError = class extends GitHubError {
3670
+ constructor(resource) {
3671
+ super(`${resource} not found`, 404, "NOT_FOUND");
3672
+ }
3673
+ };
3674
+ var PermissionError = class extends GitHubError {
3675
+ constructor(message = "Insufficient permissions for this operation") {
3676
+ super(message, 403, "PERMISSION_DENIED");
3677
+ }
3678
+ };
3679
+
3680
+ // tools/github/core.ts
3681
+ var DEFAULT_BASE_URL = "https://api.morphllm.com";
3682
+ var DEFAULT_TIMEOUT2 = 3e4;
3683
+ var GitHubClient = class {
3684
+ apiKey;
3685
+ baseUrl;
3686
+ timeout;
3687
+ debug;
3688
+ defaultInstallationId;
3689
+ /** Installation operations */
3690
+ installations;
3691
+ /** Repository operations */
3692
+ repos;
3693
+ /** Pull request operations */
3694
+ pullRequests;
3695
+ /** Deployment operations */
3696
+ deployments;
3697
+ /** Comment operations */
3698
+ comments;
3699
+ /** Check run operations */
3700
+ checkRuns;
3701
+ constructor(config = {}) {
3702
+ this.apiKey = config.apiKey || process.env.MORPH_API_KEY || "";
3703
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
3704
+ this.timeout = config.timeout || DEFAULT_TIMEOUT2;
3705
+ this.debug = config.debug || false;
3706
+ this.defaultInstallationId = config.installationId;
3707
+ if (!this.apiKey) {
3708
+ throw new Error("API key required. Set MORPH_API_KEY or pass apiKey in config.");
3709
+ }
3710
+ this.installations = {
3711
+ list: this.listInstallations.bind(this),
3712
+ get: this.getInstallation.bind(this)
3713
+ };
3714
+ this.repos = {
3715
+ list: this.listRepos.bind(this)
3716
+ };
3717
+ this.pullRequests = {
3718
+ list: this.listPullRequests.bind(this),
3719
+ get: this.getPullRequest.bind(this)
3720
+ };
3721
+ this.deployments = {
3722
+ list: this.listDeployments.bind(this)
3723
+ };
3724
+ this.comments = {
3725
+ list: this.listComments.bind(this),
3726
+ create: this.createComment.bind(this),
3727
+ update: this.updateComment.bind(this),
3728
+ delete: this.deleteComment.bind(this)
3729
+ };
3730
+ this.checkRuns = {
3731
+ create: this.createCheckRun.bind(this),
3732
+ update: this.updateCheckRun.bind(this)
3733
+ };
3734
+ }
3735
+ /**
3736
+ * Make an API request to the Morph GitHub proxy
3737
+ */
3738
+ async request(method, path5, body) {
3739
+ const url = `${this.baseUrl}${path5}`;
3740
+ if (this.debug) {
3741
+ console.log(`[GitHub SDK] ${method} ${path5}`, body || "");
3742
+ }
3743
+ const controller = new AbortController();
3744
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
3745
+ try {
3746
+ const response = await fetch(url, {
3747
+ method,
3748
+ headers: {
3749
+ "Content-Type": "application/json",
3750
+ Authorization: `Bearer ${this.apiKey}`
3751
+ },
3752
+ body: body ? JSON.stringify(body) : void 0,
3753
+ signal: controller.signal
3754
+ });
3755
+ clearTimeout(timeoutId);
3756
+ if (!response.ok) {
3757
+ const errorData = await response.json().catch(() => ({}));
3758
+ const message = errorData.error || errorData.message || response.statusText;
3759
+ if (this.debug) {
3760
+ console.error(`[GitHub SDK] Error ${response.status}:`, message);
3761
+ }
3762
+ if (response.status === 404) {
3763
+ if (message.includes("installation")) {
3764
+ throw new NoInstallationError(message);
3765
+ }
3766
+ throw new NotFoundError(message);
3767
+ }
3768
+ if (response.status === 403) {
3769
+ throw new PermissionError(message);
3770
+ }
3771
+ throw new GitHubError(message, response.status, errorData.code);
3772
+ }
3773
+ const data = await response.json();
3774
+ if (this.debug) {
3775
+ console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));
3776
+ }
3777
+ return data;
3778
+ } catch (error) {
3779
+ clearTimeout(timeoutId);
3780
+ if (error instanceof GitHubError) {
3781
+ throw error;
3782
+ }
3783
+ if (error instanceof Error && error.name === "AbortError") {
3784
+ throw new GitHubError("Request timeout", 408, "TIMEOUT");
3785
+ }
3786
+ throw new GitHubError(
3787
+ error instanceof Error ? error.message : "Unknown error",
3788
+ 500,
3789
+ "UNKNOWN"
3790
+ );
3791
+ }
3792
+ }
3793
+ /**
3794
+ * Get the installation ID to use for a request
3795
+ */
3796
+ getInstallationId(input) {
3797
+ return input?.installationId || this.defaultInstallationId;
3798
+ }
3799
+ // ==========================================================================
3800
+ // Installations
3801
+ // ==========================================================================
3802
+ async listInstallations() {
3803
+ return this.request("GET", "/v1/github/installations");
3804
+ }
3805
+ async getInstallation(installationId) {
3806
+ return this.request("GET", `/v1/github/installations/${installationId}`);
3807
+ }
3808
+ // ==========================================================================
3809
+ // Repositories
3810
+ // ==========================================================================
3811
+ async listRepos(input) {
3812
+ const installationId = input.installationId || this.defaultInstallationId;
3813
+ if (!installationId) {
3814
+ throw new NoInstallationError("installationId required. Call installations.list() first.");
3815
+ }
3816
+ return this.request("GET", `/v1/github/installations/${installationId}/repos`);
3817
+ }
3818
+ // ==========================================================================
3819
+ // Pull Requests
3820
+ // ==========================================================================
3821
+ async listPullRequests(input) {
3822
+ const installationId = this.getInstallationId(input);
3823
+ const params = new URLSearchParams({
3824
+ owner: input.owner,
3825
+ repo: input.repo,
3826
+ ...input.state && { state: input.state },
3827
+ ...installationId && { installationId }
3828
+ });
3829
+ return this.request("GET", `/v1/github/pulls?${params}`);
3830
+ }
3831
+ async getPullRequest(input) {
3832
+ const installationId = this.getInstallationId(input);
3833
+ const params = new URLSearchParams({
3834
+ owner: input.owner,
3835
+ repo: input.repo,
3836
+ ...installationId && { installationId }
3837
+ });
3838
+ return this.request(
3839
+ "GET",
3840
+ `/v1/github/pulls/${input.number}?${params}`
3841
+ );
3842
+ }
3843
+ // ==========================================================================
3844
+ // Deployments
3845
+ // ==========================================================================
3846
+ async listDeployments(input) {
3847
+ const installationId = this.getInstallationId(input);
3848
+ const params = new URLSearchParams({
3849
+ owner: input.owner,
3850
+ repo: input.repo,
3851
+ ...input.sha && { sha: input.sha },
3852
+ ...input.environment && { environment: input.environment },
3853
+ ...installationId && { installationId }
3854
+ });
3855
+ return this.request("GET", `/v1/github/deployments?${params}`);
3856
+ }
3857
+ // ==========================================================================
3858
+ // Comments
3859
+ // ==========================================================================
3860
+ async listComments(input) {
3861
+ const installationId = this.getInstallationId(input);
3862
+ const params = new URLSearchParams({
3863
+ owner: input.owner,
3864
+ repo: input.repo,
3865
+ pr: String(input.pr),
3866
+ ...installationId && { installationId }
3867
+ });
3868
+ return this.request("GET", `/v1/github/comments?${params}`);
3869
+ }
3870
+ async createComment(input) {
3871
+ const installationId = this.getInstallationId(input);
3872
+ return this.request("POST", "/v1/github/comments", {
3873
+ owner: input.owner,
3874
+ repo: input.repo,
3875
+ pr: input.pr,
3876
+ body: input.body,
3877
+ ...installationId && { installationId }
3878
+ });
3879
+ }
3880
+ async updateComment(input) {
3881
+ const installationId = this.getInstallationId(input);
3882
+ return this.request("PATCH", `/v1/github/comments/${input.commentId}`, {
3883
+ owner: input.owner,
3884
+ repo: input.repo,
3885
+ body: input.body,
3886
+ ...installationId && { installationId }
3887
+ });
3888
+ }
3889
+ async deleteComment(input) {
3890
+ const installationId = this.getInstallationId(input);
3891
+ const params = new URLSearchParams({
3892
+ owner: input.owner,
3893
+ repo: input.repo,
3894
+ ...installationId && { installationId }
3895
+ });
3896
+ await this.request("DELETE", `/v1/github/comments/${input.commentId}?${params}`);
3897
+ }
3898
+ // ==========================================================================
3899
+ // Check Runs
3900
+ // ==========================================================================
3901
+ async createCheckRun(input) {
3902
+ const installationId = this.getInstallationId(input);
3903
+ return this.request("POST", "/v1/github/check-runs", {
3904
+ owner: input.owner,
3905
+ repo: input.repo,
3906
+ sha: input.sha,
3907
+ name: input.name,
3908
+ status: input.status,
3909
+ ...input.title && { title: input.title },
3910
+ ...input.summary && { summary: input.summary },
3911
+ ...installationId && { installationId }
3912
+ });
3913
+ }
3914
+ async updateCheckRun(input) {
3915
+ const installationId = this.getInstallationId(input);
3916
+ return this.request("PATCH", `/v1/github/check-runs/${input.checkRunId}`, {
3917
+ owner: input.owner,
3918
+ repo: input.repo,
3919
+ ...input.status && { status: input.status },
3920
+ ...input.conclusion && { conclusion: input.conclusion },
3921
+ ...input.title && { title: input.title },
3922
+ ...input.summary && { summary: input.summary },
3923
+ ...input.text && { text: input.text },
3924
+ ...installationId && { installationId }
3925
+ });
3926
+ }
3927
+ };
3928
+
3651
3929
  // git/client.ts
3652
3930
  var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
3653
3931
  var import_node = __toESM(require("isomorphic-git/http/node"), 1);
@@ -5040,6 +5318,8 @@ var MorphClient = class {
5040
5318
  warpGrep;
5041
5319
  /** Browser tool for AI-powered browser automation */
5042
5320
  browser;
5321
+ /** GitHub tool for PR context, comments, and check runs */
5322
+ github;
5043
5323
  /** Git tool for version control operations */
5044
5324
  git;
5045
5325
  /** Model routers for intelligent model selection */
@@ -5090,6 +5370,12 @@ var MorphClient = class {
5090
5370
  timeout: config.timeout,
5091
5371
  retryConfig: config.retryConfig
5092
5372
  });
5373
+ this.github = new GitHubClient({
5374
+ apiKey: config.apiKey,
5375
+ debug: config.debug,
5376
+ timeout: config.timeout,
5377
+ installationId: config.github?.installationId
5378
+ });
5093
5379
  this.git = new MorphGit({
5094
5380
  apiKey: config.apiKey,
5095
5381
  retryConfig: config.retryConfig