@morphllm/morphsdk 0.2.44 → 0.2.46
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/README.md +1 -1
- package/dist/{chunk-TVFGHXPE.js → chunk-3FTAIJBH.js} +4 -4
- package/dist/chunk-5JTJOQUX.js +283 -0
- package/dist/chunk-5JTJOQUX.js.map +1 -0
- package/dist/{chunk-ZRLEAPZV.js → chunk-76DJEQEP.js} +4 -4
- package/dist/{chunk-W3XLPMV3.js → chunk-7HS6YXA3.js} +21 -5
- package/dist/{chunk-W3XLPMV3.js.map → chunk-7HS6YXA3.js.map} +1 -1
- package/dist/chunk-7T7YOPJV.js +82 -0
- package/dist/chunk-7T7YOPJV.js.map +1 -0
- package/dist/chunk-CL45IWIU.js +105 -0
- package/dist/chunk-CL45IWIU.js.map +1 -0
- package/dist/chunk-D6OD3IST.js +70 -0
- package/dist/chunk-D6OD3IST.js.map +1 -0
- package/dist/{chunk-PEGZVGG4.js → chunk-G4AWE5A2.js} +4 -4
- package/dist/{chunk-OUEJ6XEO.js → chunk-GJU7UOFL.js} +4 -4
- package/dist/{chunk-Q7PDN7TS.js → chunk-GZMUGMOZ.js} +1 -1
- package/dist/{chunk-Q7PDN7TS.js.map → chunk-GZMUGMOZ.js.map} +1 -1
- package/dist/chunk-JYBVRF72.js +1 -0
- package/dist/{chunk-EYHXBQQX.js → chunk-LVY5LPEX.js} +70 -10
- package/dist/chunk-LVY5LPEX.js.map +1 -0
- package/dist/{chunk-GDR65N2J.js → chunk-OXHGFHEU.js} +53 -26
- package/dist/chunk-OXHGFHEU.js.map +1 -0
- package/dist/{chunk-VBBJGWHY.js → chunk-P2XKFWFD.js} +2 -2
- package/dist/chunk-PABIV7X6.js +76 -0
- package/dist/chunk-PABIV7X6.js.map +1 -0
- package/dist/{chunk-GTOXMAF2.js → chunk-SWQPIKPY.js} +44 -3
- package/dist/chunk-SWQPIKPY.js.map +1 -0
- package/dist/chunk-TJIUA27P.js +94 -0
- package/dist/chunk-TJIUA27P.js.map +1 -0
- package/dist/{chunk-O5DA5V5S.js → chunk-UBX7QYBD.js} +4 -4
- package/dist/{chunk-X4CQ6D3G.js → chunk-UIZT3KVJ.js} +4 -4
- package/dist/{chunk-UYBIKZPM.js → chunk-UXYK7WZX.js} +2 -2
- package/dist/chunk-WETRQJGU.js +129 -0
- package/dist/chunk-WETRQJGU.js.map +1 -0
- package/dist/client-BGctTHu9.d.ts +318 -0
- package/dist/client.cjs +1954 -53
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.ts +14 -110
- package/dist/client.js +29 -4
- package/dist/core-DxiUwyBe.d.ts +156 -0
- package/dist/git/client.cjs +52 -25
- package/dist/git/client.cjs.map +1 -1
- package/dist/git/client.d.ts +17 -8
- package/dist/git/client.js +1 -1
- package/dist/git/index.cjs +52 -25
- package/dist/git/index.cjs.map +1 -1
- package/dist/git/index.d.ts +1 -1
- package/dist/git/index.js +2 -2
- package/dist/git/types.cjs.map +1 -1
- package/dist/git/types.d.ts +20 -2
- package/dist/index.cjs +2033 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +48 -6
- package/dist/tools/browser/anthropic.cjs +1 -0
- package/dist/tools/browser/anthropic.cjs.map +1 -1
- package/dist/tools/browser/anthropic.js +1 -1
- package/dist/tools/browser/core.cjs +69 -9
- package/dist/tools/browser/core.cjs.map +1 -1
- package/dist/tools/browser/core.js +1 -1
- package/dist/tools/browser/index.cjs +69 -9
- package/dist/tools/browser/index.cjs.map +1 -1
- package/dist/tools/browser/index.js +1 -1
- package/dist/tools/browser/openai.cjs +1 -0
- package/dist/tools/browser/openai.cjs.map +1 -1
- package/dist/tools/browser/openai.js +1 -1
- package/dist/tools/browser/types.cjs.map +1 -1
- package/dist/tools/browser/types.d.ts +2 -0
- package/dist/tools/browser/vercel.cjs +1 -0
- package/dist/tools/browser/vercel.cjs.map +1 -1
- package/dist/tools/browser/vercel.js +1 -1
- package/dist/tools/codebase_search/anthropic.js +2 -2
- package/dist/tools/codebase_search/index.js +9 -9
- package/dist/tools/codebase_search/openai.js +2 -2
- package/dist/tools/codebase_search/vercel.js +2 -2
- package/dist/tools/fastapply/anthropic.js +2 -2
- package/dist/tools/fastapply/index.js +7 -7
- package/dist/tools/fastapply/openai.js +2 -2
- package/dist/tools/fastapply/vercel.js +2 -2
- package/dist/tools/index.js +7 -7
- package/dist/tools/warp_grep/agent/config.cjs +80 -1
- package/dist/tools/warp_grep/agent/config.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/config.js +1 -1
- package/dist/tools/warp_grep/agent/parser.cjs +43 -2
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.js +1 -1
- package/dist/tools/warp_grep/agent/prompt.cjs +89 -45
- package/dist/tools/warp_grep/agent/prompt.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/prompt.d.ts +1 -1
- package/dist/tools/warp_grep/agent/prompt.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +229 -49
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +4 -4
- package/dist/tools/warp_grep/agent/types.js +0 -1
- package/dist/tools/warp_grep/anthropic.cjs +311 -83
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.d.ts +75 -12
- package/dist/tools/warp_grep/anthropic.js +21 -8
- package/dist/tools/warp_grep/index.cjs +415 -126
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.d.ts +17 -4
- package/dist/tools/warp_grep/index.js +29 -21
- package/dist/tools/warp_grep/openai.cjs +314 -83
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.d.ts +73 -29
- package/dist/tools/warp_grep/openai.js +21 -8
- package/dist/tools/warp_grep/providers/command.cjs +80 -1
- package/dist/tools/warp_grep/providers/command.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/command.js +2 -2
- package/dist/tools/warp_grep/providers/local.cjs +80 -1
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.js +2 -2
- package/dist/tools/warp_grep/vercel.cjs +291 -57
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.d.ts +40 -19
- package/dist/tools/warp_grep/vercel.js +17 -8
- package/package.json +1 -1
- package/dist/chunk-AFEPUNAO.js +0 -15
- package/dist/chunk-AFEPUNAO.js.map +0 -1
- package/dist/chunk-EYHXBQQX.js.map +0 -1
- package/dist/chunk-GDR65N2J.js.map +0 -1
- package/dist/chunk-GTOXMAF2.js.map +0 -1
- package/dist/chunk-HKZB23U7.js +0 -85
- package/dist/chunk-HKZB23U7.js.map +0 -1
- package/dist/chunk-IQHKEIQX.js +0 -54
- package/dist/chunk-IQHKEIQX.js.map +0 -1
- package/dist/chunk-JKFVDM62.js +0 -45
- package/dist/chunk-JKFVDM62.js.map +0 -1
- package/dist/chunk-KL4YVZRF.js +0 -57
- package/dist/chunk-KL4YVZRF.js.map +0 -1
- package/dist/chunk-SMR2T5BT.js +0 -104
- package/dist/chunk-SMR2T5BT.js.map +0 -1
- package/dist/chunk-XYPMN4A3.js +0 -1
- /package/dist/{chunk-TVFGHXPE.js.map → chunk-3FTAIJBH.js.map} +0 -0
- /package/dist/{chunk-ZRLEAPZV.js.map → chunk-76DJEQEP.js.map} +0 -0
- /package/dist/{chunk-PEGZVGG4.js.map → chunk-G4AWE5A2.js.map} +0 -0
- /package/dist/{chunk-OUEJ6XEO.js.map → chunk-GJU7UOFL.js.map} +0 -0
- /package/dist/{chunk-XYPMN4A3.js.map → chunk-JYBVRF72.js.map} +0 -0
- /package/dist/{chunk-VBBJGWHY.js.map → chunk-P2XKFWFD.js.map} +0 -0
- /package/dist/{chunk-O5DA5V5S.js.map → chunk-UBX7QYBD.js.map} +0 -0
- /package/dist/{chunk-X4CQ6D3G.js.map → chunk-UIZT3KVJ.js.map} +0 -0
- /package/dist/{chunk-UYBIKZPM.js.map → chunk-UXYK7WZX.js.map} +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runWarpGrep
|
|
3
|
+
} from "./chunk-7HS6YXA3.js";
|
|
4
|
+
import {
|
|
5
|
+
LocalRipgrepProvider
|
|
6
|
+
} from "./chunk-UXYK7WZX.js";
|
|
7
|
+
|
|
8
|
+
// tools/warp_grep/core.ts
|
|
9
|
+
var WarpGrepClient = class {
|
|
10
|
+
config;
|
|
11
|
+
constructor(config = {}) {
|
|
12
|
+
this.config = {
|
|
13
|
+
apiKey: config.apiKey,
|
|
14
|
+
debug: config.debug,
|
|
15
|
+
timeout: config.timeout,
|
|
16
|
+
retryConfig: config.retryConfig
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Execute a code search query
|
|
21
|
+
*
|
|
22
|
+
* @param input - Search parameters including query, repoRoot, and optional provider
|
|
23
|
+
* @returns Search results with relevant code contexts
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const result = await client.execute({
|
|
28
|
+
* query: 'Find authentication middleware',
|
|
29
|
+
* repoRoot: '.'
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* if (result.success) {
|
|
33
|
+
* for (const ctx of result.contexts) {
|
|
34
|
+
* console.log(`File: ${ctx.file}`);
|
|
35
|
+
* console.log(ctx.content);
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
async execute(input) {
|
|
41
|
+
const provider = input.provider ?? new LocalRipgrepProvider(input.repoRoot, input.excludes);
|
|
42
|
+
const result = await runWarpGrep({
|
|
43
|
+
query: input.query,
|
|
44
|
+
repoRoot: input.repoRoot,
|
|
45
|
+
provider,
|
|
46
|
+
excludes: input.excludes,
|
|
47
|
+
includes: input.includes,
|
|
48
|
+
debug: input.debug ?? this.config.debug ?? false,
|
|
49
|
+
apiKey: this.config.apiKey
|
|
50
|
+
});
|
|
51
|
+
const finish = result.finish;
|
|
52
|
+
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: "Search did not complete"
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
59
|
+
file: r.path,
|
|
60
|
+
content: r.content
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
success: true,
|
|
64
|
+
contexts,
|
|
65
|
+
summary: finish.payload
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
async function executeWarpGrep(input, config) {
|
|
70
|
+
const client = new WarpGrepClient(config);
|
|
71
|
+
return client.execute(input);
|
|
72
|
+
}
|
|
73
|
+
function formatResult(result) {
|
|
74
|
+
if (!result.success) {
|
|
75
|
+
return `Search failed: ${result.error}`;
|
|
76
|
+
}
|
|
77
|
+
if (!result.contexts || result.contexts.length === 0) {
|
|
78
|
+
return "No relevant code found. Try rephrasing your query.";
|
|
79
|
+
}
|
|
80
|
+
const lines = [];
|
|
81
|
+
lines.push(`Found ${result.contexts.length} relevant code sections:
|
|
82
|
+
`);
|
|
83
|
+
result.contexts.forEach((ctx, i) => {
|
|
84
|
+
lines.push(`${i + 1}. ${ctx.file}`);
|
|
85
|
+
lines.push("```");
|
|
86
|
+
lines.push(ctx.content);
|
|
87
|
+
lines.push("```");
|
|
88
|
+
lines.push("");
|
|
89
|
+
});
|
|
90
|
+
if (result.summary) {
|
|
91
|
+
lines.push(`Summary: ${result.summary}`);
|
|
92
|
+
}
|
|
93
|
+
return lines.join("\n");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// tools/warp_grep/prompts.ts
|
|
97
|
+
var WARP_GREP_DESCRIPTION = "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.";
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
WarpGrepClient,
|
|
101
|
+
executeWarpGrep,
|
|
102
|
+
formatResult,
|
|
103
|
+
WARP_GREP_DESCRIPTION
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=chunk-CL45IWIU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/warp_grep/core.ts","../tools/warp_grep/prompts.ts"],"sourcesContent":["/**\n * Core implementation for morph-warp-grep\n * Provides a client class for programmatic code search\n */\n\nimport { runWarpGrep } from './agent/runner.js';\nimport { LocalRipgrepProvider } from './providers/local.js';\nimport type { \n WarpGrepClientConfig, \n WarpGrepInput, \n WarpGrepResult,\n WarpGrepContext,\n} from './types.js';\n\n/**\n * WarpGrep client for programmatic code search\n * \n * @example\n * ```typescript\n * import { WarpGrepClient } from '@morphllm/morphsdk';\n * \n * const client = new WarpGrepClient({ apiKey: process.env.MORPH_API_KEY });\n * \n * // Simple usage - defaults to LocalRipgrepProvider\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * \n * // With custom excludes\n * const result = await client.execute({\n * query: 'Find database models',\n * repoRoot: '.',\n * excludes: ['node_modules', '.git', 'dist']\n * });\n * ```\n */\nexport class WarpGrepClient {\n private config: WarpGrepClientConfig;\n\n constructor(config: WarpGrepClientConfig = {}) {\n this.config = {\n apiKey: config.apiKey,\n debug: config.debug,\n timeout: config.timeout,\n retryConfig: config.retryConfig,\n };\n }\n\n /**\n * Execute a code search query\n * \n * @param input - Search parameters including query, repoRoot, and optional provider\n * @returns Search results with relevant code contexts\n * \n * @example\n * ```typescript\n * const result = await client.execute({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * \n * if (result.success) {\n * for (const ctx of result.contexts) {\n * console.log(`File: ${ctx.file}`);\n * console.log(ctx.content);\n * }\n * }\n * ```\n */\n async execute(input: WarpGrepInput): Promise<WarpGrepResult> {\n // Default to LocalRipgrepProvider if no provider specified\n const provider = input.provider ?? new LocalRipgrepProvider(input.repoRoot, input.excludes);\n \n const result = await runWarpGrep({\n query: input.query,\n repoRoot: input.repoRoot,\n provider,\n excludes: input.excludes,\n includes: input.includes,\n debug: input.debug ?? this.config.debug ?? false,\n apiKey: this.config.apiKey,\n });\n\n const finish = result.finish;\n if (result.terminationReason !== 'completed' || !finish?.metadata) {\n return { \n success: false, \n error: 'Search did not complete',\n };\n }\n\n const contexts: WarpGrepContext[] = (finish.resolved ?? []).map(r => ({\n file: r.path,\n content: r.content,\n }));\n\n return { \n success: true, \n contexts, \n summary: finish.payload,\n };\n }\n}\n\n/**\n * Execute a warp grep search directly\n * \n * @param input - Search parameters\n * @param config - Optional client configuration\n * @returns Search results\n * \n * @example\n * ```typescript\n * import { executeWarpGrep } from '@morphllm/morphsdk/tools/warp-grep';\n * \n * const result = await executeWarpGrep({\n * query: 'Find authentication middleware',\n * repoRoot: '.'\n * });\n * ```\n */\nexport async function executeWarpGrep(\n input: WarpGrepInput,\n config?: WarpGrepClientConfig\n): Promise<WarpGrepResult> {\n const client = new WarpGrepClient(config);\n return client.execute(input);\n}\n\n/**\n * Format warp grep results for display or tool responses\n * \n * @param result - The search result\n * @returns Formatted string representation\n */\nexport function formatResult(result: WarpGrepResult): string {\n if (!result.success) {\n return `Search failed: ${result.error}`;\n }\n\n if (!result.contexts || result.contexts.length === 0) {\n return 'No relevant code found. Try rephrasing your query.';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${result.contexts.length} relevant code sections:\\n`);\n\n result.contexts.forEach((ctx, i) => {\n lines.push(`${i + 1}. ${ctx.file}`);\n lines.push('```');\n lines.push(ctx.content);\n lines.push('```');\n lines.push('');\n });\n\n if (result.summary) {\n lines.push(`Summary: ${result.summary}`);\n }\n\n return lines.join('\\n');\n}\n\n","/**\n * Prompts and descriptions for morph-warp-grep\n */\n\n/**\n * Default tool description for the warp grep tool\n */\nexport const WARP_GREP_DESCRIPTION = \n 'A fast and accurate tool that can search for all relevant context in a codebase. ' +\n 'You must use this tool to save time and avoid context pollution.';\n\n/**\n * System prompt for the warp grep agent\n * Re-exported from agent/prompt.ts for convenience\n */\nexport { SYSTEM_PROMPT as WARP_GREP_SYSTEM_PROMPT, getSystemPrompt } from './agent/prompt.js';\n\n"],"mappings":";;;;;;;;AAqCO,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EAER,YAAY,SAA+B,CAAC,GAAG;AAC7C,SAAK,SAAS;AAAA,MACZ,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,aAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,QAAQ,OAA+C;AAE3D,UAAM,WAAW,MAAM,YAAY,IAAI,qBAAqB,MAAM,UAAU,MAAM,QAAQ;AAE1F,UAAM,SAAS,MAAM,YAAY;AAAA,MAC/B,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM,SAAS,KAAK,OAAO,SAAS;AAAA,MAC3C,QAAQ,KAAK,OAAO;AAAA,IACtB,CAAC;AAED,UAAM,SAAS,OAAO;AACtB,QAAI,OAAO,sBAAsB,eAAe,CAAC,QAAQ,UAAU;AACjE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,YAA+B,OAAO,YAAY,CAAC,GAAG,IAAI,QAAM;AAAA,MACpE,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,IACb,EAAE;AAEF,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,SAAS,OAAO;AAAA,IAClB;AAAA,EACF;AACF;AAmBA,eAAsB,gBACpB,OACA,QACyB;AACzB,QAAM,SAAS,IAAI,eAAe,MAAM;AACxC,SAAO,OAAO,QAAQ,KAAK;AAC7B;AAQO,SAAS,aAAa,QAAgC;AAC3D,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,kBAAkB,OAAO,KAAK;AAAA,EACvC;AAEA,MAAI,CAAC,OAAO,YAAY,OAAO,SAAS,WAAW,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,SAAS,OAAO,SAAS,MAAM;AAAA,CAA4B;AAEtE,SAAO,SAAS,QAAQ,CAAC,KAAK,MAAM;AAClC,UAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE;AAClC,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,IAAI,OAAO;AACtB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf,CAAC;AAED,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,YAAY,OAAO,OAAO,EAAE;AAAA,EACzC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC1JO,IAAM,wBACX;","names":[]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WARP_GREP_DESCRIPTION
|
|
3
|
+
} from "./chunk-CL45IWIU.js";
|
|
4
|
+
import {
|
|
5
|
+
runWarpGrep
|
|
6
|
+
} from "./chunk-7HS6YXA3.js";
|
|
7
|
+
import {
|
|
8
|
+
LocalRipgrepProvider
|
|
9
|
+
} from "./chunk-UXYK7WZX.js";
|
|
10
|
+
|
|
11
|
+
// tools/warp_grep/vercel.ts
|
|
12
|
+
import { tool } from "ai";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
var warpGrepSchema = z.object({
|
|
15
|
+
query: z.string().describe("Free-form repository question")
|
|
16
|
+
});
|
|
17
|
+
async function execute(input, config) {
|
|
18
|
+
const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
|
|
19
|
+
const result = await runWarpGrep({
|
|
20
|
+
query: input.query,
|
|
21
|
+
repoRoot: config.repoRoot,
|
|
22
|
+
provider,
|
|
23
|
+
excludes: config.excludes,
|
|
24
|
+
includes: config.includes,
|
|
25
|
+
debug: config.debug ?? false,
|
|
26
|
+
apiKey: config.apiKey
|
|
27
|
+
});
|
|
28
|
+
const finish = result.finish;
|
|
29
|
+
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
30
|
+
return { success: false, error: "Search did not complete" };
|
|
31
|
+
}
|
|
32
|
+
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
33
|
+
file: r.path,
|
|
34
|
+
content: r.content
|
|
35
|
+
}));
|
|
36
|
+
return { success: true, contexts, summary: finish.payload };
|
|
37
|
+
}
|
|
38
|
+
function createMorphWarpGrepTool(config) {
|
|
39
|
+
return tool({
|
|
40
|
+
description: config.description ?? WARP_GREP_DESCRIPTION,
|
|
41
|
+
inputSchema: warpGrepSchema,
|
|
42
|
+
execute: async (params) => {
|
|
43
|
+
const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);
|
|
44
|
+
const result = await runWarpGrep({
|
|
45
|
+
query: params.query,
|
|
46
|
+
repoRoot: config.repoRoot,
|
|
47
|
+
provider,
|
|
48
|
+
excludes: config.excludes,
|
|
49
|
+
includes: config.includes,
|
|
50
|
+
debug: config.debug ?? false,
|
|
51
|
+
apiKey: config.apiKey
|
|
52
|
+
});
|
|
53
|
+
const finish = result.finish;
|
|
54
|
+
if (result.terminationReason !== "completed" || !finish?.metadata) {
|
|
55
|
+
return { success: false, error: "Search did not complete" };
|
|
56
|
+
}
|
|
57
|
+
const contexts = (finish.resolved ?? []).map((r) => ({
|
|
58
|
+
file: r.path,
|
|
59
|
+
content: r.content
|
|
60
|
+
}));
|
|
61
|
+
return { success: true, contexts, summary: finish.payload };
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
execute,
|
|
68
|
+
createMorphWarpGrepTool
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=chunk-D6OD3IST.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/warp_grep/vercel.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for morph-warp-grep tool\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { runWarpGrep } from './agent/runner.js';\nimport { LocalRipgrepProvider } from './providers/local.js';\nimport { WARP_GREP_DESCRIPTION, getSystemPrompt } from './prompts.js';\nimport { formatResult } from './core.js';\nimport type { WarpGrepToolConfig, WarpGrepResult, WarpGrepContext } from './types.js';\n\n/**\n * Zod schema for warp grep input\n */\nconst warpGrepSchema = z.object({\n query: z.string().describe('Free-form repository question'),\n});\n\n/**\n * Execute warp grep search\n * \n * @param input - Tool input with query\n * @param config - Configuration with repoRoot and optional provider\n * @returns Search results\n */\nexport async function execute(\n input: { query: string },\n config: WarpGrepToolConfig\n): Promise<WarpGrepResult> {\n const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n \n const result = await runWarpGrep({\n query: input.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n apiKey: config.apiKey,\n });\n\n const finish = result.finish;\n if (result.terminationReason !== 'completed' || !finish?.metadata) {\n return { success: false, error: 'Search did not complete' };\n }\n\n const contexts: WarpGrepContext[] = (finish.resolved ?? []).map(r => ({\n file: r.path,\n content: r.content,\n }));\n\n return { success: true, contexts, summary: finish.payload };\n}\n\n// Re-export formatResult and getSystemPrompt for convenience\nexport { formatResult, getSystemPrompt };\n\n/**\n * Create Vercel AI SDK warp grep tool\n * \n * @param config - Configuration options\n * @returns Vercel AI SDK tool\n * \n * @example\n * ```typescript\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createMorphWarpGrepTool } from '@morphllm/morphsdk/tools/warp-grep/vercel';\n * \n * const grepTool = createMorphWarpGrepTool({ repoRoot: '.' });\n * \n * const result = await generateText({\n * model: anthropic('claude-sonnet-4-5-20250929'),\n * tools: { grep: grepTool },\n * prompt: 'Find authentication middleware'\n * });\n * ```\n */\nexport function createMorphWarpGrepTool(config: WarpGrepToolConfig) {\n return tool({\n description: config.description ?? WARP_GREP_DESCRIPTION,\n inputSchema: warpGrepSchema,\n execute: async (params) => {\n const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n const result = await runWarpGrep({\n query: params.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n apiKey: config.apiKey,\n });\n\n const finish = result.finish;\n if (result.terminationReason !== 'completed' || !finish?.metadata) {\n return { success: false, error: 'Search did not complete' };\n }\n\n const contexts: WarpGrepContext[] = (finish.resolved ?? []).map(r => ({\n file: r.path,\n content: r.content,\n }));\n\n return { success: true, contexts, summary: finish.payload };\n },\n });\n}\n"],"mappings":";;;;;;;;;;;AAIA,SAAS,YAAY;AACrB,SAAS,SAAS;AAUlB,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,OAAO,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAC5D,CAAC;AASD,eAAsB,QACpB,OACA,QACyB;AACzB,QAAM,WAAW,OAAO,YAAY,IAAI,qBAAqB,OAAO,UAAU,OAAO,QAAQ;AAE7F,QAAM,SAAS,MAAM,YAAY;AAAA,IAC/B,OAAO,MAAM;AAAA,IACb,UAAU,OAAO;AAAA,IACjB;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO,SAAS;AAAA,IACvB,QAAQ,OAAO;AAAA,EACjB,CAAC;AAED,QAAM,SAAS,OAAO;AACtB,MAAI,OAAO,sBAAsB,eAAe,CAAC,QAAQ,UAAU;AACjE,WAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,EAC5D;AAEA,QAAM,YAA+B,OAAO,YAAY,CAAC,GAAG,IAAI,QAAM;AAAA,IACpE,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,EACb,EAAE;AAEF,SAAO,EAAE,SAAS,MAAM,UAAU,SAAS,OAAO,QAAQ;AAC5D;AA0BO,SAAS,wBAAwB,QAA4B;AAClE,SAAO,KAAK;AAAA,IACV,aAAa,OAAO,eAAe;AAAA,IACnC,aAAa;AAAA,IACb,SAAS,OAAO,WAAW;AACzB,YAAM,WAAW,OAAO,YAAY,IAAI,qBAAqB,OAAO,UAAU,OAAO,QAAQ;AAC7F,YAAM,SAAS,MAAM,YAAY;AAAA,QAC/B,OAAO,OAAO;AAAA,QACd,UAAU,OAAO;AAAA,QACjB;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO,SAAS;AAAA,QACvB,QAAQ,OAAO;AAAA,MACjB,CAAC;AAED,YAAM,SAAS,OAAO;AACtB,UAAI,OAAO,sBAAsB,eAAe,CAAC,QAAQ,UAAU;AACjE,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC5D;AAEA,YAAM,YAA+B,OAAO,YAAY,CAAC,GAAG,IAAI,QAAM;AAAA,QACpE,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,MACb,EAAE;AAEF,aAAO,EAAE,SAAS,MAAM,UAAU,SAAS,OAAO,QAAQ;AAAA,IAC5D;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeEditFile
|
|
3
|
+
} from "./chunk-64PMM72R.js";
|
|
1
4
|
import {
|
|
2
5
|
EDIT_FILE_SYSTEM_PROMPT,
|
|
3
6
|
EDIT_FILE_TOOL_DESCRIPTION
|
|
4
7
|
} from "./chunk-63WE2C5R.js";
|
|
5
|
-
import {
|
|
6
|
-
executeEditFile
|
|
7
|
-
} from "./chunk-64PMM72R.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -103,4 +103,4 @@ export {
|
|
|
103
103
|
openai_default,
|
|
104
104
|
openai_exports
|
|
105
105
|
};
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
106
|
+
//# sourceMappingURL=chunk-G4AWE5A2.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeCodebaseSearch
|
|
3
|
+
} from "./chunk-WM77HRKO.js";
|
|
1
4
|
import {
|
|
2
5
|
CODEBASE_SEARCH_DESCRIPTION,
|
|
3
6
|
CODEBASE_SEARCH_SYSTEM_PROMPT
|
|
4
7
|
} from "./chunk-YQMPVJ2L.js";
|
|
5
|
-
import {
|
|
6
|
-
executeCodebaseSearch
|
|
7
|
-
} from "./chunk-WM77HRKO.js";
|
|
8
8
|
|
|
9
9
|
// tools/codebase_search/anthropic.ts
|
|
10
10
|
function createCodebaseSearchTool(config) {
|
|
@@ -80,4 +80,4 @@ function formatResult(result) {
|
|
|
80
80
|
export {
|
|
81
81
|
createCodebaseSearchTool
|
|
82
82
|
};
|
|
83
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-GJU7UOFL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../git/index.ts"],"sourcesContent":["/**\n * Morph Git SDK\n * \n * Git operations for AI agents using Morph's backend infrastructure.\n * \n * @example\n * ```typescript\n * import { MorphGit } from 'morphsdk/git';\n * \n * const morphGit = new MorphGit({\n * apiKey: process.env.MORPH_API_KEY!\n * });\n * \n * // Initialize and push\n * await morphGit.init({ repoId: 'my-project', dir: './my-project' });\n * await morphGit.add({ dir: './my-project', filepath: 'src/app.ts' });\n * await morphGit.commit({ dir: './my-project', message: 'Update' });\n * await morphGit.push({ dir: './my-project', branch: 'main' });\n * ```\n */\n\nexport { MorphGit } from './client.js';\nexport type {\n MorphGitConfig,\n CloneOptions,\n PushOptions,\n PullOptions,\n AddOptions,\n CommitOptions,\n StatusOptions,\n LogOptions,\n CheckoutOptions,\n BranchOptions,\n DiffOptions,\n CommitObject,\n StatusResult,\n ChatMessage,\n CommitMetadata,\n} from './types.js';\n\n// Re-export isomorphic-git for advanced use cases\nexport { default as git } from 'isomorphic-git';\nexport { default as http } from 'isomorphic-git/http/node';\n\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../git/index.ts"],"sourcesContent":["/**\n * Morph Git SDK\n * \n * Git operations for AI agents using Morph's backend infrastructure.\n * \n * @example\n * ```typescript\n * import { MorphGit } from 'morphsdk/git';\n * \n * const morphGit = new MorphGit({\n * apiKey: process.env.MORPH_API_KEY!\n * });\n * \n * // Initialize and push\n * await morphGit.init({ repoId: 'my-project', dir: './my-project' });\n * await morphGit.add({ dir: './my-project', filepath: 'src/app.ts' });\n * await morphGit.commit({ dir: './my-project', message: 'Update' });\n * await morphGit.push({ dir: './my-project', branch: 'main' });\n * ```\n */\n\nexport { MorphGit } from './client.js';\nexport type {\n MorphGitConfig,\n CloneOptions,\n PushOptions,\n PullOptions,\n AddOptions,\n CommitOptions,\n StatusOptions,\n LogOptions,\n CheckoutOptions,\n BranchOptions,\n DiffOptions,\n CommitObject,\n StatusResult,\n ChatMessage,\n CommitMetadata,\n MorphNotesSchema,\n} from './types.js';\n\n// Re-export isomorphic-git for advanced use cases\nexport { default as git } from 'isomorphic-git';\nexport { default as http } from 'isomorphic-git/http/node';\n\n"],"mappings":";AA0CA,SAAoB,WAAXA,gBAAsB;AAC/B,SAAoB,WAAXA,gBAAuB;","names":["default"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-JYBVRF72.js.map
|
|
@@ -31,15 +31,46 @@ var BrowserClient = class {
|
|
|
31
31
|
return executeBrowserTask(input, this.config);
|
|
32
32
|
}
|
|
33
33
|
async createTask(input) {
|
|
34
|
+
const apiUrl = this.config.apiUrl || DEFAULT_CONFIG.apiUrl;
|
|
35
|
+
const debug = this.config.debug || false;
|
|
36
|
+
if (debug) {
|
|
37
|
+
console.log(`[Browser] createTask: "${input.task.slice(0, 60)}..." url=${input.url || "none"}`);
|
|
38
|
+
console.log(`[Browser] Calling async endpoint: ${apiUrl}/browser-task/async`);
|
|
39
|
+
}
|
|
40
|
+
const headers = { "Content-Type": "application/json" };
|
|
41
|
+
if (this.config.apiKey) headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
42
|
+
const response = await fetch(`${apiUrl}/browser-task/async`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers,
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
task: input.task,
|
|
47
|
+
url: input.url,
|
|
48
|
+
max_steps: input.max_steps ?? 10,
|
|
49
|
+
model: input.model ?? "morph-computer-use-v0",
|
|
50
|
+
viewport_width: input.viewport_width ?? 1280,
|
|
51
|
+
viewport_height: input.viewport_height ?? 720,
|
|
52
|
+
external_id: input.external_id,
|
|
53
|
+
repo_id: input.repo_id,
|
|
54
|
+
commit_id: input.commit_id,
|
|
55
|
+
record_video: input.record_video ?? false,
|
|
56
|
+
video_width: input.video_width ?? input.viewport_width ?? 1280,
|
|
57
|
+
video_height: input.video_height ?? input.viewport_height ?? 720,
|
|
58
|
+
allow_resizing: input.allow_resizing ?? false,
|
|
59
|
+
structured_output: "schema" in input ? stringifyStructuredOutput(input.schema) : void 0
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const errorText = await response.text().catch(() => response.statusText);
|
|
64
|
+
if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);
|
|
65
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
66
|
+
}
|
|
67
|
+
const result = await response.json();
|
|
68
|
+
if (debug) {
|
|
69
|
+
console.log(`[Browser] \u2705 Task created: recording_id=${result.recording_id ?? "none"} debug_url=${result.debugUrl ? "available" : "none"}`);
|
|
70
|
+
}
|
|
34
71
|
if ("schema" in input) {
|
|
35
|
-
const taskInput = {
|
|
36
|
-
...input,
|
|
37
|
-
structured_output: stringifyStructuredOutput(input.schema)
|
|
38
|
-
};
|
|
39
|
-
const result = await executeBrowserTask(taskInput, this.config);
|
|
40
72
|
return wrapTaskResponseWithSchema(result, this.config, input.schema);
|
|
41
73
|
} else {
|
|
42
|
-
const result = await executeBrowserTask(input, this.config);
|
|
43
74
|
return wrapTaskResponse(result, this.config);
|
|
44
75
|
}
|
|
45
76
|
}
|
|
@@ -116,6 +147,7 @@ async function executeBrowserTask(input, config = {}) {
|
|
|
116
147
|
record_video: input.record_video ?? false,
|
|
117
148
|
video_width: input.video_width ?? input.viewport_width ?? 1280,
|
|
118
149
|
video_height: input.video_height ?? input.viewport_height ?? 720,
|
|
150
|
+
allow_resizing: input.allow_resizing ?? false,
|
|
119
151
|
structured_output: input.structured_output
|
|
120
152
|
})
|
|
121
153
|
},
|
|
@@ -309,7 +341,21 @@ function wrapTaskResponse(result, config) {
|
|
|
309
341
|
task_id: result.task_id || "",
|
|
310
342
|
liveUrl: result.task_id ? generateLiveUrl(result.task_id, config) : result.debugUrl || "",
|
|
311
343
|
complete: async (pollConfig) => {
|
|
312
|
-
|
|
344
|
+
if (result.task_id) {
|
|
345
|
+
return pollTaskUntilComplete(result.task_id, config, pollConfig);
|
|
346
|
+
}
|
|
347
|
+
if (result.recording_id) {
|
|
348
|
+
const recording = await waitForRecording(
|
|
349
|
+
result.recording_id,
|
|
350
|
+
config,
|
|
351
|
+
pollConfig
|
|
352
|
+
);
|
|
353
|
+
return {
|
|
354
|
+
...result,
|
|
355
|
+
recording_status: recording.status
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
throw new Error("Cannot poll completion: no task_id or recording_id available");
|
|
313
359
|
},
|
|
314
360
|
// Add Steel live session helpers - either functional or error-throwing
|
|
315
361
|
getLiveUrl: result.debugUrl ? (options) => buildLiveUrl(result.debugUrl, options) : () => {
|
|
@@ -340,8 +386,22 @@ function wrapTaskResponseWithSchema(result, config, schema) {
|
|
|
340
386
|
task_id: result.task_id || "",
|
|
341
387
|
liveUrl: result.task_id ? generateLiveUrl(result.task_id, config) : result.debugUrl || "",
|
|
342
388
|
complete: async (pollConfig) => {
|
|
343
|
-
|
|
344
|
-
|
|
389
|
+
if (result.task_id) {
|
|
390
|
+
const finalResult = await pollTaskUntilComplete(result.task_id, config, pollConfig);
|
|
391
|
+
return parseStructuredTaskOutput(finalResult, schema);
|
|
392
|
+
}
|
|
393
|
+
if (result.recording_id) {
|
|
394
|
+
const recording = await waitForRecording(
|
|
395
|
+
result.recording_id,
|
|
396
|
+
config,
|
|
397
|
+
pollConfig
|
|
398
|
+
);
|
|
399
|
+
return {
|
|
400
|
+
...parsed,
|
|
401
|
+
recording_status: recording.status
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
throw new Error("Cannot poll completion: no task_id or recording_id available");
|
|
345
405
|
},
|
|
346
406
|
// Add Steel live session helpers - either functional or error-throwing
|
|
347
407
|
getLiveUrl: result.debugUrl ? (options) => buildLiveUrl(result.debugUrl, options) : () => {
|
|
@@ -402,4 +462,4 @@ export {
|
|
|
402
462
|
getErrors,
|
|
403
463
|
checkHealth
|
|
404
464
|
};
|
|
405
|
-
//# sourceMappingURL=chunk-
|
|
465
|
+
//# sourceMappingURL=chunk-LVY5LPEX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../tools/browser/core.ts"],"sourcesContent":["/**\n * Core implementation for browser automation tasks\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type {\n BrowserConfig,\n BrowserTaskInput,\n BrowserTaskInputWithSchema,\n BrowserTaskResult,\n BrowserTaskWithPromise,\n BrowserTaskWithPromiseAndSchema,\n RecordingStatus,\n ErrorsResponse,\n LiveSessionOptions,\n IframeOptions,\n} from './types.js';\nimport { buildLiveUrl, buildLiveIframe, buildEmbedCode, resolvePreset } from './live.js';\n\nconst DEFAULT_CONFIG = {\n apiUrl: process.env.MORPH_ENVIRONMENT === 'DEV' \n ? 'http://localhost:8000'\n : 'https://browser.morphllm.com',\n timeout: 1000000, // 10 minutes for complex tasks\n debug: false,\n};\n\n/**\n * BrowserClient class for easier usage with instance configuration\n */\nexport class BrowserClient {\n private config: BrowserConfig;\n\n constructor(config: BrowserConfig = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n }\n\n /**\n * Execute a browser automation task\n */\n async execute(input: BrowserTaskInput): Promise<BrowserTaskResult> {\n return executeBrowserTask(input, this.config);\n }\n\n async createTask(input: BrowserTaskInput): Promise<BrowserTaskWithPromise>;\n async createTask<T>(input: BrowserTaskInputWithSchema<T>): Promise<BrowserTaskWithPromiseAndSchema<T>>;\n async createTask<T>(\n input: BrowserTaskInput | BrowserTaskInputWithSchema<T>\n ): Promise<BrowserTaskWithPromise | BrowserTaskWithPromiseAndSchema<T>> {\n const apiUrl = this.config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = this.config.debug || false;\n \n if (debug) {\n console.log(`[Browser] createTask: \"${input.task.slice(0, 60)}...\" url=${input.url || 'none'}`);\n console.log(`[Browser] Calling async endpoint: ${apiUrl}/browser-task/async`);\n }\n \n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiKey) headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n \n // Call ASYNC endpoint for immediate return with live URL\n const response = await fetch(`${apiUrl}/browser-task/async`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n task: input.task,\n url: input.url,\n max_steps: input.max_steps ?? 10,\n model: input.model ?? 'morph-computer-use-v0',\n viewport_width: input.viewport_width ?? 1280,\n viewport_height: input.viewport_height ?? 720,\n external_id: input.external_id,\n repo_id: input.repo_id,\n commit_id: input.commit_id,\n record_video: input.record_video ?? false,\n video_width: input.video_width ?? input.viewport_width ?? 1280,\n video_height: input.video_height ?? input.viewport_height ?? 720,\n allow_resizing: input.allow_resizing ?? false,\n structured_output: 'schema' in input ? stringifyStructuredOutput(input.schema) : undefined,\n }),\n });\n \n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n \n const result = await response.json();\n \n if (debug) {\n console.log(`[Browser] ✅ Task created: recording_id=${result.recording_id ?? 'none'} debug_url=${result.debugUrl ? 'available' : 'none'}`);\n }\n \n if ('schema' in input) {\n return wrapTaskResponseWithSchema(result, this.config, input.schema);\n } else {\n return wrapTaskResponse(result, this.config);\n }\n }\n\n /**\n * Execute task with recording and wait for video to be ready\n */\n async executeWithRecording(\n input: BrowserTaskInput & { record_video: true }\n ): Promise<BrowserTaskResult & { recording?: RecordingStatus }> {\n return executeWithRecording(input, this.config);\n }\n\n /**\n * Get recording status and URLs\n */\n async getRecording(recordingId: string): Promise<RecordingStatus> {\n return getRecording(recordingId, this.config);\n }\n\n /**\n * Wait for recording to complete with automatic polling\n */\n async waitForRecording(\n recordingId: string,\n options?: { timeout?: number; pollInterval?: number }\n ): Promise<RecordingStatus> {\n return waitForRecording(recordingId, this.config, options);\n }\n\n /**\n * Get errors from recording with screenshots\n */\n async getErrors(recordingId: string): Promise<ErrorsResponse> {\n return getErrors(recordingId, this.config);\n }\n\n /**\n * Check if browser worker service is healthy\n */\n async checkHealth(): Promise<{\n ok: boolean;\n google_configured: boolean;\n database_configured: boolean;\n s3_configured: boolean;\n error?: string;\n }> {\n return checkHealth(this.config);\n }\n}\n\n/**\n * Execute a natural language browser automation task\n * \n * Returns the full task result including rich agent history data (urls, errors, \n * action_history, judgement, etc.). When using this as an agent tool, use the\n * formatResult() functions from the SDK adapters to return a concise summary.\n * \n * @param input - Task parameters\n * @param config - Optional configuration (apiKey, apiUrl to override default)\n * @returns Task result with success status, findings, and comprehensive execution history\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask(\n * {\n * task: \"Test checkout flow for buying a pineapple\",\n * url: \"https://3000-abc.e2b.dev\",\n * max_steps: 20,\n * repo_id: \"my-project\",\n * commit_id: \"uuid-here\"\n * },\n * {\n * apiKey: process.env.MORPH_API_KEY,\n * // apiUrl: 'http://localhost:8001' // Override for local testing\n * }\n * );\n * \n * if (result.success) {\n * console.log('Task completed:', result.result);\n * console.log('URLs visited:', result.urls);\n * console.log('Actions taken:', result.action_names);\n * console.log('Has errors:', result.has_errors);\n * console.log('Replay:', result.replay_url);\n * }\n * ```\n */\nexport async function executeBrowserTask(\n input: BrowserTaskInput,\n config: BrowserConfig = {}\n): Promise<BrowserTaskResult> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const timeout = config.timeout || DEFAULT_CONFIG.timeout;\n const debug = config.debug || false;\n\n if (!input.task || input.task.trim().length === 0) {\n return { \n success: false, \n error: 'Task description is required. Example: \"Go to example.com and click the login button\"' \n };\n }\n\n if (input.max_steps !== undefined && (input.max_steps < 1 || input.max_steps > 50)) {\n return { \n success: false, \n error: 'max_steps must be between 1 and 50. Use more steps for complex multi-page flows.' \n };\n }\n\n if (debug) {\n console.log(`[Browser] Task: \"${input.task.slice(0, 60)}...\" url=${input.url || 'none'} maxSteps=${input.max_steps ?? 10}`);\n console.log(`[Browser] Recording: ${input.record_video ? 'yes' : 'no'} | Calling ${apiUrl}/browser-task`);\n }\n\n const startTime = Date.now();\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n const fetchPromise = fetchWithRetry(\n `${apiUrl}/browser-task`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({\n task: input.task,\n url: input.url,\n max_steps: input.max_steps ?? 10,\n model: input.model ?? 'morph-computer-use-v0',\n viewport_width: input.viewport_width ?? 1280,\n viewport_height: input.viewport_height ?? 720,\n external_id: input.external_id,\n repo_id: input.repo_id,\n commit_id: input.commit_id,\n record_video: input.record_video ?? false,\n video_width: input.video_width ?? input.viewport_width ?? 1280,\n video_height: input.video_height ?? input.viewport_height ?? 720,\n allow_resizing: input.allow_resizing ?? false,\n structured_output: input.structured_output,\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(\n fetchPromise,\n timeout,\n `Browser task timed out after ${timeout}ms. Consider increasing timeout or reducing max_steps.`\n );\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] Error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result: BrowserTaskResult = await response.json();\n const elapsed = Date.now() - startTime;\n \n if (debug) {\n console.log(`[Browser] ✅ ${result.success ? 'Success' : 'Failed'} in ${elapsed}ms | steps=${result.steps_taken ?? 0} recordingId=${result.recording_id ?? 'none'}`);\n }\n\n return result;\n\n } catch (error) {\n if (error instanceof Error) {\n // Handle network errors\n if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {\n return {\n success: false,\n error: `Cannot connect to browser worker at ${apiUrl}. Ensure the service is running and accessible. For local dev, set MORPH_ENVIRONMENT=DEV.`,\n };\n }\n\n return {\n success: false,\n error: error.message,\n };\n }\n\n return {\n success: false,\n error: String(error),\n };\n }\n}\n\n/**\n * Get recording status and video URL\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Recording status with video URL when ready\n * \n * @example\n * ```typescript\n * const status = await getRecording('uuid-here', { apiKey: 'key' });\n * if (status.status === 'COMPLETED' && status.video_url) {\n * console.log('Video ready:', status.video_url);\n * }\n * ```\n */\nexport async function getRecording(\n recordingId: string,\n config: BrowserConfig = {}\n): Promise<RecordingStatus> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (!config.apiKey) {\n throw new Error('API key required for getRecording');\n }\n\n if (debug) console.log(`[Browser] getRecording: ${recordingId}`);\n\n const response = await fetch(`${apiUrl}/recordings/${recordingId}`, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${config.apiKey}` },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getRecording error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const recording = await response.json();\n if (debug) console.log(`[Browser] Recording status: ${recording.status}`);\n\n return recording;\n}\n\n/**\n * Wait for recording to complete with automatic polling\n * \n * @param recordingId - Recording UUID\n * @param config - Configuration with apiKey\n * @param options - Polling options\n * @returns Recording status when completed or errored\n * \n * @example\n * ```typescript\n * const result = await executeBrowserTask({ task: '...', record_video: true }, config);\n * if (result.recording_id) {\n * const recording = await waitForRecording(result.recording_id, config, {\n * timeout: 60000, // 1 minute\n * pollInterval: 2000 // Check every 2 seconds\n * });\n * console.log('Video URL:', recording.video_url);\n * }\n * ```\n */\nexport async function waitForRecording(\n recordingId: string,\n config: BrowserConfig = {},\n options: { timeout?: number; pollInterval?: number } = {}\n): Promise<RecordingStatus> {\n const timeout = options.timeout ?? 60000; // Default 1 minute\n const pollInterval = options.pollInterval ?? 2000; // Default 2 seconds\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const status = await getRecording(recordingId, config);\n \n if (status.status === 'COMPLETED' || status.status === 'ERROR') {\n return status;\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, pollInterval));\n }\n\n throw new Error(`Recording timeout after ${timeout}ms - status still pending`);\n}\n\n/**\n * Execute task with recording and wait for video to be ready\n * \n * @param input - Task parameters with record_video=true\n * @param config - Configuration with apiKey\n * @returns Task result with ready video URL\n * \n * @example\n * ```typescript\n * const result = await executeWithRecording(\n * {\n * task: \"Test checkout flow\",\n * url: \"https://example.com\",\n * record_video: true,\n * repo_id: \"my-project\"\n * },\n * { apiKey: process.env.MORPH_API_KEY }\n * );\n * \n * console.log('Task result:', result.result);\n * console.log('Video URL:', result.recording?.video_url);\n * ```\n */\nexport async function executeWithRecording(\n input: BrowserTaskInput & { record_video: true },\n config: BrowserConfig = {}\n): Promise<BrowserTaskResult & { recording?: RecordingStatus }> {\n // Execute task with recording\n const taskResult = await executeBrowserTask(input, config);\n\n // If recording was created, wait for it to complete\n if (taskResult.recording_id) {\n try {\n const recording = await waitForRecording(\n taskResult.recording_id,\n config,\n { timeout: 60000, pollInterval: 2000 }\n );\n return {\n ...taskResult,\n recording,\n };\n } catch (error) {\n // Return task result even if recording fails\n return {\n ...taskResult,\n recording: {\n id: taskResult.recording_id,\n status: 'ERROR',\n error: error instanceof Error ? error.message : String(error),\n created_at: new Date().toISOString(),\n },\n };\n }\n }\n\n return taskResult;\n}\n\n/**\n * Get errors from recording with screenshots\n * \n * Screenshots are captured in real-time (500ms after error occurs) during the browser session.\n * \n * @param recordingId - Recording UUID from BrowserTaskResult\n * @param config - Configuration with apiKey\n * @returns Errors with real-time screenshots\n * \n * @example\n * ```typescript\n * const { errors, total_errors } = await getErrors('uuid-here', { apiKey: 'key' });\n * \n * console.log(`Found ${total_errors} errors`);\n * \n * errors.forEach(err => {\n * console.log(`[${err.type}] ${err.message}`);\n * if (err.url) console.log(` URL: ${err.url}`);\n * if (err.screenshot_url) console.log(` Screenshot: ${err.screenshot_url}`);\n * \n * // Download screenshot\n * if (err.screenshot_url) {\n * const response = await fetch(err.screenshot_url);\n * const screenshot = await response.arrayBuffer();\n * // Save or process screenshot\n * }\n * });\n * ```\n */\nexport async function getErrors(\n recordingId: string,\n config: BrowserConfig = {}\n): Promise<ErrorsResponse> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (!config.apiKey) {\n throw new Error('API key required for getErrors');\n }\n\n if (debug) console.log(`[Browser] getErrors: ${recordingId}`);\n\n const response = await fetch(`${apiUrl}/recordings/${recordingId}/errors`, {\n method: 'GET',\n headers: { 'Authorization': `Bearer ${config.apiKey}` },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getErrors error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const errors = await response.json();\n if (debug) console.log(`[Browser] Found ${errors.total_errors} errors`);\n\n return errors;\n}\n\n/**\n * Helper to serialize Zod schema for API\n */\nfunction stringifyStructuredOutput(schema: any): string {\n try {\n return JSON.stringify({\n type: 'object',\n description: 'Zod schema definition (Zod v3)',\n zodDef: schema._def,\n });\n } catch (error) {\n console.warn('[Browser] Failed to serialize Zod schema:', error);\n return JSON.stringify({\n type: 'object',\n description: 'Schema serialization failed',\n });\n }\n}\n\n/**\n * Parse and validate structured task output\n */\nfunction parseStructuredTaskOutput<T>(\n result: BrowserTaskResult,\n schema: any\n): BrowserTaskResult & { parsed: T | null } {\n if (!result.output) {\n return { ...result, parsed: null };\n }\n\n try {\n const parsed = JSON.parse(result.output);\n const validated = schema.parse(parsed) as T;\n return { ...result, parsed: validated };\n } catch (error) {\n if (error instanceof SyntaxError) {\n return { ...result, parsed: null };\n }\n throw error;\n }\n}\n\n/**\n * Get current task status\n */\nasync function getTaskStatus(\n taskId: string,\n config: BrowserConfig\n): Promise<BrowserTaskResult> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const debug = config.debug || false;\n\n if (debug) console.log(`[Browser] getTaskStatus: ${taskId}`);\n\n const headers: Record<string, string> = {};\n if (config.apiKey) headers['Authorization'] = `Bearer ${config.apiKey}`;\n\n const response = await fetch(`${apiUrl}/tasks/${taskId}`, {\n method: 'GET',\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n if (debug) console.error(`[Browser] getTaskStatus error: ${response.status} - ${errorText}`);\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n const result: BrowserTaskResult = await response.json();\n if (debug) console.log(`[Browser] Task status: ${result.status}`);\n\n return result;\n}\n\n/**\n * Generate live URL for watching task execution in real-time\n */\nfunction generateLiveUrl(taskId: string, config: BrowserConfig): string {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n const baseUrl = apiUrl.replace('/api', '');\n return `${baseUrl}/tasks/${taskId}/live`;\n}\n\n/**\n * Poll task until completion\n */\nasync function pollTaskUntilComplete(\n taskId: string,\n config: BrowserConfig,\n pollConfig: { interval?: number; timeout?: number } = {}\n): Promise<BrowserTaskResult> {\n const interval = pollConfig.interval ?? 2000; // 2 seconds\n const timeout = pollConfig.timeout ?? 300000; // 5 minutes\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const status = await getTaskStatus(taskId, config);\n \n if (status.status === 'completed' || status.status === 'failed') {\n return status;\n }\n\n await new Promise(resolve => setTimeout(resolve, interval));\n }\n\n throw new Error(`Task polling timeout after ${timeout}ms`);\n}\n\n/**\n * Wrap task response with convenience methods\n */\nfunction wrapTaskResponse(\n result: BrowserTaskResult,\n config: BrowserConfig\n): BrowserTaskWithPromise {\n const wrapped: BrowserTaskWithPromise = {\n ...result,\n task_id: result.task_id || '',\n liveUrl: result.task_id \n ? generateLiveUrl(result.task_id, config)\n : result.debugUrl || '',\n complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n // If we have a task_id, poll task status endpoint\n if (result.task_id) {\n return pollTaskUntilComplete(result.task_id!, config, pollConfig);\n }\n // If we have a recording_id, poll recording status instead\n if (result.recording_id) {\n const recording = await waitForRecording(\n result.recording_id,\n config,\n pollConfig\n );\n // Return a result-like object (recording doesn't have full task result)\n return {\n ...result,\n recording_status: recording.status,\n } as BrowserTaskResult;\n }\n // No way to poll completion\n throw new Error('Cannot poll completion: no task_id or recording_id available');\n },\n // Add Steel live session helpers - either functional or error-throwing\n getLiveUrl: result.debugUrl\n ? (options?: LiveSessionOptions) => buildLiveUrl(result.debugUrl!, options)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n getLiveIframe: result.debugUrl\n ? (optionsOrPreset?: string | IframeOptions) => {\n const options = resolvePreset(optionsOrPreset);\n return buildLiveIframe(result.debugUrl!, options);\n }\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n getEmbedCode: result.debugUrl\n ? () => buildEmbedCode(result.debugUrl!)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. Contact support@morphllm.com if you need help.'\n );\n },\n };\n\n return wrapped;\n}\n\n/**\n * Wrap task response with schema validation\n */\nfunction wrapTaskResponseWithSchema<T>(\n result: BrowserTaskResult,\n config: BrowserConfig,\n schema: any\n): BrowserTaskWithPromiseAndSchema<T> {\n const parsed = result.output\n ? parseStructuredTaskOutput<T>(result, schema)\n : { ...result, parsed: null };\n\n const wrapped: BrowserTaskWithPromiseAndSchema<T> = {\n ...parsed,\n task_id: result.task_id || '',\n liveUrl: result.task_id\n ? generateLiveUrl(result.task_id, config)\n : result.debugUrl || '',\n complete: async (pollConfig?: { interval?: number; timeout?: number }) => {\n // If we have a task_id, poll task status endpoint\n if (result.task_id) {\n const finalResult = await pollTaskUntilComplete(result.task_id!, config, pollConfig);\n return parseStructuredTaskOutput<T>(finalResult, schema);\n }\n // If we have a recording_id, poll recording status instead\n if (result.recording_id) {\n const recording = await waitForRecording(\n result.recording_id,\n config,\n pollConfig\n );\n // Return parsed result (recording doesn't have task output)\n return {\n ...parsed,\n recording_status: recording.status,\n };\n }\n // No way to poll completion\n throw new Error('Cannot poll completion: no task_id or recording_id available');\n },\n // Add Steel live session helpers - either functional or error-throwing\n getLiveUrl: result.debugUrl\n ? (options?: LiveSessionOptions) => buildLiveUrl(result.debugUrl!, options)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions. '\n );\n },\n getLiveIframe: result.debugUrl\n ? (optionsOrPreset?: string | IframeOptions) => {\n const options = resolvePreset(optionsOrPreset);\n return buildLiveIframe(result.debugUrl!, options);\n }\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions.'\n );\n },\n getEmbedCode: result.debugUrl\n ? () => buildEmbedCode(result.debugUrl!)\n : () => {\n throw new Error(\n 'Live sessions not available. Your backend must return a debugUrl in the response. ' +\n 'Contact support@morphllm.com if you need help enabling live sessions.'\n );\n },\n };\n\n return wrapped;\n}\n\n/**\n * Check if browser worker service is healthy\n * \n * @param config - Optional configuration\n * @returns Health status\n */\nexport async function checkHealth(config: BrowserConfig = {}): Promise<{\n ok: boolean;\n google_configured: boolean;\n database_configured: boolean;\n s3_configured: boolean;\n error?: string;\n}> {\n const apiUrl = config.apiUrl || DEFAULT_CONFIG.apiUrl;\n\n try {\n const response = await fetch(`${apiUrl}/health`, {\n method: 'GET',\n headers: config.apiKey\n ? { 'Authorization': `Bearer ${config.apiKey}` }\n : {},\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return {\n ok: true,\n google_configured: data.google_configured ?? false,\n database_configured: data.database_configured ?? false,\n s3_configured: data.s3_configured ?? false,\n };\n } catch (error) {\n return {\n ok: false,\n google_configured: false,\n database_configured: false,\n s3_configured: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n"],"mappings":"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","names":[]}
|
|
@@ -101,28 +101,26 @@ var MorphGit = class {
|
|
|
101
101
|
* ```ts
|
|
102
102
|
* await morphGit.push({
|
|
103
103
|
* dir: './my-project',
|
|
104
|
-
* branch: 'main' // Required: explicit branch name
|
|
104
|
+
* branch: 'main', // Required: explicit branch name
|
|
105
|
+
* index: true // Optional: generate embeddings (default: true)
|
|
105
106
|
* });
|
|
106
107
|
* ```
|
|
107
108
|
*/
|
|
108
109
|
async push(options) {
|
|
109
|
-
const { dir, remote = "origin", branch, waitForEmbeddings } = options;
|
|
110
|
+
const { dir, remote = "origin", branch, waitForEmbeddings, index = true } = options;
|
|
110
111
|
if (!branch) {
|
|
111
112
|
throw new Error(
|
|
112
113
|
'branch is required for push operations. Specify the branch explicitly: { dir: "./my-project", branch: "main" }'
|
|
113
114
|
);
|
|
114
115
|
}
|
|
115
|
-
|
|
116
|
+
const commitHash = await git.resolveRef({ fs, dir, ref: "HEAD" });
|
|
116
117
|
let repoId;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
if (match) {
|
|
124
|
-
repoId = match[1];
|
|
125
|
-
}
|
|
118
|
+
const remotes = await git.listRemotes({ fs, dir });
|
|
119
|
+
const originRemote = remotes.find((r) => r.remote === remote);
|
|
120
|
+
if (originRemote) {
|
|
121
|
+
const match = originRemote.url.match(/\/repos\/([^\/]+)$/);
|
|
122
|
+
if (match) {
|
|
123
|
+
repoId = match[1];
|
|
126
124
|
}
|
|
127
125
|
}
|
|
128
126
|
await git.push({
|
|
@@ -133,10 +131,35 @@ var MorphGit = class {
|
|
|
133
131
|
ref: branch,
|
|
134
132
|
onAuth: this.getAuthCallback()
|
|
135
133
|
});
|
|
136
|
-
if (
|
|
134
|
+
if (repoId && commitHash) {
|
|
135
|
+
await this.configureCommit({ repoId, commitHash, branch, index });
|
|
136
|
+
}
|
|
137
|
+
if (waitForEmbeddings && repoId && commitHash && index) {
|
|
137
138
|
await this.waitForEmbeddings({ repoId, commitHash });
|
|
138
139
|
}
|
|
139
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Configure commit settings on the backend after push.
|
|
143
|
+
* Sets the index flag to control embedding generation.
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
async configureCommit(options) {
|
|
147
|
+
const { repoId, commitHash, branch, index } = options;
|
|
148
|
+
const response = await fetch(
|
|
149
|
+
`${this.proxyUrl}/v1/repos/${repoId}/commits/${commitHash}/config`,
|
|
150
|
+
{
|
|
151
|
+
method: "POST",
|
|
152
|
+
headers: {
|
|
153
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
154
|
+
"Content-Type": "application/json"
|
|
155
|
+
},
|
|
156
|
+
body: JSON.stringify({ index, branch })
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
console.warn(`Failed to configure commit: ${response.status}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
140
163
|
/**
|
|
141
164
|
* Pull changes from remote repository
|
|
142
165
|
*
|
|
@@ -261,6 +284,7 @@ var MorphGit = class {
|
|
|
261
284
|
* name: 'AI Agent',
|
|
262
285
|
* email: 'ai@example.com'
|
|
263
286
|
* },
|
|
287
|
+
* metadata: { issueId: 'PROJ-123', source: 'agent' },
|
|
264
288
|
* chatHistory: [
|
|
265
289
|
* { role: 'user', content: 'Please add a new feature' },
|
|
266
290
|
* { role: 'assistant', content: 'I will add that feature' }
|
|
@@ -270,7 +294,7 @@ var MorphGit = class {
|
|
|
270
294
|
* ```
|
|
271
295
|
*/
|
|
272
296
|
async commit(options) {
|
|
273
|
-
const { dir, message, author, chatHistory, recordingId } = options;
|
|
297
|
+
const { dir, message, author, metadata, chatHistory, recordingId } = options;
|
|
274
298
|
const commitAuthor = author || {
|
|
275
299
|
name: "Morph SDK",
|
|
276
300
|
email: "sdk@morphllm.com"
|
|
@@ -281,17 +305,19 @@ var MorphGit = class {
|
|
|
281
305
|
message,
|
|
282
306
|
author: commitAuthor
|
|
283
307
|
});
|
|
284
|
-
if (chatHistory || recordingId) {
|
|
285
|
-
const
|
|
308
|
+
if (metadata || chatHistory || recordingId) {
|
|
309
|
+
const notes = {
|
|
310
|
+
metadata,
|
|
286
311
|
chatHistory,
|
|
287
|
-
recordingId
|
|
312
|
+
recordingId,
|
|
313
|
+
_version: 1
|
|
288
314
|
};
|
|
289
315
|
await git.addNote({
|
|
290
316
|
fs,
|
|
291
317
|
dir,
|
|
292
318
|
ref: "refs/notes/morph-metadata",
|
|
293
319
|
oid: sha,
|
|
294
|
-
note: JSON.stringify(
|
|
320
|
+
note: JSON.stringify(notes, null, 2),
|
|
295
321
|
author: commitAuthor
|
|
296
322
|
});
|
|
297
323
|
}
|
|
@@ -480,18 +506,19 @@ var MorphGit = class {
|
|
|
480
506
|
return oid;
|
|
481
507
|
}
|
|
482
508
|
/**
|
|
483
|
-
* Get metadata
|
|
509
|
+
* Get notes (metadata, chat history, recording ID) attached to a commit
|
|
484
510
|
*
|
|
485
511
|
* @example
|
|
486
512
|
* ```ts
|
|
487
|
-
* const
|
|
513
|
+
* const notes = await morphGit.getCommitMetadata({
|
|
488
514
|
* dir: './my-project',
|
|
489
515
|
* commitSha: 'abc123...'
|
|
490
516
|
* });
|
|
491
517
|
*
|
|
492
|
-
* if (
|
|
493
|
-
* console.log('
|
|
494
|
-
* console.log('
|
|
518
|
+
* if (notes) {
|
|
519
|
+
* console.log('Metadata:', notes.metadata);
|
|
520
|
+
* console.log('Chat history:', notes.chatHistory);
|
|
521
|
+
* console.log('Recording ID:', notes.recordingId);
|
|
495
522
|
* }
|
|
496
523
|
* ```
|
|
497
524
|
*/
|
|
@@ -503,8 +530,8 @@ var MorphGit = class {
|
|
|
503
530
|
ref: "refs/notes/morph-metadata",
|
|
504
531
|
oid: options.commitSha
|
|
505
532
|
});
|
|
506
|
-
const
|
|
507
|
-
return
|
|
533
|
+
const notes = JSON.parse(new TextDecoder().decode(note));
|
|
534
|
+
return notes;
|
|
508
535
|
} catch (err) {
|
|
509
536
|
return null;
|
|
510
537
|
}
|
|
@@ -514,4 +541,4 @@ var MorphGit = class {
|
|
|
514
541
|
export {
|
|
515
542
|
MorphGit
|
|
516
543
|
};
|
|
517
|
-
//# sourceMappingURL=chunk-
|
|
544
|
+
//# sourceMappingURL=chunk-OXHGFHEU.js.map
|