@opencode/plugin 2.0.28 → 2.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effect/permission.d.ts +9 -0
- package/dist/permission.d.ts +23 -0
- package/dist/permission.js +12 -0
- package/dist/promise/adapter.js +13 -7
- package/dist/promise/permission.d.ts +8 -0
- package/package.json +8 -8
|
@@ -2,6 +2,9 @@ import type { PermissionApi } from "@opencode/client/effect/api";
|
|
|
2
2
|
import type { Agent } from "@opencode/schema/agent";
|
|
3
3
|
import type { Permission } from "@opencode/schema/permission";
|
|
4
4
|
import type { Session } from "@opencode/schema/session";
|
|
5
|
+
import type { Tool } from "@opencode/schema/tool";
|
|
6
|
+
import type { Effect } from "effect";
|
|
7
|
+
import type { AssertInput } from "../permission.js";
|
|
5
8
|
import type { Hooks } from "./registration.js";
|
|
6
9
|
export interface PermissionEvaluation {
|
|
7
10
|
readonly sessionID: Session.ID;
|
|
@@ -18,4 +21,10 @@ export interface PermissionHooks {
|
|
|
18
21
|
}
|
|
19
22
|
export type PermissionDomain = Pick<PermissionApi<unknown>, "list" | "get" | "reply"> & {
|
|
20
23
|
readonly hook: Hooks<PermissionHooks>;
|
|
24
|
+
/**
|
|
25
|
+
* Evaluates the session's permission rules and, when approval is required, prompts the user and
|
|
26
|
+
* waits for the reply. Succeeds when allowed. A deny rule or a rejection with feedback fails with a
|
|
27
|
+
* `Tool.Error` carrying the reason; a plain rejection ends the current step.
|
|
28
|
+
*/
|
|
29
|
+
readonly assert: (input: AssertInput) => Effect.Effect<void, Tool.Error>;
|
|
21
30
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
export declare const AssertInput: Schema.Struct<{
|
|
3
|
+
readonly sessionID: Schema.brand<Schema.String, "SessionID"> & {
|
|
4
|
+
create: () => string & import("effect/Brand").Brand<"SessionID">;
|
|
5
|
+
descending: (id?: string) => string & import("effect/Brand").Brand<"SessionID">;
|
|
6
|
+
};
|
|
7
|
+
readonly agent: Schema.optional<Schema.brand<Schema.String, "Agent.ID">>;
|
|
8
|
+
readonly action: Schema.String;
|
|
9
|
+
readonly resources: Schema.$Array<Schema.String>;
|
|
10
|
+
readonly save: Schema.decodeTo<Schema.optional<Schema.toType<Schema.$Array<Schema.String>>>, Schema.optionalKey<Schema.$Array<Schema.String>>, never, never>;
|
|
11
|
+
readonly metadata: Schema.decodeTo<Schema.optional<Schema.toType<Schema.$Record<Schema.String, Schema.Unknown>>>, Schema.optionalKey<Schema.$Record<Schema.String, Schema.Unknown>>, never, never>;
|
|
12
|
+
readonly source: Schema.decodeTo<Schema.optional<Schema.toType<Schema.Union<readonly [Schema.Struct<{
|
|
13
|
+
readonly type: Schema.Literal<"tool">;
|
|
14
|
+
readonly messageID: Schema.String;
|
|
15
|
+
readonly id: Schema.String;
|
|
16
|
+
}>]>>>, Schema.optionalKey<Schema.Union<readonly [Schema.Struct<{
|
|
17
|
+
readonly type: Schema.Literal<"tool">;
|
|
18
|
+
readonly messageID: Schema.String;
|
|
19
|
+
readonly id: Schema.String;
|
|
20
|
+
}>]>>, never, never>;
|
|
21
|
+
}>;
|
|
22
|
+
export interface AssertInput extends Schema.Schema.Type<typeof AssertInput> {
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Agent } from "@opencode/schema/agent";
|
|
2
|
+
import { Permission } from "@opencode/schema/permission";
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
export const AssertInput = Schema.Struct({
|
|
5
|
+
sessionID: Permission.Request.fields.sessionID,
|
|
6
|
+
agent: Agent.ID.pipe(Schema.optional),
|
|
7
|
+
action: Permission.Request.fields.action,
|
|
8
|
+
resources: Permission.Request.fields.resources,
|
|
9
|
+
save: Permission.Request.fields.save,
|
|
10
|
+
metadata: Permission.Request.fields.metadata,
|
|
11
|
+
source: Permission.Request.fields.source,
|
|
12
|
+
});
|
package/dist/promise/adapter.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Tool } from "@opencode/schema/tool";
|
|
|
2
2
|
import { Effect, Schema, SchemaAST, Stream } from "effect";
|
|
3
3
|
import { HttpApiEndpoint, HttpApiSchema } from "effect/http-api";
|
|
4
4
|
import { define } from "../effect/plugin.js";
|
|
5
|
+
import { AssertInput } from "../permission.js";
|
|
5
6
|
const compiledEndpoints = new WeakMap();
|
|
6
7
|
const JsonInput = Schema.fromJsonString(Schema.Unknown);
|
|
7
8
|
class ReturnedRpcError extends Error {
|
|
@@ -312,6 +313,7 @@ export function fromPromise(plugin) {
|
|
|
312
313
|
list: adaptApiMethod(PermissionEndpoints["session.permission.list"], host.permission.list),
|
|
313
314
|
get: adaptApiMethod(PermissionEndpoints["session.permission.get"], host.permission.get),
|
|
314
315
|
reply: adaptApiMethod(PermissionEndpoints["session.permission.reply"], host.permission.reply),
|
|
316
|
+
assert: (input) => run(Schema.decodeUnknownEffect(AssertInput)(input).pipe(Effect.flatMap(host.permission.assert))),
|
|
315
317
|
},
|
|
316
318
|
plugin: {
|
|
317
319
|
list: adaptApiMethod(PluginEndpoints["plugin.list"], host.plugin.list),
|
|
@@ -361,7 +363,7 @@ export function fromPromise(plugin) {
|
|
|
361
363
|
}),
|
|
362
364
|
remove: editor.remove,
|
|
363
365
|
}))),
|
|
364
|
-
hook: (name, callback) => register(host.tool.hook(name, (event) =>
|
|
366
|
+
hook: (name, callback) => register(host.tool.hook(name, (event) => toolHook[name](() => Promise.resolve(callback(event))))),
|
|
365
367
|
},
|
|
366
368
|
vcs: {
|
|
367
369
|
get: adaptApiMethod(VcsEndpoints["vcs.get"], host.vcs.get),
|
|
@@ -451,15 +453,19 @@ export function fromPromise(plugin) {
|
|
|
451
453
|
function attempt(evaluate) {
|
|
452
454
|
return Effect.tryPromise({ try: evaluate, catch: (cause) => cause });
|
|
453
455
|
}
|
|
456
|
+
const toolError = (error) => error instanceof Tool.Error
|
|
457
|
+
? error
|
|
458
|
+
: new Tool.Error({ message: error instanceof Error ? error.message : String(error), error });
|
|
459
|
+
// Only execute.before may reject a call; a rejection fails that call alone, like an Effect hook.
|
|
460
|
+
const toolHook = {
|
|
461
|
+
"execute.before": (run) => Effect.tryPromise({ try: run, catch: toolError }),
|
|
462
|
+
"execute.after": (run) => Effect.promise(run),
|
|
463
|
+
};
|
|
454
464
|
const executePromiseTool = (tool, input, context) => Effect.tryPromise({
|
|
455
465
|
try: (signal) => tool.execute(input, {
|
|
456
466
|
...context,
|
|
457
467
|
signal,
|
|
458
468
|
progress: (update) => Effect.runPromise(context.progress(update), { signal }),
|
|
459
469
|
}),
|
|
460
|
-
catch:
|
|
461
|
-
})
|
|
462
|
-
if (error instanceof Tool.Error)
|
|
463
|
-
return Effect.fail(error);
|
|
464
|
-
return Effect.fail(new Tool.Error({ message: error instanceof Error ? error.message : String(error), error }));
|
|
465
|
-
}));
|
|
470
|
+
catch: toolError,
|
|
471
|
+
});
|
|
@@ -2,6 +2,7 @@ import type { PermissionApi } from "@opencode/client/promise/api";
|
|
|
2
2
|
import type { Agent } from "@opencode/schema/agent";
|
|
3
3
|
import type { Permission } from "@opencode/schema/permission";
|
|
4
4
|
import type { Session } from "@opencode/schema/session";
|
|
5
|
+
import type { AssertInput } from "../permission.js";
|
|
5
6
|
import type { Hooks } from "./registration.js";
|
|
6
7
|
export interface PermissionEvaluation {
|
|
7
8
|
readonly sessionID: Session.ID;
|
|
@@ -18,4 +19,11 @@ export interface PermissionHooks {
|
|
|
18
19
|
}
|
|
19
20
|
export type PermissionDomain = Pick<PermissionApi, "list" | "get" | "reply"> & {
|
|
20
21
|
readonly hook: Hooks<PermissionHooks>;
|
|
22
|
+
/**
|
|
23
|
+
* Evaluates the session's permission rules and, when approval is required, prompts the user and
|
|
24
|
+
* waits for the reply. Resolves when allowed. A deny rule or a rejection with feedback rejects with
|
|
25
|
+
* a `Tool.Error` carrying the reason. A plain rejection rejects with an error that ends the current
|
|
26
|
+
* step; rethrow it rather than returning it as tool output.
|
|
27
|
+
*/
|
|
28
|
+
readonly assert: (input: typeof AssertInput.Encoded) => Promise<void>;
|
|
21
29
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/plugin",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.29",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@ai-sdk/provider": "3.0.8",
|
|
50
|
-
"@opencode/ai": "2.0.
|
|
51
|
-
"@opencode/client": "2.0.
|
|
52
|
-
"@opencode/protocol": "2.0.
|
|
53
|
-
"@opencode/schema": "2.0.
|
|
54
|
-
"@opencode/util": "2.0.
|
|
50
|
+
"@opencode/ai": "2.0.29",
|
|
51
|
+
"@opencode/client": "2.0.29",
|
|
52
|
+
"@opencode/protocol": "2.0.29",
|
|
53
|
+
"@opencode/schema": "2.0.29",
|
|
54
|
+
"@opencode/util": "2.0.29",
|
|
55
55
|
"effect": "4.0.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@opencode/theme": "2.0.
|
|
58
|
+
"@opencode/theme": "2.0.29",
|
|
59
59
|
"@opentui/core": ">=0.5.17",
|
|
60
60
|
"@opentui/solid": ">=0.5.17",
|
|
61
61
|
"solid-js": ">=1.9.0"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
}
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@opencode/theme": "2.0.
|
|
78
|
+
"@opencode/theme": "2.0.29",
|
|
79
79
|
"@opentui/core": "0.5.17",
|
|
80
80
|
"@opentui/solid": "0.5.17",
|
|
81
81
|
"@tsconfig/bun": "1.0.9",
|