@opencode/plugin 2.0.21 → 2.0.23

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.
@@ -140,6 +140,6 @@ export interface SessionHooks {
140
140
  readonly "experimental.ws.receive": SessionWebSocketReceive;
141
141
  readonly retry: SessionRetry;
142
142
  }
143
- export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "switchAgent" | "switchModel" | "prompt" | "generate" | "command" | "synthetic" | "interrupt" | "update" | "move" | "wait" | "context"> & {
143
+ export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "remove" | "switchAgent" | "switchModel" | "prompt" | "generate" | "command" | "compact" | "synthetic" | "interrupt" | "update" | "move" | "wait" | "context"> & {
144
144
  readonly hook: ModelHooks<SessionHooks>;
145
145
  };
@@ -22,13 +22,14 @@ export interface VcsDiffInput extends VcsScope {
22
22
  export interface VcsDefinition {
23
23
  readonly id: string;
24
24
  readonly name: string;
25
+ readonly init?: (input: VcsScope) => Effect.Effect<void, unknown>;
25
26
  readonly info: (input: VcsScope) => Effect.Effect<Vcs.Info, unknown>;
26
27
  readonly base?: (input: VcsScope) => Effect.Effect<Vcs.Base | null, unknown>;
27
28
  readonly branches: (input: VcsBranchesInput) => Effect.Effect<Vcs.BranchList, unknown>;
28
29
  readonly status: (input: VcsScope) => Effect.Effect<readonly Vcs.FileStatus[], unknown>;
29
30
  readonly diff: (input: VcsDiffInput) => Effect.Effect<readonly FileDiff.Info[], unknown>;
30
31
  }
31
- export interface VcsDomain extends VcsApi<unknown> {
32
+ export interface VcsDomain extends Omit<VcsApi<unknown>, "init"> {
32
33
  readonly transform: Transform<VcsEditor>;
33
34
  readonly reload: () => Effect.Effect<void>;
34
35
  }
@@ -370,10 +370,12 @@ export function fromPromise(plugin) {
370
370
  transform: (callback) => register(host.vcs.transform((editor) => {
371
371
  callback({
372
372
  add: (definition) => {
373
+ const init = definition.init?.bind(definition);
373
374
  const base = definition.base?.bind(definition);
374
375
  editor.add({
375
376
  id: definition.id,
376
377
  name: definition.name,
378
+ init: init ? (input) => attempt((signal) => init(input, { signal })) : undefined,
377
379
  info: (input) => attempt((signal) => definition.info(input, { signal })),
378
380
  base: base ? (input) => attempt((signal) => base(input, { signal })) : undefined,
379
381
  branches: (input) => attempt((signal) => definition.branches(input, { signal })),
@@ -419,11 +421,13 @@ export function fromPromise(plugin) {
419
421
  hook: (name, callback, options) => register(host.session.hook(name, (event) => Effect.promise(() => Promise.resolve(callback(event))), options)),
420
422
  create: adaptApiMethod(SessionEndpoints["session.create"], host.session.create),
421
423
  get: adaptApiMethod(SessionEndpoints["session.get"], host.session.get),
424
+ remove: adaptApiMethod(SessionEndpoints["session.remove"], host.session.remove),
422
425
  switchAgent: adaptApiMethod(SessionEndpoints["session.switchAgent"], host.session.switchAgent),
423
426
  switchModel: adaptApiMethod(SessionEndpoints["session.switchModel"], host.session.switchModel),
424
427
  prompt: adaptApiMethod(SessionEndpoints["session.prompt"], host.session.prompt),
425
428
  generate: adaptApiMethod(SessionEndpoints["session.generate"], host.session.generate),
426
429
  command: adaptApiMethod(SessionEndpoints["session.command"], host.session.command),
430
+ compact: adaptApiMethod(SessionEndpoints["session.compact"], host.session.compact),
427
431
  synthetic: adaptApiMethod(SessionEndpoints["session.synthetic"], host.session.synthetic),
428
432
  interrupt: adaptApiMethod(SessionEndpoints["session.interrupt"], host.session.interrupt),
429
433
  update: adaptApiMethod(SessionEndpoints["session.update"], host.session.update),
@@ -140,6 +140,6 @@ export interface SessionHooks {
140
140
  readonly "experimental.ws.receive": SessionWebSocketReceive;
141
141
  readonly retry: SessionRetry;
142
142
  }
143
- export type SessionDomain = Pick<SessionApi, "create" | "get" | "switchAgent" | "switchModel" | "prompt" | "generate" | "command" | "synthetic" | "interrupt" | "update" | "move" | "wait" | "context"> & {
143
+ export type SessionDomain = Pick<SessionApi, "create" | "get" | "remove" | "switchAgent" | "switchModel" | "prompt" | "generate" | "command" | "compact" | "synthetic" | "interrupt" | "update" | "move" | "wait" | "context"> & {
144
144
  readonly hook: ModelHooks<SessionHooks>;
145
145
  };
@@ -21,6 +21,9 @@ export interface VcsDiffInput extends VcsScope {
21
21
  export interface VcsDefinition {
22
22
  readonly id: string;
23
23
  readonly name: string;
24
+ readonly init?: (input: VcsScope, context: {
25
+ readonly signal: AbortSignal;
26
+ }) => Promise<void>;
24
27
  readonly info: (input: VcsScope, context: {
25
28
  readonly signal: AbortSignal;
26
29
  }) => Promise<Vcs.Info>;
@@ -37,7 +40,7 @@ export interface VcsDefinition {
37
40
  readonly signal: AbortSignal;
38
41
  }) => Promise<readonly FileDiff.Info[]>;
39
42
  }
40
- export interface VcsDomain extends VcsApi {
43
+ export interface VcsDomain extends Omit<VcsApi, "init"> {
41
44
  readonly transform: Transform<VcsEditor>;
42
45
  readonly reload: () => Promise<void>;
43
46
  }
@@ -302,11 +302,27 @@ export interface DialogSelectOption<Value> {
302
302
  readonly category?: string;
303
303
  readonly disabled?: boolean;
304
304
  }
305
+ export type DialogSelectAction<Value> = {
306
+ readonly bind: string;
307
+ readonly title: string;
308
+ readonly side?: "left" | "right";
309
+ } & ({
310
+ /** Unavailable while no option is selected. */
311
+ readonly selection?: "required";
312
+ readonly onTrigger: (value: Value) => void;
313
+ } | {
314
+ readonly selection: "none";
315
+ readonly onTrigger: () => void;
316
+ });
305
317
  export interface DialogSelectOptions<Value> {
306
318
  readonly title: string;
307
319
  readonly placeholder?: string;
308
320
  readonly options: readonly DialogSelectOption<Value>[];
309
321
  readonly current?: Value;
322
+ /** Returns matching options in display order, including for an empty query. Receives only enabled options. Results are listed flat. */
323
+ readonly search?: (query: string, options: readonly DialogSelectOption<Value>[]) => readonly DialogSelectOption<Value>[];
324
+ /** Footer actions, also triggered by their bindings. Triggering one does not close the dialog. */
325
+ readonly actions?: readonly DialogSelectAction<Value>[];
310
326
  }
311
327
  export interface Dialog {
312
328
  /** Shows a dialog. */
@@ -373,8 +389,13 @@ export interface KeymapActive {
373
389
  readonly continues: boolean;
374
390
  }
375
391
  export interface Keymap {
376
- /** Creates a reactive keymap layer owned by the calling component. */
377
- layer(input: () => KeymapLayer): void;
392
+ /**
393
+ * Creates a reactive keymap layer. It is removed when the plugin deactivates, or earlier when the component or reactive
394
+ * computation that created it is disposed. The factory must be pure. It runs once untracked for initial command-shape
395
+ * validation, then reactively. Initial command-shape errors throw synchronously. OpenTUI handles binding-parse errors.
396
+ * Errors from later reactive updates follow Solid's error handling.
397
+ */
398
+ layer(factory: () => KeymapLayer): void;
378
399
  /** Dispatches a reachable command by ID. */
379
400
  dispatch(id: string, input?: string): void;
380
401
  /** Returns every formatted shortcut for a registered command. */
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.21",
4
+ "version": "2.0.23",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -43,17 +43,17 @@
43
43
  ],
44
44
  "dependencies": {
45
45
  "@ai-sdk/provider": "3.0.8",
46
- "@opencode/ai": "2.0.21",
47
- "@opencode/client": "2.0.21",
48
- "@opencode/protocol": "2.0.21",
49
- "@opencode/schema": "2.0.21",
50
- "@opencode/util": "2.0.21",
46
+ "@opencode/ai": "2.0.23",
47
+ "@opencode/client": "2.0.23",
48
+ "@opencode/protocol": "2.0.23",
49
+ "@opencode/schema": "2.0.23",
50
+ "@opencode/util": "2.0.23",
51
51
  "@standard-schema/spec": "1.1.0",
52
52
  "effect": "4.0.0-rc.112",
53
53
  "zod": "4.1.8"
54
54
  },
55
55
  "peerDependencies": {
56
- "@opencode/theme": "2.0.21",
56
+ "@opencode/theme": "2.0.23",
57
57
  "@opentui/core": ">=0.5.14",
58
58
  "@opentui/solid": ">=0.5.14",
59
59
  "solid-js": ">=1.9.0"
@@ -73,7 +73,7 @@
73
73
  }
74
74
  },
75
75
  "devDependencies": {
76
- "@opencode/theme": "2.0.21",
76
+ "@opencode/theme": "2.0.23",
77
77
  "@opentui/core": "0.5.14",
78
78
  "@opentui/solid": "0.5.14",
79
79
  "@tsconfig/bun": "1.0.9",