mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-03 16:43:26 +00:00
feat: Open pull request in last step (#32)
* feat: Open pull request in last step * cr * cr
This commit is contained in:
parent
76dadeeb72
commit
b9d15e9f27
7 changed files with 357 additions and 2 deletions
|
|
@ -29,6 +29,7 @@
|
||||||
"@langchain/langgraph": "^0.2.73",
|
"@langchain/langgraph": "^0.2.73",
|
||||||
"@langchain/langgraph-sdk": "^0.0.78",
|
"@langchain/langgraph-sdk": "^0.0.78",
|
||||||
"@langchain/openai": "^0.5.10",
|
"@langchain/openai": "^0.5.10",
|
||||||
|
"@octokit/rest": "^22.0.0",
|
||||||
"diff": "^8.0.1",
|
"diff": "^8.0.1",
|
||||||
"langchain": "^0.3.26",
|
"langchain": "^0.3.26",
|
||||||
"langsmith": "^0.3.29",
|
"langsmith": "^0.3.29",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
progressPlanStep,
|
progressPlanStep,
|
||||||
summarizeTaskSteps,
|
summarizeTaskSteps,
|
||||||
generateConclusion,
|
generateConclusion,
|
||||||
|
openPullRequest,
|
||||||
diagnoseError,
|
diagnoseError,
|
||||||
} from "./nodes/index.js";
|
} from "./nodes/index.js";
|
||||||
import { isAIMessage } from "@langchain/core/messages";
|
import { isAIMessage } from "@langchain/core/messages";
|
||||||
|
|
@ -54,6 +55,7 @@ const workflow = new StateGraph(GraphAnnotation, GraphConfiguration)
|
||||||
ends: ["generate-action", "generate-conclusion"],
|
ends: ["generate-action", "generate-conclusion"],
|
||||||
})
|
})
|
||||||
.addNode("generate-conclusion", generateConclusion)
|
.addNode("generate-conclusion", generateConclusion)
|
||||||
|
.addNode("open-pr", openPullRequest)
|
||||||
.addNode("diagnose-error", diagnoseError)
|
.addNode("diagnose-error", diagnoseError)
|
||||||
.addEdge(START, "initialize")
|
.addEdge(START, "initialize")
|
||||||
.addEdge("initialize", "generate-plan-subgraph")
|
.addEdge("initialize", "generate-plan-subgraph")
|
||||||
|
|
@ -61,8 +63,9 @@ const workflow = new StateGraph(GraphAnnotation, GraphConfiguration)
|
||||||
// Always interrupt after rewriting the plan.
|
// Always interrupt after rewriting the plan.
|
||||||
.addEdge("rewrite-plan", "interrupt-plan")
|
.addEdge("rewrite-plan", "interrupt-plan")
|
||||||
.addConditionalEdges("generate-action", takeActionOrEnd, ["take-action", END])
|
.addConditionalEdges("generate-action", takeActionOrEnd, ["take-action", END])
|
||||||
|
.addEdge("generate-conclusion", "open-pr")
|
||||||
.addEdge("diagnose-error", "generate-action")
|
.addEdge("diagnose-error", "generate-action")
|
||||||
.addEdge("generate-conclusion", END);
|
.addEdge("open-pr", END);
|
||||||
|
|
||||||
// Zod types are messed up
|
// Zod types are messed up
|
||||||
export const graph = workflow.compile() as any;
|
export const graph = workflow.compile() as any;
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ export * from "./interrupt-plan.js";
|
||||||
export * from "./progress-plan-step.js";
|
export * from "./progress-plan-step.js";
|
||||||
export * from "./summarize-task-steps.js";
|
export * from "./summarize-task-steps.js";
|
||||||
export * from "./generate-conclusion.js";
|
export * from "./generate-conclusion.js";
|
||||||
|
export * from "./open-pr.js";
|
||||||
export * from "./diagnose-error.js";
|
export * from "./diagnose-error.js";
|
||||||
|
|
|
||||||
148
apps/open-swe/src/nodes/open-pr.ts
Normal file
148
apps/open-swe/src/nodes/open-pr.ts
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
|
||||||
|
import { Sandbox } from "@e2b/code-interpreter";
|
||||||
|
import {
|
||||||
|
checkoutBranchAndCommit,
|
||||||
|
createPullRequest,
|
||||||
|
getBranchName,
|
||||||
|
getChangedFilesStatus,
|
||||||
|
getRepoAbsolutePath,
|
||||||
|
} from "../utils/git/index.js";
|
||||||
|
import { createLogger, LogLevel } from "../utils/logger.js";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { loadModel, Task } from "../utils/load-model.js";
|
||||||
|
import { formatPlanPromptWithSummaries } from "../utils/plan-prompt.js";
|
||||||
|
import { isHumanMessage, ToolMessage } from "@langchain/core/messages";
|
||||||
|
import { getMessageContentString } from "../utils/message/content.js";
|
||||||
|
|
||||||
|
const logger = createLogger(LogLevel.INFO, "Open PR");
|
||||||
|
|
||||||
|
const openPrSysPrompt = `You are operating as a terminal-based agentic coding assistant built by LangChain. It wraps LLM models to enable natural language interaction with a local codebase. You are expected to be precise, safe, and helpful.
|
||||||
|
|
||||||
|
You have just completed all of your tasks, and are now ready to open a pull request.
|
||||||
|
|
||||||
|
Here are all of the tasks you completed:
|
||||||
|
{COMPLETED_TASKS}
|
||||||
|
|
||||||
|
And here is the user's original request:
|
||||||
|
{USER_REQUEST}
|
||||||
|
|
||||||
|
With all of this in mind, please use the \`open_pr\` tool to open a pull request.`;
|
||||||
|
|
||||||
|
const openPrToolSchema = z.object({
|
||||||
|
title: z
|
||||||
|
.string()
|
||||||
|
.describe(
|
||||||
|
"The title of the pull request. Ensure this is a concise and thoughtful title. You should follow conventional commit title format (e.g. prefixing with 'fix:', 'feat:', 'chore:', etc.).",
|
||||||
|
),
|
||||||
|
body: z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.describe(
|
||||||
|
"The body of the pull request. This should provide a detailed description of the changes you've made, and why you've made them. Ensure you do not over-explain the changes, as we do not want to waste the user's time.",
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const openPrTool = {
|
||||||
|
name: "open_pr",
|
||||||
|
schema: openPrToolSchema,
|
||||||
|
description: "Use this tool to open a pull request.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatPrompt = (plan: PlanItem[], userRequest: string): string => {
|
||||||
|
const completedTasks = plan.filter((task) => task.completed);
|
||||||
|
return openPrSysPrompt
|
||||||
|
.replace("{COMPLETED_TASKS}", formatPlanPromptWithSummaries(completedTasks))
|
||||||
|
.replace("{USER_REQUEST}", userRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function openPullRequest(
|
||||||
|
state: GraphState,
|
||||||
|
config: GraphConfig,
|
||||||
|
): Promise<GraphUpdate> {
|
||||||
|
const sandboxSessionId = state.sandboxSessionId;
|
||||||
|
if (!sandboxSessionId) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to open pull request: No sandbox session ID found in state.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sandbox = await Sandbox.connect(sandboxSessionId);
|
||||||
|
|
||||||
|
const { owner, repo } = config.configurable?.target_repository ?? {};
|
||||||
|
|
||||||
|
if (!owner || !repo) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to open pull request: No target repository found in config.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const changedFiles = await getChangedFilesStatus(
|
||||||
|
getRepoAbsolutePath(config),
|
||||||
|
sandbox,
|
||||||
|
);
|
||||||
|
let branchName = state.branchName;
|
||||||
|
if (changedFiles.length > 0) {
|
||||||
|
logger.info(`Has ${changedFiles.length} changed files. Committing.`, {
|
||||||
|
changedFiles,
|
||||||
|
});
|
||||||
|
branchName = await checkoutBranchAndCommit(config, sandbox, {
|
||||||
|
branchName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const model = await loadModel(config, Task.SUMMARIZER);
|
||||||
|
const modelWithTool = model.bindTools([openPrTool], {
|
||||||
|
tool_choice: openPrTool.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstUserMessage = state.messages.find(isHumanMessage);
|
||||||
|
if (!firstUserMessage) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to open pull request: No user message found in state.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await modelWithTool.invoke([
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: formatPrompt(
|
||||||
|
state.plan,
|
||||||
|
getMessageContentString(firstUserMessage.content),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const toolCall = response.tool_calls?.[0];
|
||||||
|
|
||||||
|
if (!toolCall) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to generate a tool call when opening a pull request.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, body } = toolCall.args as z.infer<typeof openPrToolSchema>;
|
||||||
|
|
||||||
|
const pr = await createPullRequest({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
headBranch: branchName ?? getBranchName(config),
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
messages: [
|
||||||
|
response,
|
||||||
|
new ToolMessage({
|
||||||
|
tool_call_id: toolCall.id ?? "",
|
||||||
|
content: pr
|
||||||
|
? `Created pull request: ${pr.html_url}`
|
||||||
|
: "Failed to create pull request.",
|
||||||
|
name: toolCall.name,
|
||||||
|
additional_kwargs: {
|
||||||
|
pull_request: pr,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { Octokit } from "@octokit/rest";
|
||||||
import { CommandResult, Sandbox } from "@e2b/code-interpreter";
|
import { CommandResult, Sandbox } from "@e2b/code-interpreter";
|
||||||
import { createLogger, LogLevel } from "../logger.js";
|
import { createLogger, LogLevel } from "../logger.js";
|
||||||
import { GraphConfig } from "../../types.js";
|
import { GraphConfig } from "../../types.js";
|
||||||
|
|
@ -390,3 +391,58 @@ export async function checkoutBranchAndCommit(
|
||||||
|
|
||||||
return branchName;
|
return branchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createPullRequest({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
headBranch,
|
||||||
|
title,
|
||||||
|
body = "",
|
||||||
|
}: {
|
||||||
|
owner: string;
|
||||||
|
repo: string;
|
||||||
|
headBranch: string;
|
||||||
|
title: string;
|
||||||
|
body?: string;
|
||||||
|
}) {
|
||||||
|
// Initialize Octokit with the personal access token
|
||||||
|
const token = process.env.GITHUB_PAT;
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("GITHUB_PAT environment variable is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: token,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Step 1: Get repository information to find the default branch
|
||||||
|
const { data: repository } = await octokit.repos.get({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultBranch = repository.default_branch;
|
||||||
|
logger.info(
|
||||||
|
`Creating pull request against default branch: ${defaultBranch}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Step 2: Create the pull request
|
||||||
|
const { data: pullRequest } = await octokit.pulls.create({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
head: headBranch,
|
||||||
|
base: defaultBranch,
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info(`🐙 Pull request created: ${pullRequest.html_url}`);
|
||||||
|
return pullRequest;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(`Failed to create pull request`, {
|
||||||
|
error,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"extends": ["//"],
|
"extends": ["//"],
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"build": {
|
"build": {
|
||||||
"outputs": [".dist/**"]
|
"outputs": ["dist/**"]
|
||||||
},
|
},
|
||||||
"dev": {
|
"dev": {
|
||||||
"dependsOn": ["^dev"]
|
"dependsOn": ["^dev"]
|
||||||
|
|
|
||||||
146
yarn.lock
146
yarn.lock
|
|
@ -2472,6 +2472,130 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/auth-token@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@octokit/auth-token@npm:6.0.0"
|
||||||
|
checksum: 9c23be526c7f8e282aa7ccec6f3a72a1beec44eae736327e9ba78419fa28ba75e2c686e9eac75f35ce99bdb55eff9605f7ef7588a9d4f4e18ad5ed16a5d887ab
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/core@npm:^7.0.2":
|
||||||
|
version: 7.0.2
|
||||||
|
resolution: "@octokit/core@npm:7.0.2"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/auth-token": ^6.0.0
|
||||||
|
"@octokit/graphql": ^9.0.1
|
||||||
|
"@octokit/request": ^10.0.2
|
||||||
|
"@octokit/request-error": ^7.0.0
|
||||||
|
"@octokit/types": ^14.0.0
|
||||||
|
before-after-hook: ^4.0.0
|
||||||
|
universal-user-agent: ^7.0.0
|
||||||
|
checksum: 569e65c7fc23518c5e058aad280b669f33a82fa9f4c26afa4481ed0488147ec779907b3cd0a333eda850b0127ab46dc0caeeb27fb72eca0ed60db23c30d75bf0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/endpoint@npm:^11.0.0":
|
||||||
|
version: 11.0.0
|
||||||
|
resolution: "@octokit/endpoint@npm:11.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/types": ^14.0.0
|
||||||
|
universal-user-agent: ^7.0.2
|
||||||
|
checksum: 1c4bd71b3041bf935535c13e9636cb9846469655050583e0ad2595f2f1f840eba2a3f5f43a0dbc82fd695ad0124ab4fc389a2ef3d0770d642fed717e31e4300f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/graphql@npm:^9.0.1":
|
||||||
|
version: 9.0.1
|
||||||
|
resolution: "@octokit/graphql@npm:9.0.1"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/request": ^10.0.2
|
||||||
|
"@octokit/types": ^14.0.0
|
||||||
|
universal-user-agent: ^7.0.0
|
||||||
|
checksum: 3d59773cf56333be8668f7708c473f5746ad49552c0e542ae32c0442e0f16c4b6389408c8868f211b45d0292f1ebfdc92160ee6c2cbf12c5fa0d9a938713bcf9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/openapi-types@npm:^25.1.0":
|
||||||
|
version: 25.1.0
|
||||||
|
resolution: "@octokit/openapi-types@npm:25.1.0"
|
||||||
|
checksum: 441b17f801254629b3ddb4b878c589fee1fd23015253c8b72a3acb3eeedbe981691bb311649ab5f955005c5d7adb940f19e18eaf0c875752fe0cc12b3dc1d24b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/plugin-paginate-rest@npm:^13.0.1":
|
||||||
|
version: 13.0.1
|
||||||
|
resolution: "@octokit/plugin-paginate-rest@npm:13.0.1"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/types": ^14.1.0
|
||||||
|
peerDependencies:
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
checksum: 4b74c601346a055d1ebf007137bc9e47f0a4276b0767fb7d833e81b3ffda5901b4f0e1bac0d059e733b2caddaeb7df0cae36b98d9085d1690aa81dcd5bb9994a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/plugin-request-log@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@octokit/plugin-request-log@npm:6.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
checksum: 8a79973b1429bfead9113c4117f418aaef5ff368795daded3415ba14623d97d5fc08d1e822dbd566ecc9f041119e1a48a11853a9c48d9eb1caa62baa79c17f83
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/plugin-rest-endpoint-methods@npm:^16.0.0":
|
||||||
|
version: 16.0.0
|
||||||
|
resolution: "@octokit/plugin-rest-endpoint-methods@npm:16.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/types": ^14.1.0
|
||||||
|
peerDependencies:
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
checksum: 8ebb30b41628b839cca0b1051459f92001db37f4c3b8a87551915cdf5707d9e87f300565795ca2c12b5767b0d294b15bb0cd1ab3da99620c82690b37eddbd635
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/request-error@npm:^7.0.0":
|
||||||
|
version: 7.0.0
|
||||||
|
resolution: "@octokit/request-error@npm:7.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/types": ^14.0.0
|
||||||
|
checksum: c4370d2c31f599c1f366c480d5a02bc93442e5a0e151ec5caf0d5a5b0f0f91b50ecedc945aa6ea61b4c9ed1e89153dc7727daf4317680d33e916f829da7d141b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/request@npm:^10.0.2":
|
||||||
|
version: 10.0.2
|
||||||
|
resolution: "@octokit/request@npm:10.0.2"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/endpoint": ^11.0.0
|
||||||
|
"@octokit/request-error": ^7.0.0
|
||||||
|
"@octokit/types": ^14.0.0
|
||||||
|
fast-content-type-parse: ^3.0.0
|
||||||
|
universal-user-agent: ^7.0.2
|
||||||
|
checksum: 66e56fbf8d3df538c68881eab393e4ebca418204c6f452d39f95d050ec6151169efd1dac3cea9def3f1ebfc8ddc7fad7721f39d2f793f60d52d63cd386b11a90
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/rest@npm:^22.0.0":
|
||||||
|
version: 22.0.0
|
||||||
|
resolution: "@octokit/rest@npm:22.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/core": ^7.0.2
|
||||||
|
"@octokit/plugin-paginate-rest": ^13.0.1
|
||||||
|
"@octokit/plugin-request-log": ^6.0.0
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": ^16.0.0
|
||||||
|
checksum: 6a7eff019c0889b23c0820831936e5dc8fa7643bdf0e98ba073b36a10f5602b9f283ca2c74ec8172b8529d0647dfa4a7857dcd81ca028b303937f26750a6c7f6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@octokit/types@npm:^14.0.0, @octokit/types@npm:^14.1.0":
|
||||||
|
version: 14.1.0
|
||||||
|
resolution: "@octokit/types@npm:14.1.0"
|
||||||
|
dependencies:
|
||||||
|
"@octokit/openapi-types": ^25.1.0
|
||||||
|
checksum: 0513520e26dc5395c3b3b407568151d32be1f51bedb151f5b294cadc72dc3fe2d0dbbccad96f01dc80d26247b4aed3358de0ce31ad3c013eb22b96e6234feeb5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@open-agent-platform/docs@workspace:apps/docs":
|
"@open-agent-platform/docs@workspace:apps/docs":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@open-agent-platform/docs@workspace:apps/docs"
|
resolution: "@open-agent-platform/docs@workspace:apps/docs"
|
||||||
|
|
@ -2495,6 +2619,7 @@ __metadata:
|
||||||
"@langchain/langgraph-cli": latest
|
"@langchain/langgraph-cli": latest
|
||||||
"@langchain/langgraph-sdk": ^0.0.78
|
"@langchain/langgraph-sdk": ^0.0.78
|
||||||
"@langchain/openai": ^0.5.10
|
"@langchain/openai": ^0.5.10
|
||||||
|
"@octokit/rest": ^22.0.0
|
||||||
"@tsconfig/recommended": ^1.0.8
|
"@tsconfig/recommended": ^1.0.8
|
||||||
"@types/jest": ^29.5.0
|
"@types/jest": ^29.5.0
|
||||||
"@types/node": ^22.13.5
|
"@types/node": ^22.13.5
|
||||||
|
|
@ -5328,6 +5453,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"before-after-hook@npm:^4.0.0":
|
||||||
|
version: 4.0.0
|
||||||
|
resolution: "before-after-hook@npm:4.0.0"
|
||||||
|
checksum: a8cbd4d3c48f42f44307ef5966be152b836d2e5908834f2f885ddf104c2e2ba66dbb5e6ef89a37e77371b1d22d5c75b74df1472286c684a037c1a6db43f5617b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"better-opn@npm:^3.0.2":
|
"better-opn@npm:^3.0.2":
|
||||||
version: 3.0.2
|
version: 3.0.2
|
||||||
resolution: "better-opn@npm:3.0.2"
|
resolution: "better-opn@npm:3.0.2"
|
||||||
|
|
@ -7769,6 +7901,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"fast-content-type-parse@npm:^3.0.0":
|
||||||
|
version: 3.0.0
|
||||||
|
resolution: "fast-content-type-parse@npm:3.0.0"
|
||||||
|
checksum: 490199423215b8a9c6e24a5a01a0d072af8ebfe24c13deac0a393dcac36b732295dd8cec5a2c4241249ed0fffc6983ba138f3001b13286afefb66360b6715a46
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
|
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
|
||||||
version: 3.1.3
|
version: 3.1.3
|
||||||
resolution: "fast-deep-equal@npm:3.1.3"
|
resolution: "fast-deep-equal@npm:3.1.3"
|
||||||
|
|
@ -15715,6 +15854,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2":
|
||||||
|
version: 7.0.3
|
||||||
|
resolution: "universal-user-agent@npm:7.0.3"
|
||||||
|
checksum: c497e85f8b11eb8fa4dce584d7a39cc98710164959f494cafc3c269b51abb20fff269951838efd7424d15f6b3d001507f3cb8b52bb5676fdb642019dfd17e63e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"universalify@npm:^2.0.0":
|
"universalify@npm:^2.0.0":
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
resolution: "universalify@npm:2.0.1"
|
resolution: "universalify@npm:2.0.1"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue