@morphllm/morphsdk 0.2.111 → 0.2.113
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/{chunk-JYKYQ5DN.js → chunk-2SOSDQFG.js} +19 -40
- package/dist/chunk-2SOSDQFG.js.map +1 -0
- package/dist/{chunk-I3IN742Q.js → chunk-A3PK4H7A.js} +2 -2
- package/dist/{chunk-KQP6ZPYB.js → chunk-JD4H6U3Z.js} +2 -2
- package/dist/{chunk-TLC3QKE6.js → chunk-R3BSIJCL.js} +4 -3
- package/dist/{chunk-TLC3QKE6.js.map → chunk-R3BSIJCL.js.map} +1 -1
- package/dist/{chunk-HDRLLCAD.js → chunk-TGUQHW3I.js} +2 -2
- package/dist/{chunk-2MAUPERG.js → chunk-Z6TF5G4R.js} +5 -4
- package/dist/chunk-Z6TF5G4R.js.map +1 -0
- package/dist/{client-DksVOIsG.d.ts → client-Bm_umdno.d.ts} +3 -14
- package/dist/client.cjs +21 -40
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +6 -6
- package/dist/edge.cjs +4 -3
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.js +1 -1
- package/dist/index.cjs +21 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/tools/fastapply/anthropic.cjs +7 -5
- package/dist/tools/fastapply/anthropic.cjs.map +1 -1
- package/dist/tools/fastapply/anthropic.js +3 -3
- package/dist/tools/fastapply/apply.cjs +4 -3
- package/dist/tools/fastapply/apply.cjs.map +1 -1
- package/dist/tools/fastapply/apply.d.ts +4 -1
- package/dist/tools/fastapply/apply.js +1 -1
- package/dist/tools/fastapply/core.cjs +7 -5
- package/dist/tools/fastapply/core.cjs.map +1 -1
- package/dist/tools/fastapply/core.js +2 -2
- package/dist/tools/fastapply/index.cjs +7 -5
- package/dist/tools/fastapply/index.cjs.map +1 -1
- package/dist/tools/fastapply/index.js +5 -5
- package/dist/tools/fastapply/openai.cjs +7 -5
- package/dist/tools/fastapply/openai.cjs.map +1 -1
- package/dist/tools/fastapply/openai.js +3 -3
- package/dist/tools/fastapply/types.cjs.map +1 -1
- package/dist/tools/fastapply/types.d.ts +5 -0
- package/dist/tools/fastapply/vercel.cjs +7 -5
- package/dist/tools/fastapply/vercel.cjs.map +1 -1
- package/dist/tools/fastapply/vercel.js +3 -3
- package/dist/tools/index.cjs +7 -5
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-2MAUPERG.js.map +0 -1
- package/dist/chunk-JYKYQ5DN.js.map +0 -1
- /package/dist/{chunk-I3IN742Q.js.map → chunk-A3PK4H7A.js.map} +0 -0
- /package/dist/{chunk-KQP6ZPYB.js.map → chunk-JD4H6U3Z.js.map} +0 -0
- /package/dist/{chunk-HDRLLCAD.js.map → chunk-TGUQHW3I.js.map} +0 -0
|
@@ -24,16 +24,16 @@ import {
|
|
|
24
24
|
} from "./chunk-WM77HRKO.js";
|
|
25
25
|
import {
|
|
26
26
|
createEditFileTool as createEditFileTool3
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-TGUQHW3I.js";
|
|
28
28
|
import {
|
|
29
29
|
createEditFileTool as createEditFileTool2
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-JD4H6U3Z.js";
|
|
31
31
|
import {
|
|
32
32
|
createEditFileTool
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-A3PK4H7A.js";
|
|
34
34
|
import {
|
|
35
35
|
FastApplyClient
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-R3BSIJCL.js";
|
|
37
37
|
import {
|
|
38
38
|
BrowserClient
|
|
39
39
|
} from "./chunk-4IOC2D5Y.js";
|
|
@@ -77,13 +77,11 @@ var PermissionError = class extends GitHubError {
|
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
// tools/github/core.ts
|
|
80
|
-
var
|
|
81
|
-
var BACKEND_BASE_URL = "https://browser.morphllm.com";
|
|
80
|
+
var DEFAULT_BASE_URL = "https://api.morphllm.com";
|
|
82
81
|
var DEFAULT_TIMEOUT = 3e4;
|
|
83
82
|
var GitHubClient = class {
|
|
84
83
|
apiKey;
|
|
85
|
-
|
|
86
|
-
backendUrl;
|
|
84
|
+
baseUrl;
|
|
87
85
|
timeout;
|
|
88
86
|
debug;
|
|
89
87
|
defaultInstallationId;
|
|
@@ -110,8 +108,7 @@ var GitHubClient = class {
|
|
|
110
108
|
}
|
|
111
109
|
constructor(config = {}) {
|
|
112
110
|
this.apiKey = config.apiKey || process.env.MORPH_API_KEY || "";
|
|
113
|
-
this.
|
|
114
|
-
this.backendUrl = config.backendUrl || BACKEND_BASE_URL;
|
|
111
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
115
112
|
this.timeout = config.timeout || DEFAULT_TIMEOUT;
|
|
116
113
|
this.debug = config.debug || false;
|
|
117
114
|
this.defaultInstallationId = config.installationId;
|
|
@@ -156,24 +153,10 @@ var GitHubClient = class {
|
|
|
156
153
|
};
|
|
157
154
|
}
|
|
158
155
|
/**
|
|
159
|
-
* Make an API request
|
|
156
|
+
* Make an authenticated API request
|
|
160
157
|
*/
|
|
161
158
|
async request(method, path, body) {
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
// TODO: These endpoints use Octokit and currently live in landing.
|
|
165
|
-
// Move them to the backend so all GitHub SDK traffic goes through a single URL.
|
|
166
|
-
/**
|
|
167
|
-
* Make an API request to the landing app (Octokit-based endpoints)
|
|
168
|
-
*/
|
|
169
|
-
async landingRequest(method, path, body) {
|
|
170
|
-
return this._fetch(this.landingUrl, method, path, body);
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Shared fetch logic for both backend and landing requests
|
|
174
|
-
*/
|
|
175
|
-
async _fetch(baseUrl, method, path, body) {
|
|
176
|
-
const url = `${baseUrl}${path}`;
|
|
159
|
+
const url = `${this.baseUrl}${path}`;
|
|
177
160
|
if (this.debug) {
|
|
178
161
|
console.log(`[GitHub SDK] ${method} ${path}`, body || "");
|
|
179
162
|
}
|
|
@@ -305,7 +288,6 @@ var GitHubClient = class {
|
|
|
305
288
|
}
|
|
306
289
|
// ==========================================================================
|
|
307
290
|
// Pull Requests
|
|
308
|
-
// TODO: Move to backend — currently uses Octokit in landing
|
|
309
291
|
// ==========================================================================
|
|
310
292
|
async listPullRequests(input) {
|
|
311
293
|
const installationId = this.getInstallationId(input);
|
|
@@ -315,7 +297,7 @@ var GitHubClient = class {
|
|
|
315
297
|
...input.state && { state: input.state },
|
|
316
298
|
...installationId && { installationId }
|
|
317
299
|
});
|
|
318
|
-
return this.
|
|
300
|
+
return this.request("GET", `/api/v1/github/pulls?${params}`);
|
|
319
301
|
}
|
|
320
302
|
async getPullRequest(input) {
|
|
321
303
|
const installationId = this.getInstallationId(input);
|
|
@@ -324,14 +306,13 @@ var GitHubClient = class {
|
|
|
324
306
|
repo: input.repo,
|
|
325
307
|
...installationId && { installationId }
|
|
326
308
|
});
|
|
327
|
-
return this.
|
|
309
|
+
return this.request(
|
|
328
310
|
"GET",
|
|
329
311
|
`/api/v1/github/pulls/${input.number}?${params}`
|
|
330
312
|
);
|
|
331
313
|
}
|
|
332
314
|
// ==========================================================================
|
|
333
315
|
// Deployments
|
|
334
|
-
// TODO: Move to backend — currently uses Octokit in landing
|
|
335
316
|
// ==========================================================================
|
|
336
317
|
async listDeployments(input) {
|
|
337
318
|
const installationId = this.getInstallationId(input);
|
|
@@ -342,11 +323,10 @@ var GitHubClient = class {
|
|
|
342
323
|
...input.environment && { environment: input.environment },
|
|
343
324
|
...installationId && { installationId }
|
|
344
325
|
});
|
|
345
|
-
return this.
|
|
326
|
+
return this.request("GET", `/api/v1/github/deployments?${params}`);
|
|
346
327
|
}
|
|
347
328
|
// ==========================================================================
|
|
348
329
|
// Comments
|
|
349
|
-
// TODO: Move to backend — currently uses Octokit in landing
|
|
350
330
|
// ==========================================================================
|
|
351
331
|
async listComments(input) {
|
|
352
332
|
const installationId = this.getInstallationId(input);
|
|
@@ -356,11 +336,11 @@ var GitHubClient = class {
|
|
|
356
336
|
pr: String(input.pr),
|
|
357
337
|
...installationId && { installationId }
|
|
358
338
|
});
|
|
359
|
-
return this.
|
|
339
|
+
return this.request("GET", `/api/v1/github/comments?${params}`);
|
|
360
340
|
}
|
|
361
341
|
async createComment(input) {
|
|
362
342
|
const installationId = this.getInstallationId(input);
|
|
363
|
-
return this.
|
|
343
|
+
return this.request("POST", "/api/v1/github/comments", {
|
|
364
344
|
owner: input.owner,
|
|
365
345
|
repo: input.repo,
|
|
366
346
|
pr: input.pr,
|
|
@@ -370,7 +350,7 @@ var GitHubClient = class {
|
|
|
370
350
|
}
|
|
371
351
|
async updateComment(input) {
|
|
372
352
|
const installationId = this.getInstallationId(input);
|
|
373
|
-
return this.
|
|
353
|
+
return this.request("PATCH", `/api/v1/github/comments/${input.commentId}`, {
|
|
374
354
|
owner: input.owner,
|
|
375
355
|
repo: input.repo,
|
|
376
356
|
body: input.body,
|
|
@@ -384,15 +364,14 @@ var GitHubClient = class {
|
|
|
384
364
|
repo: input.repo,
|
|
385
365
|
...installationId && { installationId }
|
|
386
366
|
});
|
|
387
|
-
await this.
|
|
367
|
+
await this.request("DELETE", `/api/v1/github/comments/${input.commentId}?${params}`);
|
|
388
368
|
}
|
|
389
369
|
// ==========================================================================
|
|
390
370
|
// Check Runs
|
|
391
|
-
// TODO: Move to backend — currently uses Octokit in landing
|
|
392
371
|
// ==========================================================================
|
|
393
372
|
async createCheckRun(input) {
|
|
394
373
|
const installationId = this.getInstallationId(input);
|
|
395
|
-
return this.
|
|
374
|
+
return this.request("POST", "/api/v1/github/check-runs", {
|
|
396
375
|
owner: input.owner,
|
|
397
376
|
repo: input.repo,
|
|
398
377
|
sha: input.sha,
|
|
@@ -405,7 +384,7 @@ var GitHubClient = class {
|
|
|
405
384
|
}
|
|
406
385
|
async updateCheckRun(input) {
|
|
407
386
|
const installationId = this.getInstallationId(input);
|
|
408
|
-
return this.
|
|
387
|
+
return this.request("PATCH", `/api/v1/github/check-runs/${input.checkRunId}`, {
|
|
409
388
|
owner: input.owner,
|
|
410
389
|
repo: input.repo,
|
|
411
390
|
...input.status && { status: input.status },
|
|
@@ -664,4 +643,4 @@ export {
|
|
|
664
643
|
VercelToolFactory,
|
|
665
644
|
MorphClient
|
|
666
645
|
};
|
|
667
|
-
//# sourceMappingURL=chunk-
|
|
646
|
+
//# sourceMappingURL=chunk-2SOSDQFG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/github/types.ts","../tools/github/core.ts","../factories/openai.ts","../factories/anthropic.ts","../factories/vercel.ts","../client.ts"],"sourcesContent":["/**\n * GitHub SDK Types\n *\n * Type definitions for the Morph GitHub integration.\n * Users connect GitHub in the Morph dashboard, then use these\n * types to interact with their GitHub repos through the SDK.\n */\n\n// =============================================================================\n// Configuration\n// =============================================================================\n\n/**\n * Configuration for the GitHub client\n */\nexport interface GitHubClientConfig {\n /** Morph API key (defaults to MORPH_API_KEY env var) */\n apiKey?: string;\n /** Default installation ID to use (optional, can be specified per-request) */\n installationId?: string;\n /** Base URL for the Morph API (defaults to https://api.morphllm.com) */\n baseUrl?: string;\n /** Request timeout in milliseconds */\n timeout?: number;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * A GitHub App installation (connected GitHub account)\n */\nexport interface Installation {\n /** Installation ID (use this for subsequent requests) */\n id: string;\n /** GitHub account login (username or org name) */\n accountLogin: string;\n /** Account type */\n accountType: \"User\" | \"Organization\";\n /** Custom display name (set in Morph dashboard) */\n displayName?: string;\n /** Whether check runs are disabled (only PR comments posted) */\n disableCheckRun: boolean;\n /** Whether to keep all previous PR comments (vs. replacing with latest) */\n keepCommentHistory: boolean;\n /** Browser automation model used for preview tests */\n model: string;\n}\n\n/**\n * Input for updating installation settings\n */\nexport interface UpdateInstallationInput {\n /** Installation ID to update */\n installationId: string;\n /** Custom display name */\n displayName?: string;\n /** Whether to disable check runs */\n disableCheckRun?: boolean;\n /** Whether to keep comment history */\n keepCommentHistory?: boolean;\n /** Browser automation model */\n model?: string;\n}\n\n/**\n * Site authentication credentials for a repo or project\n */\nexport interface SiteAuth {\n /** Login username or email */\n username: string | null;\n /** Login password */\n password: string | null;\n}\n\n/**\n * A repository with its Morph configuration\n */\nexport interface RepoConfig {\n /** Database UUID — use this for update/remove operations */\n id: string;\n /** GitHub's numeric repo ID */\n githubId: number;\n /** Full name including owner (e.g., \"acme/app\") */\n fullName: string;\n /** Repository name (e.g., \"app\") */\n name: string;\n /** Whether Morph tests are enabled */\n enabled: boolean;\n /** Whether to also test on mobile viewport */\n testMobile: boolean;\n /** Path filter — only trigger tests when files match this prefix */\n pathFilter: string | null;\n /** Custom instructions for the AI agent */\n customInstructions: string | null;\n /** Site authentication credentials */\n auth: SiteAuth | null;\n}\n\n/**\n * Input for updating a repo's configuration\n */\nexport interface UpdateRepoInput {\n /** Repo DB ID (from RepoConfig.id) */\n repoId: string;\n /** Whether Morph tests are enabled */\n enabled?: boolean;\n /** Whether to also test on mobile viewport */\n testMobile?: boolean;\n /** Path filter for conditional triggers */\n pathFilter?: string | null;\n /** Custom instructions for the AI agent */\n customInstructions?: string | null;\n /** Site auth credentials (null to clear) */\n auth?: { username?: string; password?: string; cookies?: unknown } | null;\n}\n\n/**\n * Input for syncing repos from GitHub\n */\nexport interface SyncReposInput {\n /** Installation ID to sync repos for */\n installationId: string;\n}\n\n/**\n * A monorepo sub-project scoped under a repo\n */\nexport interface Project {\n /** Project DB UUID */\n id: string;\n /** Parent repo DB UUID */\n repoId: string;\n /** Project name */\n name: string;\n /** Path filter within the repo */\n pathFilter: string | null;\n /** Whether tests are enabled */\n enabled: boolean;\n /** Whether to test on mobile viewport */\n testMobile: boolean;\n /** Custom instructions for the AI agent */\n customInstructions: string | null;\n /** Site authentication credentials */\n auth: SiteAuth | null;\n /** Creation timestamp (ISO 8601) */\n createdAt: string;\n}\n\n/**\n * Input for creating a project\n */\nexport interface CreateProjectInput {\n /** Parent repo DB ID */\n repoId: string;\n /** Project name (must be unique within the repo) */\n name: string;\n /** Path filter within the repo (e.g., \"packages/web/\") */\n pathFilter: string;\n /** Custom instructions for the AI agent */\n customInstructions?: string;\n}\n\n/**\n * Input for updating a project\n */\nexport interface UpdateProjectInput {\n /** Project DB ID */\n projectId: string;\n /** Whether tests are enabled */\n enabled?: boolean;\n /** Whether to test on mobile viewport */\n testMobile?: boolean;\n /** Path filter within the repo */\n pathFilter?: string | null;\n /** Custom instructions for the AI agent */\n customInstructions?: string | null;\n /** Site auth credentials (null to clear) */\n auth?: { username?: string; password?: string; cookies?: unknown } | null;\n}\n\n/**\n * Input for listing projects\n */\nexport interface ListProjectsInput {\n /** Parent repo DB ID */\n repoId: string;\n}\n\n/**\n * A GitHub repository\n */\nexport interface Repo {\n /** GitHub's numeric repo ID */\n id: number;\n /** Repository name (e.g., \"app\") */\n name: string;\n /** Full name including owner (e.g., \"acme/app\") */\n fullName: string;\n /** Whether the repo is private */\n private: boolean;\n /** Default branch name */\n defaultBranch?: string;\n}\n\n/**\n * A pull request (basic info)\n */\nexport interface PullRequest {\n /** PR number */\n number: number;\n /** PR title */\n title: string;\n /** PR description/body */\n body: string | null;\n /** PR state */\n state: \"open\" | \"closed\";\n /** Author's GitHub username */\n author: string;\n /** HEAD commit SHA */\n headSha: string;\n /** Base branch name */\n baseBranch: string;\n /** HEAD branch name */\n headBranch: string;\n /** Creation timestamp (ISO 8601) */\n createdAt: string;\n /** Last update timestamp (ISO 8601) */\n updatedAt: string;\n}\n\n/**\n * A pull request with full context (diff and files)\n */\nexport interface PullRequestWithContext extends PullRequest {\n /** Full unified diff */\n diff: string;\n /** List of changed files with patches */\n files: FileChange[];\n}\n\n/**\n * A file changed in a pull request\n */\nexport interface FileChange {\n /** File path */\n filename: string;\n /** Change status */\n status: \"added\" | \"removed\" | \"modified\" | \"renamed\";\n /** Number of lines added */\n additions: number;\n /** Number of lines deleted */\n deletions: number;\n /** Unified diff patch for this file */\n patch?: string;\n}\n\n/**\n * A deployment (e.g., Vercel preview)\n */\nexport interface Deployment {\n /** Deployment ID */\n id: number;\n /** Commit SHA this deployment is for */\n sha: string;\n /** Environment name (e.g., \"preview\", \"production\") */\n environment: string;\n /** Deployment state */\n state: \"pending\" | \"success\" | \"failure\" | \"error\" | \"inactive\" | \"in_progress\" | \"queued\";\n /** Preview/deployment URL (if available) */\n url: string | null;\n /** Creation timestamp (ISO 8601) */\n createdAt: string;\n}\n\n/**\n * A comment on a PR/issue\n */\nexport interface Comment {\n /** Comment ID */\n id: number;\n /** Comment body/content */\n body: string;\n /** Author's GitHub username */\n author: string;\n /** Creation timestamp (ISO 8601) */\n createdAt: string;\n /** Last update timestamp (ISO 8601) */\n updatedAt: string;\n}\n\n/**\n * A GitHub check run (CI status)\n */\nexport interface CheckRun {\n /** Check run ID */\n id: number;\n /** Check run name */\n name: string;\n /** Current status */\n status: \"queued\" | \"in_progress\" | \"completed\";\n /** Conclusion (only set when status is \"completed\") */\n conclusion?:\n | \"success\"\n | \"failure\"\n | \"neutral\"\n | \"cancelled\"\n | \"skipped\"\n | \"timed_out\"\n | \"action_required\";\n /** Start timestamp (ISO 8601) */\n startedAt?: string;\n /** Completion timestamp (ISO 8601) */\n completedAt?: string;\n}\n\n// =============================================================================\n// Input Types\n// =============================================================================\n\n/**\n * Input for listing repositories\n */\nexport interface ListReposInput {\n /** Installation ID to list repos for */\n installationId: string;\n}\n\n/**\n * Input for listing pull requests\n */\nexport interface ListPullRequestsInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Filter by PR state (default: \"open\") */\n state?: \"open\" | \"closed\" | \"all\";\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for getting a single pull request\n */\nexport interface GetPullRequestInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** PR number */\n number: number;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for listing deployments\n */\nexport interface ListDeploymentsInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Filter by commit SHA */\n sha?: string;\n /** Filter by environment name */\n environment?: string;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for listing comments on a PR\n */\nexport interface ListCommentsInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** PR number */\n pr: number;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for creating a comment\n */\nexport interface CreateCommentInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** PR number */\n pr: number;\n /** Comment body (Markdown supported) */\n body: string;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for updating a comment\n */\nexport interface UpdateCommentInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Comment ID to update */\n commentId: number;\n /** New comment body */\n body: string;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for deleting a comment\n */\nexport interface DeleteCommentInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Comment ID to delete */\n commentId: number;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for creating a check run\n */\nexport interface CreateCheckRunInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Commit SHA to create check run for */\n sha: string;\n /** Check run name (e.g., \"Preview Test\") */\n name: string;\n /** Initial status */\n status: \"queued\" | \"in_progress\";\n /** Output title */\n title?: string;\n /** Output summary (Markdown supported) */\n summary?: string;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n/**\n * Input for updating a check run\n */\nexport interface UpdateCheckRunInput {\n /** Repository owner */\n owner: string;\n /** Repository name */\n repo: string;\n /** Check run ID to update */\n checkRunId: number;\n /** New status */\n status?: \"queued\" | \"in_progress\" | \"completed\";\n /** Conclusion (required if status is \"completed\") */\n conclusion?: CheckRun[\"conclusion\"];\n /** Output title */\n title?: string;\n /** Output summary (Markdown supported) */\n summary?: string;\n /** Output text (detailed info, Markdown supported) */\n text?: string;\n /** Installation ID (uses default if not specified) */\n installationId?: string;\n}\n\n// =============================================================================\n// Error Types\n// =============================================================================\n\n/**\n * Error thrown by GitHub operations\n */\nexport class GitHubError extends Error {\n /** HTTP status code */\n status: number;\n /** Error code from API */\n code?: string;\n\n constructor(message: string, status: number, code?: string) {\n super(message);\n this.name = \"GitHubError\";\n this.status = status;\n this.code = code;\n }\n}\n\n/**\n * Error thrown when no installation is found or specified\n */\nexport class NoInstallationError extends GitHubError {\n constructor(message = \"No GitHub installation found. Connect GitHub at morphllm.com/dashboard/integrations/github\") {\n super(message, 404, \"NO_INSTALLATION\");\n }\n}\n\n/**\n * Error thrown when resource is not found\n */\nexport class NotFoundError extends GitHubError {\n constructor(resource: string) {\n super(`${resource} not found`, 404, \"NOT_FOUND\");\n }\n}\n\n/**\n * Error thrown when user lacks permission\n */\nexport class PermissionError extends GitHubError {\n constructor(message = \"Insufficient permissions for this operation\") {\n super(message, 403, \"PERMISSION_DENIED\");\n }\n}\n","/**\n * GitHub SDK Client\n *\n * Provides access to GitHub repositories, pull requests, deployments,\n * comments, and check runs through the user's connected GitHub account.\n *\n * All operations are proxied through the Morph API - installation tokens\n * are never exposed to the client.\n */\n\nimport type {\n GitHubClientConfig,\n Installation,\n Repo,\n RepoConfig,\n PullRequest,\n PullRequestWithContext,\n Deployment,\n Comment,\n CheckRun,\n Project,\n ListReposInput,\n ListPullRequestsInput,\n GetPullRequestInput,\n ListDeploymentsInput,\n ListCommentsInput,\n CreateCommentInput,\n UpdateCommentInput,\n DeleteCommentInput,\n CreateCheckRunInput,\n UpdateCheckRunInput,\n UpdateInstallationInput,\n UpdateRepoInput,\n SyncReposInput,\n CreateProjectInput,\n UpdateProjectInput,\n ListProjectsInput,\n} from \"./types.js\";\n\nimport { GitHubError, NoInstallationError, NotFoundError, PermissionError } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.morphllm.com\";\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * GitHub SDK Client\n *\n * @example\n * ```typescript\n * import { MorphClient } from '@morphllm/morphsdk';\n *\n * const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });\n *\n * // List installations\n * const installations = await morph.github.installations.list();\n *\n * // Get PR with context\n * const pr = await morph.github.pullRequests.get({\n * owner: \"acme\",\n * repo: \"app\",\n * number: 42\n * });\n * ```\n */\nexport class GitHubClient {\n private apiKey: string;\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n private defaultInstallationId?: string;\n\n /** Installation operations */\n public installations: {\n list: () => Promise<Installation[]>;\n get: (installationId: string) => Promise<Installation>;\n update: (input: UpdateInstallationInput) => Promise<Installation>;\n disconnect: (installationId: string) => Promise<{ success: boolean; alreadyDeleted: boolean }>;\n };\n\n /** Repository operations */\n public repos: {\n list: (input: ListReposInput) => Promise<RepoConfig[]>;\n get: (repoId: string) => Promise<RepoConfig>;\n update: (input: UpdateRepoInput) => Promise<RepoConfig>;\n remove: (repoId: string) => Promise<{ success: boolean; alreadyRemoved: boolean }>;\n sync: (input: SyncReposInput) => Promise<{ count: number }>;\n };\n\n /** Project operations (monorepo sub-projects) */\n public projects: {\n list: (input: ListProjectsInput) => Promise<Project[]>;\n create: (input: CreateProjectInput) => Promise<Project>;\n update: (input: UpdateProjectInput) => Promise<Project>;\n delete: (projectId: string) => Promise<{ success: boolean }>;\n };\n\n /** Pull request operations */\n public pullRequests: {\n list: (input: ListPullRequestsInput) => Promise<PullRequest[]>;\n get: (input: GetPullRequestInput) => Promise<PullRequestWithContext>;\n };\n\n /** Deployment operations */\n public deployments: {\n list: (input: ListDeploymentsInput) => Promise<Deployment[]>;\n };\n\n /** Comment operations */\n public comments: {\n list: (input: ListCommentsInput) => Promise<Comment[]>;\n create: (input: CreateCommentInput) => Promise<Comment>;\n update: (input: UpdateCommentInput) => Promise<Comment>;\n delete: (input: DeleteCommentInput) => Promise<void>;\n };\n\n /** Check run operations */\n public checkRuns: {\n create: (input: CreateCheckRunInput) => Promise<CheckRun>;\n update: (input: UpdateCheckRunInput) => Promise<CheckRun>;\n };\n\n /**\n * Get the GitHub App installation URL.\n * Users visit this URL once to install the Morph GitHub App on their account/org.\n */\n public getInstallUrl(): string {\n return \"https://github.com/apps/morph-subagents/installations/new\";\n }\n\n constructor(config: GitHubClientConfig = {}) {\n this.apiKey = config.apiKey || process.env.MORPH_API_KEY || \"\";\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n this.defaultInstallationId = config.installationId;\n\n if (!this.apiKey) {\n throw new Error(\"API key required. Set MORPH_API_KEY or pass apiKey in config.\");\n }\n\n // Bind all methods\n this.installations = {\n list: this.listInstallations.bind(this),\n get: this.getInstallation.bind(this),\n update: this.updateInstallation.bind(this),\n disconnect: this.disconnectInstallation.bind(this),\n };\n\n this.repos = {\n list: this.listRepos.bind(this),\n get: this.getRepo.bind(this),\n update: this.updateRepo.bind(this),\n remove: this.removeRepo.bind(this),\n sync: this.syncRepos.bind(this),\n };\n\n this.projects = {\n list: this.listProjects.bind(this),\n create: this.createProject.bind(this),\n update: this.updateProject.bind(this),\n delete: this.deleteProject.bind(this),\n };\n\n this.pullRequests = {\n list: this.listPullRequests.bind(this),\n get: this.getPullRequest.bind(this),\n };\n\n this.deployments = {\n list: this.listDeployments.bind(this),\n };\n\n this.comments = {\n list: this.listComments.bind(this),\n create: this.createComment.bind(this),\n update: this.updateComment.bind(this),\n delete: this.deleteComment.bind(this),\n };\n\n this.checkRuns = {\n create: this.createCheckRun.bind(this),\n update: this.updateCheckRun.bind(this),\n };\n }\n\n /**\n * Make an authenticated API request\n */\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n if (this.debug) {\n console.log(`[GitHub SDK] ${method} ${path}`, body || \"\");\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const message = errorData.error || errorData.detail || errorData.message || response.statusText;\n\n if (this.debug) {\n console.error(`[GitHub SDK] Error ${response.status}:`, message);\n }\n\n // Map to specific error types\n if (response.status === 404) {\n if (message.includes(\"installation\")) {\n throw new NoInstallationError(message);\n }\n throw new NotFoundError(message);\n }\n if (response.status === 403) {\n throw new PermissionError(message);\n }\n throw new GitHubError(message, response.status, errorData.code);\n }\n\n const data = await response.json();\n\n if (this.debug) {\n console.log(`[GitHub SDK] Response:`, JSON.stringify(data).slice(0, 200));\n }\n\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof GitHubError) {\n throw error;\n }\n\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new GitHubError(\"Request timeout\", 408, \"TIMEOUT\");\n }\n\n throw new GitHubError(\n error instanceof Error ? error.message : \"Unknown error\",\n 500,\n \"UNKNOWN\"\n );\n }\n }\n\n /**\n * Get the installation ID to use for a request\n */\n private getInstallationId(input?: { installationId?: string }): string | undefined {\n return input?.installationId || this.defaultInstallationId;\n }\n\n // ==========================================================================\n // Installations\n // ==========================================================================\n\n private async listInstallations(): Promise<Installation[]> {\n return this.request<Installation[]>(\"GET\", \"/api/v1/github/installations\");\n }\n\n private async getInstallation(installationId: string): Promise<Installation> {\n return this.request<Installation>(\"GET\", `/api/v1/github/installations/${installationId}`);\n }\n\n private async updateInstallation(input: UpdateInstallationInput): Promise<Installation> {\n if (this.debug) console.log(\"[GitHub SDK] updateInstallation\", input.installationId);\n const { installationId, ...body } = input;\n return this.request<Installation>(\"PATCH\", `/api/v1/github/installations/${installationId}`, body);\n }\n\n private async disconnectInstallation(installationId: string): Promise<{ success: boolean; alreadyDeleted: boolean }> {\n if (this.debug) console.log(\"[GitHub SDK] disconnectInstallation\", installationId);\n return this.request<{ success: boolean; alreadyDeleted: boolean }>(\"DELETE\", `/api/v1/github/installations/${installationId}`);\n }\n\n // ==========================================================================\n // Repositories\n // ==========================================================================\n\n private async listRepos(input: ListReposInput): Promise<RepoConfig[]> {\n const installationId = input.installationId || this.defaultInstallationId;\n if (!installationId) {\n throw new NoInstallationError(\"installationId required. Call installations.list() first.\");\n }\n return this.request<RepoConfig[]>(\"GET\", `/api/v1/github/installations/${installationId}/repos`);\n }\n\n private async getRepo(repoId: string): Promise<RepoConfig> {\n if (this.debug) console.log(\"[GitHub SDK] getRepo\", repoId);\n return this.request<RepoConfig>(\"GET\", `/api/v1/github/repos/${repoId}`);\n }\n\n private async updateRepo(input: UpdateRepoInput): Promise<RepoConfig> {\n if (this.debug) console.log(\"[GitHub SDK] updateRepo\", input.repoId);\n const { repoId, ...body } = input;\n return this.request<RepoConfig>(\"PATCH\", `/api/v1/github/repos/${repoId}`, body);\n }\n\n private async removeRepo(repoId: string): Promise<{ success: boolean; alreadyRemoved: boolean }> {\n if (this.debug) console.log(\"[GitHub SDK] removeRepo\", repoId);\n return this.request<{ success: boolean; alreadyRemoved: boolean }>(\"DELETE\", `/api/v1/github/repos/${repoId}`);\n }\n\n private async syncRepos(input: SyncReposInput): Promise<{ count: number }> {\n const installationId = input.installationId || this.defaultInstallationId;\n if (!installationId) {\n throw new NoInstallationError(\"installationId required. Call installations.list() first.\");\n }\n if (this.debug) console.log(\"[GitHub SDK] syncRepos\", installationId);\n return this.request<{ count: number }>(\"POST\", `/api/v1/github/installations/${installationId}/repos/sync`);\n }\n\n // ==========================================================================\n // Projects (monorepo sub-projects)\n // ==========================================================================\n\n private async listProjects(input: ListProjectsInput): Promise<Project[]> {\n if (this.debug) console.log(\"[GitHub SDK] listProjects\", input.repoId);\n return this.request<Project[]>(\"GET\", `/api/v1/github/repos/${input.repoId}/projects`);\n }\n\n private async createProject(input: CreateProjectInput): Promise<Project> {\n if (this.debug) console.log(\"[GitHub SDK] createProject\", input.repoId, input.name);\n const { repoId, ...body } = input;\n return this.request<Project>(\"POST\", `/api/v1/github/repos/${repoId}/projects`, body);\n }\n\n private async updateProject(input: UpdateProjectInput): Promise<Project> {\n if (this.debug) console.log(\"[GitHub SDK] updateProject\", input.projectId);\n const { projectId, ...body } = input;\n return this.request<Project>(\"PATCH\", `/api/v1/github/projects/${projectId}`, body);\n }\n\n private async deleteProject(projectId: string): Promise<{ success: boolean }> {\n if (this.debug) console.log(\"[GitHub SDK] deleteProject\", projectId);\n return this.request<{ success: boolean }>(\"DELETE\", `/api/v1/github/projects/${projectId}`);\n }\n\n // ==========================================================================\n // Pull Requests\n // ==========================================================================\n\n private async listPullRequests(input: ListPullRequestsInput): Promise<PullRequest[]> {\n const installationId = this.getInstallationId(input);\n const params = new URLSearchParams({\n owner: input.owner,\n repo: input.repo,\n ...(input.state && { state: input.state }),\n ...(installationId && { installationId }),\n });\n return this.request<PullRequest[]>(\"GET\", `/api/v1/github/pulls?${params}`);\n }\n\n private async getPullRequest(input: GetPullRequestInput): Promise<PullRequestWithContext> {\n const installationId = this.getInstallationId(input);\n const params = new URLSearchParams({\n owner: input.owner,\n repo: input.repo,\n ...(installationId && { installationId }),\n });\n return this.request<PullRequestWithContext>(\n \"GET\",\n `/api/v1/github/pulls/${input.number}?${params}`\n );\n }\n\n // ==========================================================================\n // Deployments\n // ==========================================================================\n\n private async listDeployments(input: ListDeploymentsInput): Promise<Deployment[]> {\n const installationId = this.getInstallationId(input);\n const params = new URLSearchParams({\n owner: input.owner,\n repo: input.repo,\n ...(input.sha && { sha: input.sha }),\n ...(input.environment && { environment: input.environment }),\n ...(installationId && { installationId }),\n });\n return this.request<Deployment[]>(\"GET\", `/api/v1/github/deployments?${params}`);\n }\n\n // ==========================================================================\n // Comments\n // ==========================================================================\n\n private async listComments(input: ListCommentsInput): Promise<Comment[]> {\n const installationId = this.getInstallationId(input);\n const params = new URLSearchParams({\n owner: input.owner,\n repo: input.repo,\n pr: String(input.pr),\n ...(installationId && { installationId }),\n });\n return this.request<Comment[]>(\"GET\", `/api/v1/github/comments?${params}`);\n }\n\n private async createComment(input: CreateCommentInput): Promise<Comment> {\n const installationId = this.getInstallationId(input);\n return this.request<Comment>(\"POST\", \"/api/v1/github/comments\", {\n owner: input.owner,\n repo: input.repo,\n pr: input.pr,\n body: input.body,\n ...(installationId && { installationId }),\n });\n }\n\n private async updateComment(input: UpdateCommentInput): Promise<Comment> {\n const installationId = this.getInstallationId(input);\n return this.request<Comment>(\"PATCH\", `/api/v1/github/comments/${input.commentId}`, {\n owner: input.owner,\n repo: input.repo,\n body: input.body,\n ...(installationId && { installationId }),\n });\n }\n\n private async deleteComment(input: DeleteCommentInput): Promise<void> {\n const installationId = this.getInstallationId(input);\n const params = new URLSearchParams({\n owner: input.owner,\n repo: input.repo,\n ...(installationId && { installationId }),\n });\n await this.request<void>(\"DELETE\", `/api/v1/github/comments/${input.commentId}?${params}`);\n }\n\n // ==========================================================================\n // Check Runs\n // ==========================================================================\n\n private async createCheckRun(input: CreateCheckRunInput): Promise<CheckRun> {\n const installationId = this.getInstallationId(input);\n return this.request<CheckRun>(\"POST\", \"/api/v1/github/check-runs\", {\n owner: input.owner,\n repo: input.repo,\n sha: input.sha,\n name: input.name,\n status: input.status,\n ...(input.title && { title: input.title }),\n ...(input.summary && { summary: input.summary }),\n ...(installationId && { installationId }),\n });\n }\n\n private async updateCheckRun(input: UpdateCheckRunInput): Promise<CheckRun> {\n const installationId = this.getInstallationId(input);\n return this.request<CheckRun>(\"PATCH\", `/api/v1/github/check-runs/${input.checkRunId}`, {\n owner: input.owner,\n repo: input.repo,\n ...(input.status && { status: input.status }),\n ...(input.conclusion && { conclusion: input.conclusion }),\n ...(input.title && { title: input.title }),\n ...(input.summary && { summary: input.summary }),\n ...(input.text && { text: input.text }),\n ...(installationId && { installationId }),\n });\n }\n}\n","/**\n * OpenAI Tool Factory for MorphClient\n * \n * Creates OpenAI-compatible tools that inherit the API key from MorphClient.\n */\n\nimport type { MorphClientConfig } from '../client.js';\nimport { createWarpGrepTool } from '../tools/warp_grep/openai.js';\nimport { createCodebaseSearchTool } from '../tools/codebase_search/openai.js';\nimport { createEditFileTool } from '../tools/fastapply/openai.js';\nimport type { WarpGrepToolConfig } from '../tools/warp_grep/types.js';\nimport type { CodebaseSearchConfig } from '../tools/codebase_search/types.js';\nimport type { EditFileConfig } from '../tools/fastapply/types.js';\n\n/**\n * Factory for creating OpenAI-compatible tools with inherited API key\n * \n * @example\n * ```typescript\n * const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });\n * \n * const grepTool = morph.openai.createWarpGrepTool({ repoRoot: '.' });\n * const searchTool = morph.openai.createCodebaseSearchTool({ repoId: 'my-project' });\n * const editTool = morph.openai.createEditFileTool({ baseDir: './src' });\n * \n * // Use with OpenAI client\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o',\n * tools: [grepTool, searchTool, editTool],\n * messages: [{ role: 'user', content: 'Find and fix the bug' }]\n * });\n * ```\n */\nexport class OpenAIToolFactory {\n constructor(private config: MorphClientConfig) {}\n\n /**\n * Create an OpenAI-compatible warp grep tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns OpenAI ChatCompletionTool with execute and formatResult methods\n */\n createWarpGrepTool(toolConfig: Omit<WarpGrepToolConfig, 'morphApiKey'>) {\n return createWarpGrepTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n }\n\n /**\n * Create an OpenAI-compatible codebase search tool\n * \n * @param toolConfig - Tool configuration with repoId (apiKey inherited from MorphClient)\n * @returns OpenAI ChatCompletionTool with execute and formatResult methods\n */\n createCodebaseSearchTool(toolConfig: Omit<CodebaseSearchConfig, 'apiKey'>) {\n return createCodebaseSearchTool({ \n ...toolConfig, \n apiKey: this.config.apiKey,\n });\n }\n\n /**\n * Create an OpenAI-compatible edit file tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns OpenAI ChatCompletionTool with execute and formatResult methods\n */\n createEditFileTool(toolConfig: Omit<EditFileConfig, 'morphApiKey'> = {}) {\n return createEditFileTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n }\n}\n\n","/**\n * Anthropic Tool Factory for MorphClient\n * \n * Creates Anthropic-compatible tools that inherit the API key from MorphClient.\n */\n\nimport type { MorphClientConfig } from '../client.js';\nimport { createWarpGrepTool } from '../tools/warp_grep/anthropic.js';\nimport { createCodebaseSearchTool } from '../tools/codebase_search/anthropic.js';\nimport { createEditFileTool } from '../tools/fastapply/anthropic.js';\nimport type { WarpGrepToolConfig } from '../tools/warp_grep/types.js';\nimport type { CodebaseSearchConfig } from '../tools/codebase_search/types.js';\nimport type { EditFileConfig } from '../tools/fastapply/types.js';\n\n/**\n * Factory for creating Anthropic-compatible tools with inherited API key\n * \n * @example\n * ```typescript\n * const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });\n * \n * const grepTool = morph.anthropic.createWarpGrepTool({ repoRoot: '.' });\n * const searchTool = morph.anthropic.createCodebaseSearchTool({ repoId: 'my-project' });\n * const editTool = morph.anthropic.createEditFileTool({ baseDir: './src' });\n * \n * // Use with Anthropic client\n * const response = await anthropic.messages.create({\n * model: 'claude-sonnet-4-5-20250929',\n * tools: [grepTool, searchTool, editTool],\n * messages: [{ role: 'user', content: 'Find and fix the bug' }]\n * });\n * ```\n */\nexport class AnthropicToolFactory {\n constructor(private config: MorphClientConfig) {}\n\n /**\n * Create an Anthropic-compatible warp grep tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns Anthropic Tool with execute and formatResult methods\n */\n createWarpGrepTool(toolConfig: Omit<WarpGrepToolConfig, 'morphApiKey'>) {\n return createWarpGrepTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n\n }\n\n /**\n * Create an Anthropic-compatible codebase search tool\n * \n * @param toolConfig - Tool configuration with repoId (apiKey inherited from MorphClient)\n * @returns Anthropic Tool with execute and formatResult methods\n */\n createCodebaseSearchTool(toolConfig: Omit<CodebaseSearchConfig, 'apiKey'>) {\n return createCodebaseSearchTool({ \n ...toolConfig, \n apiKey: this.config.apiKey,\n });\n }\n\n /**\n * Create an Anthropic-compatible edit file tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns Anthropic Tool with execute and formatResult methods\n */\n createEditFileTool(toolConfig: Omit<EditFileConfig, 'morphApiKey'> = {}) {\n return createEditFileTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n }\n}\n\n","/**\n * Vercel AI SDK Tool Factory for MorphClient\n * \n * Creates Vercel AI SDK-compatible tools that inherit the API key from MorphClient.\n */\n\nimport type { MorphClientConfig } from '../client.js';\nimport { createWarpGrepTool } from '../tools/warp_grep/vercel.js';\nimport { createCodebaseSearchTool } from '../tools/codebase_search/vercel.js';\nimport { createEditFileTool } from '../tools/fastapply/vercel.js';\nimport type { WarpGrepToolConfig } from '../tools/warp_grep/types.js';\nimport type { CodebaseSearchConfig } from '../tools/codebase_search/types.js';\nimport type { EditFileConfig } from '../tools/fastapply/types.js';\n\n/**\n * Factory for creating Vercel AI SDK-compatible tools with inherited API key\n * \n * @example\n * ```typescript\n * const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });\n * \n * const grepTool = morph.vercel.createWarpGrepTool({ repoRoot: '.' });\n * const searchTool = morph.vercel.createCodebaseSearchTool({ repoId: 'my-project' });\n * const editTool = morph.vercel.createEditFileTool({ baseDir: './src' });\n * \n * // Use with Vercel AI SDK\n * const result = await generateText({\n * model: anthropic('claude-sonnet-4-5-20250929'),\n * tools: { grep: grepTool, search: searchTool, edit: editTool },\n * prompt: 'Find and fix the bug'\n * });\n * ```\n */\nexport class VercelToolFactory {\n constructor(private config: MorphClientConfig) {}\n\n /**\n * Create a Vercel AI SDK-compatible warp grep tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns Vercel AI SDK tool\n */\n createWarpGrepTool(toolConfig: Omit<WarpGrepToolConfig, 'morphApiKey'>) {\n return createWarpGrepTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n }\n\n /**\n * Create a Vercel AI SDK-compatible codebase search tool\n * \n * @param toolConfig - Tool configuration with repoId (apiKey inherited from MorphClient)\n * @returns Vercel AI SDK tool\n */\n createCodebaseSearchTool(toolConfig: Omit<CodebaseSearchConfig, 'apiKey'>) {\n return createCodebaseSearchTool({ \n ...toolConfig, \n apiKey: this.config.apiKey,\n });\n }\n\n /**\n * Create a Vercel AI SDK-compatible edit file tool\n * \n * @param toolConfig - Tool configuration (morphApiKey inherited from MorphClient)\n * @returns Vercel AI SDK tool\n */\n createEditFileTool(toolConfig: Omit<EditFileConfig, 'morphApiKey'> = {}) {\n return createEditFileTool({ \n ...toolConfig, \n morphApiKey: this.config.apiKey,\n });\n }\n}\n\n","/**\n * Unified Morph SDK Client\n * \n * Provides access to all Morph tools through a single interface\n * \n * @example\n * ```typescript\n * import { MorphClient } from '@morphllm/morphsdk';\n * \n * const morph = new MorphClient({ \n * apiKey: process.env.MORPH_API_KEY,\n * debug: true,\n * timeout: 60000\n * });\n * \n * // Direct execution\n * await morph.fastApply.execute({ target_filepath: 'src/index.ts', ... });\n * await morph.warpGrep.execute({ query: 'Find auth', repoRoot: '.' });\n * await morph.codebaseSearch.search({ query: 'auth logic', repoId: 'x' });\n * \n * // Tool creation for AI agents (API key inherited)\n * const grepTool = morph.openai.createWarpGrepTool({ repoRoot: '.' });\n * const searchTool = morph.anthropic.createCodebaseSearchTool({ repoId: 'x' });\n * const editTool = morph.vercel.createEditFileTool({ baseDir: './src' });\n * \n * // Use tools with OpenAI\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4o',\n * tools: [grepTool],\n * messages: [{ role: 'user', content: 'Find the bug' }]\n * });\n * ```\n */\n\nimport type { RetryConfig } from './tools/utils/resilience.js';\nimport { FastApplyClient } from './tools/fastapply/core.js';\nimport { CodebaseSearchClient } from './tools/codebase_search/core.js';\nimport { BrowserClient } from './tools/browser/core.js';\nimport { WarpGrepClient } from './tools/warp_grep/client.js';\nimport { GitHubClient } from './tools/github/core.js';\nimport { MorphGit } from './git/index.js';\nimport { OpenAIRouter, AnthropicRouter, GeminiRouter, RawRouter } from './modelrouter/core.js';\nimport { OpenAIToolFactory, AnthropicToolFactory, VercelToolFactory } from './factories/index.js';\n\n/**\n * Configuration for the MorphClient\n */\nexport interface MorphClientConfig {\n /** Morph API key for authentication (defaults to MORPH_API_KEY env var) */\n apiKey?: string;\n /** Enable debug logging across all tools */\n debug?: boolean;\n /** Default timeout in milliseconds for API requests */\n timeout?: number;\n /** Retry configuration for failed requests */\n retryConfig?: RetryConfig;\n /** GitHub-specific configuration */\n github?: {\n /** Default installation ID for GitHub operations */\n installationId?: string;\n };\n}\n\n/**\n * Unified Morph SDK Client\n * \n * Provides access to all Morph tools through a single interface:\n * - fastApply: AI-powered file editing with intelligent merging\n * - codebaseSearch: Semantic code search\n * - warpGrep: Fast code search with ripgrep\n * - browser: AI-powered browser automation\n * - git: Version control operations\n * - routers: Intelligent model selection (OpenAI, Anthropic, Gemini)\n * - openai/anthropic/vercel: Tool factories for agent frameworks\n */\nexport class MorphClient {\n /** Client configuration */\n public config: MorphClientConfig;\n\n /** FastApply tool for editing files with AI-powered merge */\n public fastApply: FastApplyClient;\n\n /** CodebaseSearch tool for semantic code search */\n public codebaseSearch: CodebaseSearchClient;\n\n /** WarpGrep tool for fast code search using ripgrep */\n public warpGrep: WarpGrepClient;\n\n /** Browser tool for AI-powered browser automation */\n public browser: BrowserClient;\n\n /** GitHub tool for PR context, comments, and check runs */\n public github: GitHubClient;\n\n /** Git tool for version control operations */\n public git: MorphGit;\n\n /** Model routers for intelligent model selection */\n public routers: {\n openai: OpenAIRouter;\n anthropic: AnthropicRouter;\n gemini: GeminiRouter;\n raw: RawRouter;\n };\n\n /** OpenAI-compatible tool factories */\n public openai: OpenAIToolFactory;\n\n /** Anthropic-compatible tool factories */\n public anthropic: AnthropicToolFactory;\n\n /** Vercel AI SDK tool factories */\n public vercel: VercelToolFactory;\n\n /**\n * Create a new Morph SDK client\n * \n * @param config - Client configuration (apiKey, debug, timeout, retryConfig)\n * \n * @example\n * ```typescript\n * const morph = new MorphClient({ \n * apiKey: process.env.MORPH_API_KEY,\n * debug: true,\n * timeout: 60000\n * });\n * ```\n */\n constructor(config: MorphClientConfig = {}) {\n this.config = config;\n\n // Initialize all sub-clients with shared config\n this.fastApply = new FastApplyClient({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n });\n\n this.codebaseSearch = new CodebaseSearchClient({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n });\n\n this.warpGrep = new WarpGrepClient({\n morphApiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n });\n\n this.browser = new BrowserClient({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n });\n\n this.github = new GitHubClient({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n installationId: config.github?.installationId,\n });\n\n this.git = new MorphGit({\n apiKey: config.apiKey,\n retryConfig: config.retryConfig,\n });\n\n this.routers = {\n openai: new OpenAIRouter({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n }),\n anthropic: new AnthropicRouter({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n }),\n gemini: new GeminiRouter({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n }),\n raw: new RawRouter({\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n }),\n };\n\n // Initialize tool factories\n this.openai = new OpenAIToolFactory(config);\n this.anthropic = new AnthropicToolFactory(config);\n this.vercel = new VercelToolFactory(config);\n }\n}\n"],"mappings":"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","names":["createWarpGrepTool","createCodebaseSearchTool","createEditFileTool","createWarpGrepTool","createCodebaseSearchTool","createEditFileTool"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-63WE2C5R.js";
|
|
5
5
|
import {
|
|
6
6
|
executeEditFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R3BSIJCL.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -91,4 +91,4 @@ export {
|
|
|
91
91
|
openai_default,
|
|
92
92
|
openai_exports
|
|
93
93
|
};
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
94
|
+
//# sourceMappingURL=chunk-A3PK4H7A.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-63WE2C5R.js";
|
|
5
5
|
import {
|
|
6
6
|
executeEditFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R3BSIJCL.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -79,4 +79,4 @@ export {
|
|
|
79
79
|
getSystemPrompt,
|
|
80
80
|
anthropic_exports
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-JD4H6U3Z.js.map
|
|
@@ -82,7 +82,7 @@ async function executeEditFile(input, config = {}) {
|
|
|
82
82
|
}
|
|
83
83
|
if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);
|
|
84
84
|
}
|
|
85
|
-
const mergedCode = await callMorphAPI2(originalCode, input.code_edit, input.instructions, input.target_filepath, config);
|
|
85
|
+
const { content: mergedCode, completionId } = await callMorphAPI2(originalCode, input.code_edit, input.instructions, input.target_filepath, config);
|
|
86
86
|
const udiff = config.generateUdiff !== false ? generateUdiff2(originalCode, mergedCode, input.target_filepath) : void 0;
|
|
87
87
|
if (config.autoWrite !== false) {
|
|
88
88
|
await writeFile(fullPath, mergedCode, "utf-8");
|
|
@@ -93,7 +93,8 @@ async function executeEditFile(input, config = {}) {
|
|
|
93
93
|
success: true,
|
|
94
94
|
filepath: input.target_filepath,
|
|
95
95
|
udiff,
|
|
96
|
-
changes
|
|
96
|
+
changes,
|
|
97
|
+
completionId
|
|
97
98
|
};
|
|
98
99
|
} catch (error) {
|
|
99
100
|
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
@@ -111,4 +112,4 @@ export {
|
|
|
111
112
|
FastApplyClient,
|
|
112
113
|
executeEditFile
|
|
113
114
|
};
|
|
114
|
-
//# sourceMappingURL=chunk-
|
|
115
|
+
//# sourceMappingURL=chunk-R3BSIJCL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../tools/fastapply/core.ts"],"sourcesContent":["/**\n * Core implementation of Morph Fast Apply\n *\n * This module provides file-based operations that require Node.js.\n * For edge-compatible code-in/code-out operations, use applyEdit from ./apply.ts\n */\n\nimport { join, resolve, relative } from 'path';\nimport type {\n EditFileInput,\n EditFileResult,\n EditFileConfig,\n} from './types.js';\n\n// Re-export edge-compatible functions\nexport { applyEdit, generateUdiff, countChanges, callMorphAPI } from './apply.js';\n\nconst DEFAULT_CONFIG: Required<Omit<EditFileConfig, 'morphApiKey' | 'systemPrompt' | 'retryConfig' | 'description'>> = {\n morphApiUrl: 'https://api.morphllm.com',\n baseDir: process.cwd(),\n generateUdiff: true,\n autoWrite: true,\n timeout: 30000,\n debug: false,\n};\n\n/**\n * FastApply client for programmatic file editing\n * Note: This client requires Node.js for file operations\n */\nexport class FastApplyClient {\n private config: EditFileConfig;\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n morphApiKey: config.apiKey,\n morphApiUrl: DEFAULT_CONFIG.morphApiUrl,\n debug: config.debug,\n timeout: config.timeout || DEFAULT_CONFIG.timeout,\n retryConfig: config.retryConfig,\n generateUdiff: DEFAULT_CONFIG.generateUdiff,\n autoWrite: DEFAULT_CONFIG.autoWrite,\n };\n }\n\n /**\n * Execute a file edit operation\n *\n * @param input - Edit parameters including filepath, instructions, and code_edit\n * @param overrides - Optional config overrides for this operation\n * @returns Edit result with success status and changes\n */\n async execute(input: EditFileInput, overrides?: Partial<EditFileConfig>): Promise<EditFileResult> {\n return executeEditFile(input, { ...this.config, ...overrides });\n }\n\n /**\n * Apply an edit to code directly without file I/O\n *\n * Useful for sandbox environments or when you manage your own file system.\n * Compatible with the earlier OpenAI client API contract.\n *\n * @param input - Code and edit parameters\n * @param overrides - Optional config overrides for this operation\n * @returns Result with merged code\n *\n * @example\n * ```typescript\n * const result = await client.applyEdit({\n * originalCode: 'function hello() { return \"world\"; }',\n * codeEdit: 'function hello() { return \"universe\"; }',\n * instructions: 'Change return value'\n * });\n * console.log(result.mergedCode);\n * ```\n */\n async applyEdit(input: import('./types.js').ApplyEditInput, overrides?: Partial<import('./types.js').ApplyEditConfig>): Promise<import('./types.js').ApplyEditResult> {\n const { applyEdit } = await import('./apply.js');\n return applyEdit(input, { ...this.config, ...overrides });\n }\n}\n\n/**\n * Execute a file edit using Morph Fast Apply\n * Note: This function requires Node.js for file I/O\n */\nexport async function executeEditFile(\n input: EditFileInput,\n config: EditFileConfig = {}\n): Promise<EditFileResult> {\n const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;\n const fullPath = resolve(join(baseDir, input.target_filepath));\n const debug = config.debug || false;\n\n // Security: ensure file is within baseDir\n const relativePath = relative(baseDir, fullPath);\n if (relativePath.startsWith('..') || fullPath === baseDir) {\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`,\n };\n }\n\n try {\n if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);\n\n // Dynamic import to avoid loading Node.js fs module at module evaluation time\n const { readFile, writeFile } = await import('fs/promises');\n const { callMorphAPI, generateUdiff, countChanges } = await import('./apply.js');\n\n // Handle both existing and non-existent files\n let originalCode = '';\n try {\n originalCode = await readFile(fullPath, 'utf-8');\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n throw error; // Re-throw if it's not a \"file not found\" error\n }\n // File doesn't exist, proceed with empty content (will create new file)\n if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);\n }\n\n const mergedCode = await callMorphAPI(originalCode, input.code_edit, input.instructions, input.target_filepath, config);\n\n const udiff = config.generateUdiff !== false ? generateUdiff(originalCode, mergedCode, input.target_filepath) : undefined;\n\n if (config.autoWrite !== false) {\n await writeFile(fullPath, mergedCode, 'utf-8');\n if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);\n }\n\n const changes = countChanges(originalCode, mergedCode);\n\n return {\n success: true,\n filepath: input.target_filepath,\n udiff,\n changes,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n"],"mappings":";AAOA,SAAS,MAAM,SAAS,gBAAgB;AAUxC,IAAM,iBAAiH;AAAA,EACrH,aAAa;AAAA,EACb,SAAS,QAAQ,IAAI;AAAA,EACrB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAMO,IAAM,kBAAN,MAAsB;AAAA,EACnB;AAAA,EAER,YAAY,SAAoF,CAAC,GAAG;AAClG,SAAK,SAAS;AAAA,MACZ,aAAa,OAAO;AAAA,MACpB,aAAa,eAAe;AAAA,MAC5B,OAAO,OAAO;AAAA,MACd,SAAS,OAAO,WAAW,eAAe;AAAA,MAC1C,aAAa,OAAO;AAAA,MACpB,eAAe,eAAe;AAAA,MAC9B,WAAW,eAAe;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAQ,OAAsB,WAA8D;AAChG,WAAO,gBAAgB,OAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,UAAU,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAM,UAAU,OAA4C,WAA0G;AACpK,UAAM,EAAE,WAAAA,WAAU,IAAI,MAAM,OAAO,4BAAY;AAC/C,WAAOA,WAAU,OAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,UAAU,CAAC;AAAA,EAC1D;AACF;AAMA,eAAsB,gBACpB,OACA,SAAyB,CAAC,GACD;AACzB,QAAM,UAAU,OAAO,WAAW,eAAe;AACjD,QAAM,WAAW,QAAQ,KAAK,SAAS,MAAM,eAAe,CAAC;AAC7D,QAAM,QAAQ,OAAO,SAAS;AAG9B,QAAM,eAAe,SAAS,SAAS,QAAQ;AAC/C,MAAI,aAAa,WAAW,IAAI,KAAK,aAAa,SAAS;AACzD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,MAAM;AAAA,MAChB,SAAS,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,EAAE;AAAA,MAC5D,OAAO,sBAAsB,MAAM,eAAe;AAAA,IACpD;AAAA,EACF;AAEA,MAAI;AACF,QAAI,MAAO,SAAQ,IAAI,6BAA6B,MAAM,eAAe,EAAE;AAG3E,UAAM,EAAE,UAAU,UAAU,IAAI,MAAM,OAAO,aAAa;AAC1D,UAAM,EAAE,cAAAC,eAAc,eAAAC,gBAAe,cAAAC,cAAa,IAAI,MAAM,OAAO,4BAAY;AAG/E,QAAI,eAAe;AACnB,QAAI;AACF,qBAAe,MAAM,SAAS,UAAU,OAAO;AAAA,IACjD,SAAS,OAAY;AACnB,UAAI,MAAM,SAAS,UAAU;AAC3B,cAAM;AAAA,MACR;AAEA,UAAI,MAAO,SAAQ,IAAI,sDAAsD;AAAA,IAC/E;AAEA,UAAM,aAAa,MAAMF,cAAa,cAAc,MAAM,WAAW,MAAM,cAAc,MAAM,iBAAiB,MAAM;
|
|
1
|
+
{"version":3,"sources":["../tools/fastapply/core.ts"],"sourcesContent":["/**\n * Core implementation of Morph Fast Apply\n *\n * This module provides file-based operations that require Node.js.\n * For edge-compatible code-in/code-out operations, use applyEdit from ./apply.ts\n */\n\nimport { join, resolve, relative } from 'path';\nimport type {\n EditFileInput,\n EditFileResult,\n EditFileConfig,\n} from './types.js';\n\n// Re-export edge-compatible functions\nexport { applyEdit, generateUdiff, countChanges, callMorphAPI } from './apply.js';\n\nconst DEFAULT_CONFIG: Required<Omit<EditFileConfig, 'morphApiKey' | 'systemPrompt' | 'retryConfig' | 'description'>> = {\n morphApiUrl: 'https://api.morphllm.com',\n baseDir: process.cwd(),\n generateUdiff: true,\n autoWrite: true,\n timeout: 30000,\n debug: false,\n};\n\n/**\n * FastApply client for programmatic file editing\n * Note: This client requires Node.js for file operations\n */\nexport class FastApplyClient {\n private config: EditFileConfig;\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n morphApiKey: config.apiKey,\n morphApiUrl: DEFAULT_CONFIG.morphApiUrl,\n debug: config.debug,\n timeout: config.timeout || DEFAULT_CONFIG.timeout,\n retryConfig: config.retryConfig,\n generateUdiff: DEFAULT_CONFIG.generateUdiff,\n autoWrite: DEFAULT_CONFIG.autoWrite,\n };\n }\n\n /**\n * Execute a file edit operation\n *\n * @param input - Edit parameters including filepath, instructions, and code_edit\n * @param overrides - Optional config overrides for this operation\n * @returns Edit result with success status and changes\n */\n async execute(input: EditFileInput, overrides?: Partial<EditFileConfig>): Promise<EditFileResult> {\n return executeEditFile(input, { ...this.config, ...overrides });\n }\n\n /**\n * Apply an edit to code directly without file I/O\n *\n * Useful for sandbox environments or when you manage your own file system.\n * Compatible with the earlier OpenAI client API contract.\n *\n * @param input - Code and edit parameters\n * @param overrides - Optional config overrides for this operation\n * @returns Result with merged code\n *\n * @example\n * ```typescript\n * const result = await client.applyEdit({\n * originalCode: 'function hello() { return \"world\"; }',\n * codeEdit: 'function hello() { return \"universe\"; }',\n * instructions: 'Change return value'\n * });\n * console.log(result.mergedCode);\n * ```\n */\n async applyEdit(input: import('./types.js').ApplyEditInput, overrides?: Partial<import('./types.js').ApplyEditConfig>): Promise<import('./types.js').ApplyEditResult> {\n const { applyEdit } = await import('./apply.js');\n return applyEdit(input, { ...this.config, ...overrides });\n }\n}\n\n/**\n * Execute a file edit using Morph Fast Apply\n * Note: This function requires Node.js for file I/O\n */\nexport async function executeEditFile(\n input: EditFileInput,\n config: EditFileConfig = {}\n): Promise<EditFileResult> {\n const baseDir = config.baseDir || DEFAULT_CONFIG.baseDir;\n const fullPath = resolve(join(baseDir, input.target_filepath));\n const debug = config.debug || false;\n\n // Security: ensure file is within baseDir\n const relativePath = relative(baseDir, fullPath);\n if (relativePath.startsWith('..') || fullPath === baseDir) {\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: `Invalid filepath: '${input.target_filepath}' is outside baseDir`,\n };\n }\n\n try {\n if (debug) console.log(`[FastApply] Reading file: ${input.target_filepath}`);\n\n // Dynamic import to avoid loading Node.js fs module at module evaluation time\n const { readFile, writeFile } = await import('fs/promises');\n const { callMorphAPI, generateUdiff, countChanges } = await import('./apply.js');\n\n // Handle both existing and non-existent files\n let originalCode = '';\n try {\n originalCode = await readFile(fullPath, 'utf-8');\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n throw error; // Re-throw if it's not a \"file not found\" error\n }\n // File doesn't exist, proceed with empty content (will create new file)\n if (debug) console.log(`[FastApply] File doesn't exist, will create new file`);\n }\n\n const { content: mergedCode, completionId } = await callMorphAPI(originalCode, input.code_edit, input.instructions, input.target_filepath, config);\n\n const udiff = config.generateUdiff !== false ? generateUdiff(originalCode, mergedCode, input.target_filepath) : undefined;\n\n if (config.autoWrite !== false) {\n await writeFile(fullPath, mergedCode, 'utf-8');\n if (debug) console.log(`[FastApply] Wrote ${mergedCode.length} chars to ${input.target_filepath}`);\n }\n\n const changes = countChanges(originalCode, mergedCode);\n\n return {\n success: true,\n filepath: input.target_filepath,\n udiff,\n changes,\n completionId,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n filepath: input.target_filepath,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n"],"mappings":"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","names":["applyEdit","callMorphAPI","generateUdiff","countChanges"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-63WE2C5R.js";
|
|
5
5
|
import {
|
|
6
6
|
executeEditFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R3BSIJCL.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -86,4 +86,4 @@ export {
|
|
|
86
86
|
vercel_default,
|
|
87
87
|
vercel_exports
|
|
88
88
|
};
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-TGUQHW3I.js.map
|
|
@@ -85,7 +85,7 @@ async function callMorphAPI(originalCode, codeEdit, instructions, filepath, conf
|
|
|
85
85
|
if (debug) {
|
|
86
86
|
console.log(`[FastApply] \u2705 Success in ${elapsed}ms, merged: ${data.choices[0].message.content.length} chars`);
|
|
87
87
|
}
|
|
88
|
-
return data.choices[0].message.content;
|
|
88
|
+
return { content: data.choices[0].message.content, completionId: data.id };
|
|
89
89
|
}
|
|
90
90
|
async function applyEdit(input, config = {}) {
|
|
91
91
|
const debug = config.debug || false;
|
|
@@ -94,7 +94,7 @@ async function applyEdit(input, config = {}) {
|
|
|
94
94
|
if (debug) {
|
|
95
95
|
console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);
|
|
96
96
|
}
|
|
97
|
-
const mergedCode = await callMorphAPI(
|
|
97
|
+
const { content: mergedCode, completionId } = await callMorphAPI(
|
|
98
98
|
input.originalCode,
|
|
99
99
|
input.codeEdit,
|
|
100
100
|
input.instructions,
|
|
@@ -107,7 +107,8 @@ async function applyEdit(input, config = {}) {
|
|
|
107
107
|
success: true,
|
|
108
108
|
mergedCode,
|
|
109
109
|
udiff,
|
|
110
|
-
changes
|
|
110
|
+
changes,
|
|
111
|
+
completionId
|
|
111
112
|
};
|
|
112
113
|
} catch (error) {
|
|
113
114
|
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
@@ -126,4 +127,4 @@ export {
|
|
|
126
127
|
callMorphAPI,
|
|
127
128
|
applyEdit
|
|
128
129
|
};
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
130
|
+
//# sourceMappingURL=chunk-Z6TF5G4R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/fastapply/apply.ts"],"sourcesContent":["/**\n * Edge-compatible code application API\n *\n * This module has zero Node.js dependencies and works on:\n * - Cloudflare Workers\n * - Vercel Edge Functions\n * - Deno Deploy\n * - Browser environments\n *\n * For file-based operations, use executeEditFile from core.ts\n */\n\nimport { createTwoFilesPatch } from 'diff';\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type {\n EditChanges,\n MorphApplyResponse,\n ApplyEditInput,\n ApplyEditResult,\n ApplyEditConfig,\n} from './types.js';\n\nconst DEFAULT_API_URL = 'https://api.morphllm.com';\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * Generate a unified diff between two strings\n */\nexport function generateUdiff(\n original: string,\n modified: string,\n filepath: string\n): string {\n return createTwoFilesPatch(\n filepath,\n filepath,\n original,\n modified,\n 'Original',\n 'Modified'\n );\n}\n\n/**\n * Count changes from a unified diff\n */\nexport function countChanges(original: string, modified: string): EditChanges {\n const diff = generateUdiff(original, modified, 'file');\n const lines = diff.split('\\n');\n\n let linesAdded = 0;\n let linesRemoved = 0;\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n linesAdded++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n linesRemoved++;\n }\n }\n\n const linesModified = Math.min(linesAdded, linesRemoved);\n\n return {\n linesAdded: linesAdded - linesModified,\n linesRemoved: linesRemoved - linesModified,\n linesModified,\n };\n}\n\n/**\n * Call Morph Apply API to merge code edits\n * Uses OpenAI-compatible chat completions endpoint with XML-formatted message\n */\nexport async function callMorphAPI(\n originalCode: string,\n codeEdit: string,\n instructions: string,\n filepath: string,\n config: ApplyEditConfig\n): Promise<{ content: string; completionId?: string }> {\n const apiKey = config.morphApiKey || (typeof process !== 'undefined' ? process.env?.MORPH_API_KEY : undefined);\n const apiUrl = config.morphApiUrl || DEFAULT_API_URL;\n const timeout = config.timeout || DEFAULT_TIMEOUT;\n const debug = config.debug || false;\n\n if (!apiKey) {\n throw new Error(\n 'Morph API key not found. Set MORPH_API_KEY environment variable or pass morphApiKey in config.'\n );\n }\n\n // Format message with XML tags as per Morph Fast Apply spec\n const message = `<instruction>${instructions}</instruction>\\n<code>${originalCode}</code>\\n<update>${codeEdit}</update>`;\n\n if (debug) {\n console.log(`[FastApply] Calling ${apiUrl}/v1/chat/completions`);\n console.log(`[FastApply] File: ${filepath}, Instructions: ${instructions.slice(0, 60)}...`);\n console.log(`[FastApply] Original: ${originalCode.length} chars, Edit: ${codeEdit.length} chars`);\n }\n\n const startTime = Date.now();\n\n // Fetch with retry and timeout\n const fetchPromise = fetchWithRetry(\n `${apiUrl}/v1/chat/completions`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: 'morph-v3-fast',\n messages: [{ role: 'user', content: message }],\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n timeout,\n `Morph API request timed out after ${timeout}ms`\n );\n\n if (!response.ok) {\n const error = await response.text();\n if (debug) console.error(`[FastApply] API error: ${response.status} - ${error}`);\n throw new Error(`Morph API error (${response.status}): ${error}`);\n }\n\n const data: MorphApplyResponse = await response.json();\n const elapsed = Date.now() - startTime;\n\n if (debug) {\n console.log(`[FastApply] ✅ Success in ${elapsed}ms, merged: ${data.choices[0].message.content.length} chars`);\n }\n\n return { content: data.choices[0].message.content, completionId: data.id };\n}\n\n/**\n * Apply an edit to code directly without file I/O\n *\n * This is the edge-compatible code-in/code-out API that accepts code content directly\n * and returns the merged result without reading or writing any files.\n *\n * Works on Cloudflare Workers, Vercel Edge Functions, Deno, and browsers.\n *\n * @param input - Code and edit parameters\n * @param config - Optional configuration\n * @returns Result with merged code\n *\n * @example\n * ```typescript\n * import { applyEdit } from '@morphllm/morphsdk';\n *\n * const result = await applyEdit({\n * originalCode: fs.readFileSync('file.ts', 'utf-8'),\n * codeEdit: '// ... existing code ...\\nconst newVar = 42;\\n// ... existing code ...',\n * instructions: 'Add a new variable',\n * filepath: 'file.ts' // optional, for udiff context\n * });\n *\n * if (result.success) {\n * fs.writeFileSync('file.ts', result.mergedCode);\n * }\n * ```\n */\nexport async function applyEdit(\n input: ApplyEditInput,\n config: ApplyEditConfig = {}\n): Promise<ApplyEditResult> {\n const debug = config.debug || false;\n const filepath = input.filepath || 'file';\n\n try {\n if (debug) {\n console.log(`[FastApply] Applying edit to code (${input.originalCode.length} chars)`);\n }\n\n const { content: mergedCode, completionId } = await callMorphAPI(\n input.originalCode,\n input.codeEdit,\n input.instructions,\n filepath,\n config\n );\n\n const udiff = config.generateUdiff !== false\n ? generateUdiff(input.originalCode, mergedCode, filepath)\n : undefined;\n\n const changes = countChanges(input.originalCode, mergedCode);\n\n return {\n success: true,\n mergedCode,\n udiff,\n changes,\n completionId,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n if (debug) console.error(`[FastApply] Error: ${errorMessage}`);\n\n return {\n success: false,\n changes: { linesAdded: 0, linesRemoved: 0, linesModified: 0 },\n error: errorMessage,\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -28,10 +28,8 @@ interface GitHubClientConfig {
|
|
|
28
28
|
apiKey?: string;
|
|
29
29
|
/** Default installation ID to use (optional, can be specified per-request) */
|
|
30
30
|
installationId?: string;
|
|
31
|
-
/** Base URL for the Morph
|
|
31
|
+
/** Base URL for the Morph API (defaults to https://api.morphllm.com) */
|
|
32
32
|
baseUrl?: string;
|
|
33
|
-
/** Base URL for the browser backend API — used for CRUD endpoints (defaults to https://browser.morphllm.com) */
|
|
34
|
-
backendUrl?: string;
|
|
35
33
|
/** Request timeout in milliseconds */
|
|
36
34
|
timeout?: number;
|
|
37
35
|
/** Enable debug logging */
|
|
@@ -517,8 +515,7 @@ declare class PermissionError extends GitHubError {
|
|
|
517
515
|
*/
|
|
518
516
|
declare class GitHubClient {
|
|
519
517
|
private apiKey;
|
|
520
|
-
private
|
|
521
|
-
private backendUrl;
|
|
518
|
+
private baseUrl;
|
|
522
519
|
private timeout;
|
|
523
520
|
private debug;
|
|
524
521
|
private defaultInstallationId?;
|
|
@@ -582,17 +579,9 @@ declare class GitHubClient {
|
|
|
582
579
|
getInstallUrl(): string;
|
|
583
580
|
constructor(config?: GitHubClientConfig);
|
|
584
581
|
/**
|
|
585
|
-
* Make an API request
|
|
582
|
+
* Make an authenticated API request
|
|
586
583
|
*/
|
|
587
584
|
private request;
|
|
588
|
-
/**
|
|
589
|
-
* Make an API request to the landing app (Octokit-based endpoints)
|
|
590
|
-
*/
|
|
591
|
-
private landingRequest;
|
|
592
|
-
/**
|
|
593
|
-
* Shared fetch logic for both backend and landing requests
|
|
594
|
-
*/
|
|
595
|
-
private _fetch;
|
|
596
585
|
/**
|
|
597
586
|
* Get the installation ID to use for a request
|
|
598
587
|
*/
|