summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-11-06 11:42:46 -0500
committerDax Raad <[email protected]>2025-11-06 11:42:46 -0500
commit67f3c934fec7e118de90fe845c262a4d75ce03ba (patch)
tree38161ce4d9d59f6e1f0e4cd611857fd0235c5a12
parent065f656fb00adf9287dee38ddb13928048f56d3d (diff)
downloadopencode-67f3c934fec7e118de90fe845c262a4d75ce03ba.tar.gz
opencode-67f3c934fec7e118de90fe845c262a4d75ce03ba.zip
fix tests
-rw-r--r--packages/opencode/src/permission/index.ts38
-rw-r--r--packages/opencode/test/tool/patch.test.ts25
2 files changed, 53 insertions, 10 deletions
diff --git a/packages/opencode/src/permission/index.ts b/packages/opencode/src/permission/index.ts
index eb541049d..fbcda6cf6 100644
--- a/packages/opencode/src/permission/index.ts
+++ b/packages/opencode/src/permission/index.ts
@@ -75,12 +75,23 @@ export namespace Permission {
async (state) => {
for (const pending of Object.values(state.pending)) {
for (const item of Object.values(pending)) {
- item.reject(new RejectedError(item.info.sessionID, item.info.id, item.info.callID, item.info.metadata))
+ item.reject(
+ new RejectedError(
+ item.info.sessionID,
+ item.info.id,
+ item.info.callID,
+ item.info.metadata,
+ ),
+ )
}
}
},
)
+ export function pending() {
+ return state().pending
+ }
+
export async function ask(input: {
type: Info["type"]
title: Info["title"]
@@ -139,7 +150,11 @@ export namespace Permission {
export const Response = z.enum(["once", "always", "reject"])
export type Response = z.infer<typeof Response>
- export function respond(input: { sessionID: Info["sessionID"]; permissionID: Info["id"]; response: Response }) {
+ export function respond(input: {
+ sessionID: Info["sessionID"]
+ permissionID: Info["id"]
+ response: Response
+ }) {
log.info("response", input)
const { pending, approved } = state()
const match = pending[input.sessionID]?.[input.permissionID]
@@ -151,7 +166,14 @@ export namespace Permission {
response: input.response,
})
if (input.response === "reject") {
- match.reject(new RejectedError(input.sessionID, input.permissionID, match.info.callID, match.info.metadata))
+ match.reject(
+ new RejectedError(
+ input.sessionID,
+ input.permissionID,
+ match.info.callID,
+ match.info.metadata,
+ ),
+ )
return
}
match.resolve()
@@ -166,7 +188,11 @@ export namespace Permission {
for (const item of Object.values(items)) {
const itemKeys = toKeys(item.info.pattern, item.info.type)
if (covered(itemKeys, approved[input.sessionID])) {
- respond({ sessionID: item.info.sessionID, permissionID: item.info.id, response: input.response })
+ respond({
+ sessionID: item.info.sessionID,
+ permissionID: item.info.id,
+ response: input.response,
+ })
}
}
}
@@ -179,7 +205,9 @@ export namespace Permission {
public readonly toolCallID?: string,
public readonly metadata?: Record<string, any>,
) {
- super(`The user rejected permission to use this specific tool call. You may try again with different parameters.`)
+ super(
+ `The user rejected permission to use this specific tool call. You may try again with different parameters.`,
+ )
}
}
}
diff --git a/packages/opencode/test/tool/patch.test.ts b/packages/opencode/test/tool/patch.test.ts
index 78d1fecb1..141759db1 100644
--- a/packages/opencode/test/tool/patch.test.ts
+++ b/packages/opencode/test/tool/patch.test.ts
@@ -3,6 +3,7 @@ import path from "path"
import { PatchTool } from "../../src/tool/patch"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
+import { Permission } from "../../src/permission"
import * as fs from "fs/promises"
const ctx = {
@@ -21,9 +22,7 @@ describe("tool.patch", () => {
await Instance.provide({
directory: "/tmp",
fn: async () => {
- await expect(patchTool.execute({ patchText: "" }, ctx)).rejects.toThrow(
- "patchText is required",
- )
+ expect(patchTool.execute({ patchText: "" }, ctx)).rejects.toThrow("patchText is required")
},
})
})
@@ -32,7 +31,7 @@ describe("tool.patch", () => {
await Instance.provide({
directory: "/tmp",
fn: async () => {
- await expect(patchTool.execute({ patchText: "invalid patch" }, ctx)).rejects.toThrow(
+ expect(patchTool.execute({ patchText: "invalid patch" }, ctx)).rejects.toThrow(
"Failed to parse patch",
)
},
@@ -46,13 +45,29 @@ describe("tool.patch", () => {
const emptyPatch = `*** Begin Patch
*** End Patch`
- await expect(patchTool.execute({ patchText: emptyPatch }, ctx)).rejects.toThrow(
+ expect(patchTool.execute({ patchText: emptyPatch }, ctx)).rejects.toThrow(
"No file changes found in patch",
)
},
})
})
+ test("should ask permission for files outside working directory", async () => {
+ await Instance.provide({
+ directory: "/tmp",
+ fn: async () => {
+ const maliciousPatch = `*** Begin Patch
+*** Add File: /etc/passwd
++malicious content
+*** End Patch`
+ patchTool.execute({ patchText: maliciousPatch }, ctx)
+ // TODO: this sucks
+ await new Promise((resolve) => setTimeout(resolve, 100))
+ expect(Permission.pending()[ctx.sessionID]).toBeDefined()
+ },
+ })
+ })
+
test("should handle simple add file operation", async () => {
await using fixture = await tmpdir()