shmem-opencode 0.2.22 → 0.2.24

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.
Files changed (3) hide show
  1. package/index.ts +20 -60
  2. package/package.json +4 -2
  3. package/tsconfig.json +2 -0
package/index.ts CHANGED
@@ -1,29 +1,6 @@
1
- /**
2
- * shmem-opencode — memory hooks for OpenCode.
3
- *
4
- * This plugin shells out to `shmem hook user-message` and `shmem hook response`
5
- * after each user prompt and assistant response. The hook commands read a
6
- * JSON blob from stdin with the shape:
7
- *
8
- * user-message: { "prompt": "<text>", "cwd": "<absolute path>" }
9
- * response: { "last_assistant_message": "<text>", "cwd": "<absolute path>" }
10
- *
11
- * The MCP server (`shmem-mcp`) is the primary capture path for OpenCode and
12
- * is configured via `shmem init --for opencode`. These hooks provide a
13
- * secondary capture path that works independently of MCP.
14
- *
15
- * TODO: Verify the exact import path for @opencode-ai/sdk once the plugin
16
- * API stabilises. The `define` export and event names below are based on
17
- * the OpenCode plugin RFC / v0.1 spec — adjust if the upstream API changes.
18
- */
19
-
20
- // TODO: replace with the correct package name once confirmed stable.
21
- // Candidate: "@opencode-ai/sdk" or "@opencode-ai/plugin"
22
- import { define } from "@opencode-ai/sdk"
1
+ import type { Plugin, PluginModule } from "@opencode-ai/plugin"
23
2
  import { execFileSync } from "child_process"
24
3
 
25
- // Pipe content into a shmem hook subcommand. Fire-and-forget: errors are
26
- // swallowed so a shmem outage never blocks the agent.
27
4
  function shmemHook(subcommand: string, payload: Record<string, string>): void {
28
5
  try {
29
6
  execFileSync("shmem", ["hook", subcommand], {
@@ -32,45 +9,28 @@ function shmemHook(subcommand: string, payload: Record<string, string>): void {
32
9
  stdio: ["pipe", "ignore", "ignore"],
33
10
  })
34
11
  } catch {
35
- // Swallow — hook failures must not surface to the user.
12
+ // hook failures must not surface to the user
36
13
  }
37
14
  }
38
15
 
39
- export default define({
40
- id: "shmem",
41
-
42
- // TODO: Verify the correct setup function signature for OpenCode's plugin API.
43
- // The ctx object shape below is speculative; consult @opencode-ai/sdk types.
44
- setup: async (ctx: {
45
- // TODO: replace with the actual OpenCode SDK context type.
46
- // Expected surface area based on OpenCode plugin RFC:
47
- // ctx.session.cwd — absolute path of the session working directory
48
- // ctx.on(event, fn) — subscribe to lifecycle events
49
- on: (
50
- event: string,
51
- handler: (data: Record<string, unknown>) => void | Promise<void>
52
- ) => void
53
- session?: { cwd?: string }
54
- }) => {
55
- const cwd = ctx.session?.cwd ?? ""
56
-
57
- // TODO: Verify the exact event names. OpenCode's plugin RFC uses:
58
- // "message:user" — fired when the user submits a prompt
59
- // "message:assistant" — fired when the assistant response completes
60
- // Adjust to the actual event names once confirmed.
61
- ctx.on("message:user", (data) => {
62
- const prompt = typeof data["content"] === "string" ? data["content"] : ""
63
- if (prompt.length >= 10) {
64
- shmemHook("user-message", { prompt, cwd })
65
- }
66
- })
16
+ const plugin: Plugin = async ({ directory }) => ({
17
+ "chat.message": async (_input, output) => {
18
+ const text = output.parts
19
+ .filter((p): p is Extract<typeof p, { type: "text" }> => p.type === "text")
20
+ .map((p) => p.text)
21
+ .join("")
22
+ if (text.length >= 10) {
23
+ shmemHook("user-message", { prompt: text, cwd: directory })
24
+ }
25
+ },
67
26
 
68
- ctx.on("message:assistant", (data) => {
69
- const message =
70
- typeof data["content"] === "string" ? data["content"] : ""
71
- if (message.length >= 20) {
72
- shmemHook("response", { last_assistant_message: message, cwd })
73
- }
74
- })
27
+ "experimental.text.complete": async (_input, output) => {
28
+ if (output.text.length >= 20) {
29
+ shmemHook("response", { last_assistant_message: output.text, cwd: directory })
30
+ }
75
31
  },
76
32
  })
33
+
34
+ export default {
35
+ server: plugin,
36
+ } satisfies PluginModule
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "shmem-opencode",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "description": "shmem memory hooks for OpenCode",
5
5
  "main": "index.ts",
6
6
  "scripts": {
7
7
  "typecheck": "tsc --noEmit"
8
8
  },
9
9
  "peerDependencies": {
10
- "@opencode-ai/sdk": "*"
10
+ "@opencode-ai/plugin": "*"
11
11
  },
12
12
  "devDependencies": {
13
+ "@opencode-ai/plugin": "^1.17.13",
14
+ "@types/node": "^26.1.0",
13
15
  "typescript": "^5.0.0"
14
16
  },
15
17
  "keywords": [
package/tsconfig.json CHANGED
@@ -3,6 +3,8 @@
3
3
  "target": "ES2022",
4
4
  "module": "ESNext",
5
5
  "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "types": ["node"],
6
8
  "strict": true,
7
9
  "skipLibCheck": true,
8
10
  "noEmit": true