refactor(tool): yield InstanceState context (#25199)
This commit is contained in:
@@ -256,7 +256,8 @@ export const layer = Layer.effect(
|
|||||||
|
|
||||||
const assistantMessage = input.messages.findLast((msg) => msg.info.role === "assistant")
|
const assistantMessage = input.messages.findLast((msg) => msg.info.role === "assistant")
|
||||||
if (input.agent.name !== "plan" && assistantMessage?.info.agent === "plan") {
|
if (input.agent.name !== "plan" && assistantMessage?.info.agent === "plan") {
|
||||||
const plan = Session.plan(input.session)
|
const ctx = yield* InstanceState.context
|
||||||
|
const plan = Session.plan(input.session, ctx)
|
||||||
if (!(yield* fsys.existsSafe(plan))) return input.messages
|
if (!(yield* fsys.existsSafe(plan))) return input.messages
|
||||||
const part = yield* sessions.updatePart({
|
const part = yield* sessions.updatePart({
|
||||||
id: PartID.ascending(),
|
id: PartID.ascending(),
|
||||||
@@ -272,7 +273,8 @@ export const layer = Layer.effect(
|
|||||||
|
|
||||||
if (input.agent.name !== "plan" || assistantMessage?.info.agent === "plan") return input.messages
|
if (input.agent.name !== "plan" || assistantMessage?.info.agent === "plan") return input.messages
|
||||||
|
|
||||||
const plan = Session.plan(input.session)
|
const ctx = yield* InstanceState.context
|
||||||
|
const plan = Session.plan(input.session, ctx)
|
||||||
const exists = yield* fsys.existsSafe(plan)
|
const exists = yield* fsys.existsSafe(plan)
|
||||||
if (!exists) yield* fsys.ensureDir(path.dirname(plan)).pipe(Effect.catch(Effect.die))
|
if (!exists) yield* fsys.ensureDir(path.dirname(plan)).pipe(Effect.catch(Effect.die))
|
||||||
const part = yield* sessions.updatePart({
|
const part = yield* sessions.updatePart({
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import { ProjectTable } from "../project/project.sql"
|
|||||||
import { Storage } from "@/storage/storage"
|
import { Storage } from "@/storage/storage"
|
||||||
import * as Log from "@opencode-ai/core/util/log"
|
import * as Log from "@opencode-ai/core/util/log"
|
||||||
import { MessageV2 } from "./message-v2"
|
import { MessageV2 } from "./message-v2"
|
||||||
import { Instance } from "../project/instance"
|
import { Instance, type InstanceContext } from "../project/instance"
|
||||||
import { InstanceState } from "@/effect/instance-state"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { Snapshot } from "@/snapshot"
|
import { Snapshot } from "@/snapshot"
|
||||||
import { ProjectID } from "../project/schema"
|
import { ProjectID } from "../project/schema"
|
||||||
@@ -311,9 +311,9 @@ export const Event = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
export function plan(input: { slug: string; time: { created: number } }) {
|
export function plan(input: { slug: string; time: { created: number } }, instance: InstanceContext) {
|
||||||
const base = Instance.project.vcs
|
const base = instance.project.vcs
|
||||||
? path.join(Instance.worktree, ".opencode", "plans")
|
? path.join(instance.worktree, ".opencode", "plans")
|
||||||
: path.join(Global.Path.data, "plans")
|
: path.join(Global.Path.data, "plans")
|
||||||
return path.join(base, [input.time.created, input.slug].join("-") + ".md")
|
return path.join(base, [input.time.created, input.slug].join("-") + ".md")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Effect, Schema } from "effect"
|
|||||||
import * as Tool from "./tool"
|
import * as Tool from "./tool"
|
||||||
import { Bus } from "../bus"
|
import { Bus } from "../bus"
|
||||||
import { FileWatcher } from "../file/watcher"
|
import { FileWatcher } from "../file/watcher"
|
||||||
import { Instance } from "../project/instance"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { Patch } from "../patch"
|
import { Patch } from "../patch"
|
||||||
import { createTwoFilesPatch, diffLines } from "diff"
|
import { createTwoFilesPatch, diffLines } from "diff"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
@@ -52,6 +52,8 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
return yield* Effect.fail(new Error("apply_patch verification failed: no hunks found"))
|
return yield* Effect.fail(new Error("apply_patch verification failed: no hunks found"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const instance = yield* InstanceState.context
|
||||||
|
|
||||||
// Validate file paths and check permissions
|
// Validate file paths and check permissions
|
||||||
const fileChanges: Array<{
|
const fileChanges: Array<{
|
||||||
filePath: string
|
filePath: string
|
||||||
@@ -68,7 +70,7 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
let totalDiff = ""
|
let totalDiff = ""
|
||||||
|
|
||||||
for (const hunk of hunks) {
|
for (const hunk of hunks) {
|
||||||
const filePath = path.resolve(Instance.directory, hunk.path)
|
const filePath = path.resolve(instance.directory, hunk.path)
|
||||||
yield* assertExternalDirectoryEffect(ctx, filePath)
|
yield* assertExternalDirectoryEffect(ctx, filePath)
|
||||||
|
|
||||||
switch (hunk.type) {
|
switch (hunk.type) {
|
||||||
@@ -133,7 +135,7 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
if (change.removed) deletions += change.count || 0
|
if (change.removed) deletions += change.count || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const movePath = hunk.move_path ? path.resolve(Instance.directory, hunk.move_path) : undefined
|
const movePath = hunk.move_path ? path.resolve(instance.directory, hunk.move_path) : undefined
|
||||||
yield* assertExternalDirectoryEffect(ctx, movePath)
|
yield* assertExternalDirectoryEffect(ctx, movePath)
|
||||||
|
|
||||||
fileChanges.push({
|
fileChanges.push({
|
||||||
@@ -187,7 +189,7 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
// Build per-file metadata for UI rendering (used for both permission and result)
|
// Build per-file metadata for UI rendering (used for both permission and result)
|
||||||
const files = fileChanges.map((change) => ({
|
const files = fileChanges.map((change) => ({
|
||||||
filePath: change.filePath,
|
filePath: change.filePath,
|
||||||
relativePath: path.relative(Instance.worktree, change.movePath ?? change.filePath).replaceAll("\\", "/"),
|
relativePath: path.relative(instance.worktree, change.movePath ?? change.filePath).replaceAll("\\", "/"),
|
||||||
type: change.type,
|
type: change.type,
|
||||||
patch: change.diff,
|
patch: change.diff,
|
||||||
additions: change.additions,
|
additions: change.additions,
|
||||||
@@ -196,7 +198,7 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// Check permissions if needed
|
// Check permissions if needed
|
||||||
const relativePaths = fileChanges.map((c) => path.relative(Instance.worktree, c.filePath).replaceAll("\\", "/"))
|
const relativePaths = fileChanges.map((c) => path.relative(instance.worktree, c.filePath).replaceAll("\\", "/"))
|
||||||
yield* ctx.ask({
|
yield* ctx.ask({
|
||||||
permission: "edit",
|
permission: "edit",
|
||||||
patterns: relativePaths,
|
patterns: relativePaths,
|
||||||
@@ -267,13 +269,13 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
// Generate output summary
|
// Generate output summary
|
||||||
const summaryLines = fileChanges.map((change) => {
|
const summaryLines = fileChanges.map((change) => {
|
||||||
if (change.type === "add") {
|
if (change.type === "add") {
|
||||||
return `A ${path.relative(Instance.worktree, change.filePath).replaceAll("\\", "/")}`
|
return `A ${path.relative(instance.worktree, change.filePath).replaceAll("\\", "/")}`
|
||||||
}
|
}
|
||||||
if (change.type === "delete") {
|
if (change.type === "delete") {
|
||||||
return `D ${path.relative(Instance.worktree, change.filePath).replaceAll("\\", "/")}`
|
return `D ${path.relative(instance.worktree, change.filePath).replaceAll("\\", "/")}`
|
||||||
}
|
}
|
||||||
const target = change.movePath ?? change.filePath
|
const target = change.movePath ?? change.filePath
|
||||||
return `M ${path.relative(Instance.worktree, target).replaceAll("\\", "/")}`
|
return `M ${path.relative(instance.worktree, target).replaceAll("\\", "/")}`
|
||||||
})
|
})
|
||||||
let output = `Success. Updated the following files:\n${summaryLines.join("\n")}`
|
let output = `Success. Updated the following files:\n${summaryLines.join("\n")}`
|
||||||
|
|
||||||
@@ -282,7 +284,7 @@ export const ApplyPatchTool = Tool.define(
|
|||||||
const target = change.movePath ?? change.filePath
|
const target = change.movePath ?? change.filePath
|
||||||
const block = LSP.Diagnostic.report(target, diagnostics[AppFileSystem.normalizePath(target)] ?? [])
|
const block = LSP.Diagnostic.report(target, diagnostics[AppFileSystem.normalizePath(target)] ?? [])
|
||||||
if (!block) continue
|
if (!block) continue
|
||||||
const rel = path.relative(Instance.worktree, target).replaceAll("\\", "/")
|
const rel = path.relative(instance.worktree, target).replaceAll("\\", "/")
|
||||||
output += `\n\nLSP errors detected in ${rel}, please fix:\n${block}`
|
output += `\n\nLSP errors detected in ${rel}, please fix:\n${block}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import * as Tool from "./tool"
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import DESCRIPTION from "./bash.txt"
|
import DESCRIPTION from "./bash.txt"
|
||||||
import * as Log from "@opencode-ai/core/util/log"
|
import * as Log from "@opencode-ai/core/util/log"
|
||||||
import { Instance } from "../project/instance"
|
import { Instance, type InstanceContext } from "../project/instance"
|
||||||
import { lazy } from "@/util/lazy"
|
import { lazy } from "@/util/lazy"
|
||||||
import { Language, type Node } from "web-tree-sitter"
|
import { Language, type Node } from "web-tree-sitter"
|
||||||
|
|
||||||
@@ -363,7 +363,13 @@ export const BashTool = Tool.define(
|
|||||||
return yield* resolvePath(next, cwd, shell)
|
return yield* resolvePath(next, cwd, shell)
|
||||||
})
|
})
|
||||||
|
|
||||||
const collect = Effect.fn("BashTool.collect")(function* (root: Node, cwd: string, ps: boolean, shell: string) {
|
const collect = Effect.fn("BashTool.collect")(function* (
|
||||||
|
root: Node,
|
||||||
|
cwd: string,
|
||||||
|
ps: boolean,
|
||||||
|
shell: string,
|
||||||
|
instance: InstanceContext,
|
||||||
|
) {
|
||||||
const scan: Scan = {
|
const scan: Scan = {
|
||||||
dirs: new Set<string>(),
|
dirs: new Set<string>(),
|
||||||
patterns: new Set<string>(),
|
patterns: new Set<string>(),
|
||||||
@@ -379,7 +385,7 @@ export const BashTool = Tool.define(
|
|||||||
for (const arg of pathArgs(command, ps)) {
|
for (const arg of pathArgs(command, ps)) {
|
||||||
const resolved = yield* argPath(arg, cwd, ps, shell)
|
const resolved = yield* argPath(arg, cwd, ps, shell)
|
||||||
log.info("resolved path", { arg, resolved })
|
log.info("resolved path", { arg, resolved })
|
||||||
if (!resolved || Instance.containsPath(resolved)) continue
|
if (!resolved || Instance.containsPath(resolved, instance)) continue
|
||||||
const dir = (yield* fs.isDir(resolved)) ? resolved : path.dirname(resolved)
|
const dir = (yield* fs.isDir(resolved)) ? resolved : path.dirname(resolved)
|
||||||
scan.dirs.add(dir)
|
scan.dirs.add(dir)
|
||||||
}
|
}
|
||||||
@@ -589,9 +595,10 @@ export const BashTool = Tool.define(
|
|||||||
parameters: Parameters,
|
parameters: Parameters,
|
||||||
execute: (params: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context) =>
|
execute: (params: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
const executeInstance = yield* InstanceState.context
|
||||||
const cwd = params.workdir
|
const cwd = params.workdir
|
||||||
? yield* resolvePath(params.workdir, Instance.directory, shell)
|
? yield* resolvePath(params.workdir, executeInstance.directory, shell)
|
||||||
: Instance.directory
|
: executeInstance.directory
|
||||||
if (params.timeout !== undefined && params.timeout < 0) {
|
if (params.timeout !== undefined && params.timeout < 0) {
|
||||||
throw new Error(`Invalid timeout value: ${params.timeout}. Timeout must be a positive number.`)
|
throw new Error(`Invalid timeout value: ${params.timeout}. Timeout must be a positive number.`)
|
||||||
}
|
}
|
||||||
@@ -602,8 +609,8 @@ export const BashTool = Tool.define(
|
|||||||
const tree = yield* Effect.acquireRelease(parse(params.command, ps), (tree) =>
|
const tree = yield* Effect.acquireRelease(parse(params.command, ps), (tree) =>
|
||||||
Effect.sync(() => tree.delete()),
|
Effect.sync(() => tree.delete()),
|
||||||
)
|
)
|
||||||
const scan = yield* collect(tree.rootNode, cwd, ps, shell)
|
const scan = yield* collect(tree.rootNode, cwd, ps, shell, executeInstance)
|
||||||
if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
|
if (!Instance.containsPath(cwd, executeInstance)) scan.dirs.add(cwd)
|
||||||
yield* ask(ctx, scan)
|
yield* ask(ctx, scan)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { File } from "../file"
|
|||||||
import { FileWatcher } from "../file/watcher"
|
import { FileWatcher } from "../file/watcher"
|
||||||
import { Bus } from "../bus"
|
import { Bus } from "../bus"
|
||||||
import { Format } from "../format"
|
import { Format } from "../format"
|
||||||
import { Instance } from "../project/instance"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { Snapshot } from "@/snapshot"
|
import { Snapshot } from "@/snapshot"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||||
@@ -76,9 +76,10 @@ export const EditTool = Tool.define(
|
|||||||
throw new Error("No changes to apply: oldString and newString are identical.")
|
throw new Error("No changes to apply: oldString and newString are identical.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const instance = yield* InstanceState.context
|
||||||
const filePath = path.isAbsolute(params.filePath)
|
const filePath = path.isAbsolute(params.filePath)
|
||||||
? params.filePath
|
? params.filePath
|
||||||
: path.join(Instance.directory, params.filePath)
|
: path.join(instance.directory, params.filePath)
|
||||||
yield* assertExternalDirectoryEffect(ctx, filePath)
|
yield* assertExternalDirectoryEffect(ctx, filePath)
|
||||||
|
|
||||||
let diff = ""
|
let diff = ""
|
||||||
@@ -96,7 +97,7 @@ export const EditTool = Tool.define(
|
|||||||
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
|
diff = trimDiff(createTwoFilesPatch(filePath, filePath, contentOld, contentNew))
|
||||||
yield* ctx.ask({
|
yield* ctx.ask({
|
||||||
permission: "edit",
|
permission: "edit",
|
||||||
patterns: [path.relative(Instance.worktree, filePath)],
|
patterns: [path.relative(instance.worktree, filePath)],
|
||||||
always: ["*"],
|
always: ["*"],
|
||||||
metadata: {
|
metadata: {
|
||||||
filepath: filePath,
|
filepath: filePath,
|
||||||
@@ -139,7 +140,7 @@ export const EditTool = Tool.define(
|
|||||||
)
|
)
|
||||||
yield* ctx.ask({
|
yield* ctx.ask({
|
||||||
permission: "edit",
|
permission: "edit",
|
||||||
patterns: [path.relative(Instance.worktree, filePath)],
|
patterns: [path.relative(instance.worktree, filePath)],
|
||||||
always: ["*"],
|
always: ["*"],
|
||||||
metadata: {
|
metadata: {
|
||||||
filepath: filePath,
|
filepath: filePath,
|
||||||
@@ -201,7 +202,7 @@ export const EditTool = Tool.define(
|
|||||||
diff,
|
diff,
|
||||||
filediff,
|
filediff,
|
||||||
},
|
},
|
||||||
title: `${path.relative(Instance.worktree, filePath)}`,
|
title: `${path.relative(instance.worktree, filePath)}`,
|
||||||
output,
|
output,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as Tool from "./tool"
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import { LSP } from "@/lsp/lsp"
|
import { LSP } from "@/lsp/lsp"
|
||||||
import DESCRIPTION from "./lsp.txt"
|
import DESCRIPTION from "./lsp.txt"
|
||||||
import { Instance } from "../project/instance"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { pathToFileURL } from "url"
|
import { pathToFileURL } from "url"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||||
@@ -44,7 +44,8 @@ export const LspTool = Tool.define(
|
|||||||
parameters: Parameters,
|
parameters: Parameters,
|
||||||
execute: (args: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context) =>
|
execute: (args: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const file = path.isAbsolute(args.filePath) ? args.filePath : path.join(Instance.directory, args.filePath)
|
const instance = yield* InstanceState.context
|
||||||
|
const file = path.isAbsolute(args.filePath) ? args.filePath : path.join(instance.directory, args.filePath)
|
||||||
yield* assertExternalDirectoryEffect(ctx, file)
|
yield* assertExternalDirectoryEffect(ctx, file)
|
||||||
const meta =
|
const meta =
|
||||||
args.operation === "workspaceSymbol"
|
args.operation === "workspaceSymbol"
|
||||||
@@ -61,7 +62,7 @@ export const LspTool = Tool.define(
|
|||||||
|
|
||||||
const uri = pathToFileURL(file).href
|
const uri = pathToFileURL(file).href
|
||||||
const position = { file, line: args.line - 1, character: args.character - 1 }
|
const position = { file, line: args.line - 1, character: args.character - 1 }
|
||||||
const relPath = path.relative(Instance.worktree, file)
|
const relPath = path.relative(instance.worktree, file)
|
||||||
const detail =
|
const detail =
|
||||||
args.operation === "workspaceSymbol"
|
args.operation === "workspaceSymbol"
|
||||||
? ""
|
? ""
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Question } from "../question"
|
|||||||
import { Session } from "@/session/session"
|
import { Session } from "@/session/session"
|
||||||
import { MessageV2 } from "../session/message-v2"
|
import { MessageV2 } from "../session/message-v2"
|
||||||
import { Provider } from "@/provider/provider"
|
import { Provider } from "@/provider/provider"
|
||||||
import { Instance } from "../project/instance"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { type SessionID, MessageID, PartID } from "../session/schema"
|
import { type SessionID, MessageID, PartID } from "../session/schema"
|
||||||
import EXIT_DESCRIPTION from "./plan-exit.txt"
|
import EXIT_DESCRIPTION from "./plan-exit.txt"
|
||||||
|
|
||||||
@@ -30,8 +30,9 @@ export const PlanExitTool = Tool.define(
|
|||||||
parameters: Parameters,
|
parameters: Parameters,
|
||||||
execute: (_params: {}, ctx: Tool.Context) =>
|
execute: (_params: {}, ctx: Tool.Context) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
const instance = yield* InstanceState.context
|
||||||
const info = yield* session.get(ctx.sessionID)
|
const info = yield* session.get(ctx.sessionID)
|
||||||
const plan = path.relative(Instance.worktree, Session.plan(info))
|
const plan = path.relative(instance.worktree, Session.plan(info, instance))
|
||||||
const answers = yield* question.ask({
|
const answers = yield* question.ask({
|
||||||
sessionID: ctx.sessionID,
|
sessionID: ctx.sessionID,
|
||||||
questions: [
|
questions: [
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { File } from "../file"
|
|||||||
import { FileWatcher } from "../file/watcher"
|
import { FileWatcher } from "../file/watcher"
|
||||||
import { Format } from "../format"
|
import { Format } from "../format"
|
||||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||||
import { Instance } from "../project/instance"
|
import { InstanceState } from "@/effect/instance-state"
|
||||||
import { trimDiff } from "./edit"
|
import { trimDiff } from "./edit"
|
||||||
import { assertExternalDirectoryEffect } from "./external-directory"
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
||||||
import * as Bom from "@/util/bom"
|
import * as Bom from "@/util/bom"
|
||||||
@@ -37,9 +37,10 @@ export const WriteTool = Tool.define(
|
|||||||
parameters: Parameters,
|
parameters: Parameters,
|
||||||
execute: (params: { content: string; filePath: string }, ctx: Tool.Context) =>
|
execute: (params: { content: string; filePath: string }, ctx: Tool.Context) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
const instance = yield* InstanceState.context
|
||||||
const filepath = path.isAbsolute(params.filePath)
|
const filepath = path.isAbsolute(params.filePath)
|
||||||
? params.filePath
|
? params.filePath
|
||||||
: path.join(Instance.directory, params.filePath)
|
: path.join(instance.directory, params.filePath)
|
||||||
yield* assertExternalDirectoryEffect(ctx, filepath)
|
yield* assertExternalDirectoryEffect(ctx, filepath)
|
||||||
|
|
||||||
const exists = yield* fs.existsSafe(filepath)
|
const exists = yield* fs.existsSafe(filepath)
|
||||||
@@ -52,7 +53,7 @@ export const WriteTool = Tool.define(
|
|||||||
const diff = trimDiff(createTwoFilesPatch(filepath, filepath, contentOld, contentNew))
|
const diff = trimDiff(createTwoFilesPatch(filepath, filepath, contentOld, contentNew))
|
||||||
yield* ctx.ask({
|
yield* ctx.ask({
|
||||||
permission: "edit",
|
permission: "edit",
|
||||||
patterns: [path.relative(Instance.worktree, filepath)],
|
patterns: [path.relative(instance.worktree, filepath)],
|
||||||
always: ["*"],
|
always: ["*"],
|
||||||
metadata: {
|
metadata: {
|
||||||
filepath,
|
filepath,
|
||||||
@@ -89,7 +90,7 @@ export const WriteTool = Tool.define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: path.relative(Instance.worktree, filepath),
|
title: path.relative(instance.worktree, filepath),
|
||||||
metadata: {
|
metadata: {
|
||||||
diagnostics,
|
diagnostics,
|
||||||
filepath,
|
filepath,
|
||||||
|
|||||||
Reference in New Issue
Block a user