suemo 0.1.8 → 0.1.9

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/README.md CHANGED
@@ -544,7 +544,7 @@ These scenarios intentionally exercise all memory kinds and all relation kinds,
544
544
  - **Runtime** — [Bun](https://bun.sh)
545
545
  - **Language** — TypeScript (strict, `exactOptionalPropertyTypes`)
546
546
  - **Database** — [SurrealDB](https://surrealdb.com) v3.0+ (SurrealKV)
547
- - **SDK** — [surrealdb.js](https://github.com/surrealdb/surrealdb.js) v2 + `@surrealdb/node`
547
+ - **SDK** — [surrealdb.js](https://github.com/surrealdb/surrealdb.js) v2 + `@mdrv/surreal-node` (fork of `@surrealdb/node`)
548
548
  - **CLI** — [crust](https://github.com/chenxin-yan/crust) (`@crustjs/core`)
549
549
  - **HTTP / MCP** — [Elysia](https://elysiajs.com) v1.4
550
550
  - **Validation** — [Zod](https://zod.dev) v4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suemo",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Persistent semantic memory for AI agents — backed by SurrealDB.",
5
5
  "author": {
6
6
  "name": "Umar Alfarouk",
@@ -51,7 +51,7 @@
51
51
  "@crustjs/style": "^0.0.6",
52
52
  "@logtape/file": "^2.0.4",
53
53
  "@logtape/logtape": "^2.0.4",
54
- "@surrealdb/node": "^3.0.3",
54
+ "@mdrv/surreal-node": "latest",
55
55
  "elysia": "^1.4.28",
56
56
  "surrealdb": "^2.0.3",
57
57
  "zod": "^4.3.6"
@@ -3,7 +3,7 @@ name: suemo
3
3
  description: OpenCode-focused persistent memory workflow for suemo with CLI/MCP parity and versioned references.
4
4
  license: GPL-3.0-only
5
5
  compatibility: opencode
6
- version: 0.1.8
6
+ version: 0.1.9
7
7
  ---
8
8
 
9
9
  # suemo skill
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agents-snippet
3
3
  description: AGENTS.md snippet optimized for suemo skill discovery and usage.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # AGENTS.md snippet
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: cli-reference
3
3
  description: CLI command reference for suemo v0.0.6 including skill access.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # CLI reference
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: core-workflow
3
3
  description: Canonical suemo operating loop for OpenCode agents.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # Core workflow
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: manual-test-plan
3
3
  description: Comprehensive manual test matrix for suemo features and commands.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # Manual test plan
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: mcp-reference
3
3
  description: MCP tool reference for suemo v0.0.6.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # MCP tools
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: schema-retention-longevity
3
3
  description: Long-term schema and retention design expectations for suemo.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # Schema + retention longevity
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: sync-local-vps
3
3
  description: Two-way sync manual scenario for local and VPS SurrealDB.
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  ---
6
6
 
7
7
  # Local ↔ VPS sync scenario
package/src/AGENTS.md CHANGED
@@ -127,4 +127,4 @@ Load docs once per session unless requirements changed.
127
127
 
128
128
  ---
129
129
 
130
- _Version: 0.1.8 | Updated: 2026-03-24 | Summary: stricter schema + explicit completion contract_
130
+ _Version: 0.1.9 | Updated: 2026-03-24 | Summary: stricter schema + explicit completion contract_
package/src/db/client.ts CHANGED
@@ -2,9 +2,9 @@
2
2
  // createRemoteEngines() handles ws://, wss://, http://, https:// connections.
3
3
  // createNodeEngines() patches in the Node.js WebSocket implementation.
4
4
  import type { SurrealTarget } from '@/src/config.ts'
5
- import { createSurrealEngines, toSurrealConnectionError } from '@/src/db/engines.ts'
6
5
  import { getLogger } from '@/src/logger.ts'
7
- import { Surreal } from 'surrealdb'
6
+ import { createNodeEngines } from '@mdrv/surreal-node'
7
+ import { createRemoteEngines, Surreal } from 'surrealdb'
8
8
 
9
9
  const log = getLogger(['suemo', 'db', 'client'])
10
10
 
@@ -19,33 +19,30 @@ export async function connect(target: SurrealTarget): Promise<Surreal> {
19
19
  db: target.database,
20
20
  })
21
21
 
22
- try {
23
- const engines = await createSurrealEngines({
24
- url: target.url,
25
- context: 'db:connect',
26
- })
27
-
28
- // v2 SDK: engines are registered at construction time, not at connect.
29
- const db = new Surreal({ engines })
30
-
31
- // v2 SDK: namespace, database, and authentication can all be passed inline
32
- // to connect(). The `authentication` callback is invoked on connect and on
33
- // any automatic reconnection/token-refresh cycle.
34
- await db.connect(target.url, {
35
- namespace: target.namespace,
36
- database: target.database,
37
- authentication: () => ({
38
- username: target.auth.user,
39
- password: target.auth.pass,
40
- }),
41
- })
42
-
43
- _db = db
44
- log.debug('Connected')
45
- return db
46
- } catch (error) {
47
- throw toSurrealConnectionError(error, 'db:connect', target.url)
48
- }
22
+ // v2 SDK: engines are registered at construction time, not at connect.
23
+ // Both remote (ws/wss/http) and Node.js engines are needed for Bun.
24
+ const db = new Surreal({
25
+ engines: {
26
+ ...createRemoteEngines(),
27
+ ...createNodeEngines(),
28
+ },
29
+ })
30
+
31
+ // v2 SDK: namespace, database, and authentication can all be passed inline
32
+ // to connect(). The `authentication` callback is invoked on connect and on
33
+ // any automatic reconnection/token-refresh cycle.
34
+ await db.connect(target.url, {
35
+ namespace: target.namespace,
36
+ database: target.database,
37
+ authentication: () => ({
38
+ username: target.auth.user,
39
+ password: target.auth.pass,
40
+ }),
41
+ })
42
+
43
+ _db = db
44
+ log.debug('Connected')
45
+ return db
49
46
  }
50
47
 
51
48
  export function getDb(): Surreal {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * suemo OpenCode plugin (v0.1.8)
2
+ * suemo OpenCode plugin (v0.1.9)
3
3
  *
4
4
  * Purpose:
5
5
  * - Inject strict, always-on suemo memory workflow instructions.
@@ -12,7 +12,7 @@
12
12
  import type { Plugin } from '@opencode-ai/plugin'
13
13
 
14
14
  const SERVICE = 'suemo-plugin'
15
- const PLUGIN_VERSION = '0.1.8'
15
+ const PLUGIN_VERSION = '0.1.9'
16
16
  const PROTOCOL_MARKER = 'Suemo Persistent Memory — Protocol'
17
17
 
18
18
  interface SystemTransformOutput {
@@ -38,7 +38,7 @@ interface PluginLogExtra {
38
38
  [key: string]: unknown
39
39
  }
40
40
 
41
- const MEMORY_INSTRUCTIONS = `## Suemo Persistent Memory — Protocol (v0.1.8)
41
+ const MEMORY_INSTRUCTIONS = `## Suemo Persistent Memory — Protocol (v0.1.9)
42
42
 
43
43
  You have access to suemo persistent memory tools (commonly prefixed as \`suemo_*\`).
44
44
 
package/src/sync.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { SurrealTarget } from '@/src/config.ts'
2
- import { createSurrealEngines, toSurrealConnectionError } from '@/src/db/engines.ts'
3
2
  import { getLogger } from '@/src/logger.ts'
4
3
  import type { SyncResult } from '@/src/types.ts'
4
+ import { createNodeEngines } from '@surrealdb/node'
5
5
  import { createHash } from 'node:crypto'
6
- import { Surreal } from 'surrealdb'
6
+ import { createRemoteEngines, Surreal } from 'surrealdb'
7
7
 
8
8
  const log = getLogger(['suemo', 'sync'])
9
9
 
@@ -32,24 +32,21 @@ function remoteKey(target: SurrealTarget): string {
32
32
  }
33
33
 
34
34
  async function makeRemoteDb(target: SurrealTarget): Promise<Surreal> {
35
- try {
36
- const engines = await createSurrealEngines({
37
- url: target.url,
38
- context: 'sync:remote-connect',
39
- })
40
- const db = new Surreal({ engines })
41
- await db.connect(target.url, {
42
- namespace: target.namespace,
43
- database: target.database,
44
- authentication: () => ({
45
- username: target.auth.user,
46
- password: target.auth.pass,
47
- }),
48
- })
49
- return db
50
- } catch (error) {
51
- throw toSurrealConnectionError(error, 'sync:remote-connect', target.url)
52
- }
35
+ const db = new Surreal({
36
+ engines: {
37
+ ...createRemoteEngines(),
38
+ ...createNodeEngines(),
39
+ },
40
+ })
41
+ await db.connect(target.url, {
42
+ namespace: target.namespace,
43
+ database: target.database,
44
+ authentication: () => ({
45
+ username: target.auth.user,
46
+ password: target.auth.pass,
47
+ }),
48
+ })
49
+ return db
53
50
  }
54
51
 
55
52
  async function pushMemoryBatch(
package/tsconfig.json CHANGED
@@ -24,5 +24,5 @@
24
24
  "@/*": ["./*"]
25
25
  }
26
26
  },
27
- "include": ["src/**/*", "suemo.config.ts"]
27
+ "include": ["src/**/*"]
28
28
  }
package/src/db/engines.ts DELETED
@@ -1,113 +0,0 @@
1
- import { getLogger } from '@/src/logger.ts'
2
- import { createRemoteEngines } from 'surrealdb'
3
-
4
- type SurrealEngines = ReturnType<typeof createRemoteEngines>
5
-
6
- const log = getLogger(['suemo', 'db', 'engines'])
7
-
8
- export interface CreateSurrealEnginesOptions {
9
- url: string
10
- context: string
11
- loadNodeEngines?: () => Promise<SurrealEngines>
12
- }
13
-
14
- const REMOTE_SCHEME_RE = /^(https?|wss?):\/\//i
15
-
16
- export function isRemoteSurrealUrl(url: string): boolean {
17
- return REMOTE_SCHEME_RE.test(url)
18
- }
19
-
20
- function isLikelyArm64NativeIssue(message: string): boolean {
21
- return message.includes('_ZTVSt12bad_weak_ptr')
22
- || message.includes('surrealdb-node.linux-arm64-gnu.node')
23
- || message.includes('surrealdb-node.linux-arm64-musl.node')
24
- || message.includes('Cannot find native binding')
25
- || message.includes('@surrealdb/node')
26
- }
27
-
28
- function buildArm64NativeBuildGuidance(): string {
29
- return [
30
- '@surrealdb/node native binding failed on linux arm64.',
31
- 'Automatic install of @surrealdb/node-linux-* is not attempted by suemo because npm package availability/versioning is inconsistent across arm64 variants.',
32
- 'Recommended workaround: build native binding locally and replace the bundled binary:',
33
- ' git clone https://github.com/surrealdb/surrealdb.js',
34
- ' cd surrealdb.js/packages/node',
35
- ' bun add -g @napi-rs/cli',
36
- ' bunx napi build --platform --release',
37
- ' cp surrealdb-node.linux-arm64-gnu.node ~/.bun/install/global/node_modules/@surrealdb/node/dist/',
38
- 'If your environment is musl-based, replace the destination file accordingly.',
39
- 'Also consider filing/upvoting an upstream issue for arm64 portability.',
40
- ].join('\n')
41
- }
42
-
43
- function wrapArm64NativeError(error: unknown, context: string, url: string): Error {
44
- const base = error instanceof Error ? error.message : String(error)
45
- const details = [
46
- `SurrealDB native engine initialization failed (${context}) for target: ${url}`,
47
- base,
48
- ]
49
-
50
- if (process.platform === 'linux' && process.arch === 'arm64') {
51
- details.push('', buildArm64NativeBuildGuidance())
52
- }
53
-
54
- return new Error(details.join('\n'))
55
- }
56
-
57
- async function defaultLoadNodeEngines(): Promise<SurrealEngines> {
58
- const mod = await import('@surrealdb/node')
59
- if (typeof mod.createNodeEngines !== 'function') {
60
- throw new Error('@surrealdb/node loaded without createNodeEngines export')
61
- }
62
- const engines = mod.createNodeEngines()
63
- if (!engines || typeof engines !== 'object') {
64
- throw new Error('@surrealdb/node createNodeEngines() returned invalid value')
65
- }
66
- return engines as SurrealEngines
67
- }
68
-
69
- export async function createSurrealEngines(options: CreateSurrealEnginesOptions): Promise<SurrealEngines> {
70
- const remoteEngines = createRemoteEngines() as SurrealEngines
71
- const loadNodeEngines = options.loadNodeEngines ?? defaultLoadNodeEngines
72
-
73
- try {
74
- const nodeEngines = await loadNodeEngines()
75
- log.debug('Loaded @surrealdb/node engines', {
76
- context: options.context,
77
- url: options.url,
78
- nodeEngineCount: Object.keys(nodeEngines).length,
79
- })
80
- return { ...remoteEngines, ...nodeEngines }
81
- } catch (error) {
82
- const message = error instanceof Error ? error.message : String(error)
83
- const remoteUrl = isRemoteSurrealUrl(options.url)
84
-
85
- log.warning('Unable to initialize @surrealdb/node engines', {
86
- context: options.context,
87
- url: options.url,
88
- platform: process.platform,
89
- arch: process.arch,
90
- remoteUrl,
91
- error: message,
92
- })
93
-
94
- if (!remoteUrl || isLikelyArm64NativeIssue(message)) {
95
- throw wrapArm64NativeError(error, options.context, options.url)
96
- }
97
-
98
- log.info('Falling back to remote-only engines', {
99
- context: options.context,
100
- url: options.url,
101
- })
102
- return remoteEngines
103
- }
104
- }
105
-
106
- export function toSurrealConnectionError(error: unknown, context: string, url: string): Error {
107
- const message = error instanceof Error ? error.message : String(error)
108
- if (isLikelyArm64NativeIssue(message)) {
109
- return wrapArm64NativeError(error, context, url)
110
- }
111
- if (error instanceof Error) return error
112
- return new Error(String(error))
113
- }