suemo 0.1.8 → 0.1.10
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 +1 -1
- package/package.json +6 -6
- package/skills/suemo/SKILL.md +1 -2
- package/skills/suemo/references/agents-snippet.md +0 -1
- package/skills/suemo/references/cli-reference.md +0 -1
- package/skills/suemo/references/core-workflow.md +0 -1
- package/skills/suemo/references/manual-test-plan.md +0 -1
- package/skills/suemo/references/mcp-reference.md +0 -1
- package/skills/suemo/references/schema-retention-longevity.md +0 -1
- package/skills/suemo/references/sync-local-vps.md +0 -1
- package/src/AGENTS.md +0 -2
- package/src/cli/commands/init.ts +1 -1
- package/src/db/client.ts +26 -29
- package/src/opencode/plugin.ts +3 -3
- package/src/sync.ts +17 -20
- package/tsconfig.json +1 -1
- package/src/db/engines.ts +0 -113
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.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Persistent semantic memory for AI agents — backed by SurrealDB.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Umar Alfarouk",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"@crustjs/plugins": "^0.0.20",
|
|
50
50
|
"@crustjs/prompts": "^0.0.10",
|
|
51
51
|
"@crustjs/style": "^0.0.6",
|
|
52
|
-
"@logtape/file": "^2.0.
|
|
53
|
-
"@logtape/logtape": "^2.0.
|
|
54
|
-
"@
|
|
52
|
+
"@logtape/file": "^2.0.5",
|
|
53
|
+
"@logtape/logtape": "^2.0.5",
|
|
54
|
+
"@mdrv/surreal-node": "^3.0.3",
|
|
55
55
|
"elysia": "^1.4.28",
|
|
56
56
|
"surrealdb": "^2.0.3",
|
|
57
57
|
"zod": "^4.3.6"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@opencode-ai/plugin": "^1.3.
|
|
60
|
+
"@opencode-ai/plugin": "^1.3.2",
|
|
61
61
|
"@types/bun": "^1.3.11",
|
|
62
|
-
"typescript": "^
|
|
62
|
+
"typescript": "^6.0.2"
|
|
63
63
|
}
|
|
64
64
|
}
|
package/skills/suemo/SKILL.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: suemo
|
|
3
|
-
description: OpenCode-focused persistent memory workflow for suemo with CLI/MCP parity and
|
|
3
|
+
description: OpenCode-focused persistent memory workflow for suemo with CLI/MCP parity and references.
|
|
4
4
|
license: GPL-3.0-only
|
|
5
5
|
compatibility: opencode
|
|
6
|
-
version: 0.1.8
|
|
7
6
|
---
|
|
8
7
|
|
|
9
8
|
# suemo skill
|
package/src/AGENTS.md
CHANGED
package/src/cli/commands/init.ts
CHANGED
|
@@ -1325,7 +1325,7 @@ const initFastembedCmd = init.sub('fastembed')
|
|
|
1325
1325
|
'id',
|
|
1326
1326
|
...(manager.kind === 'systemd' ? ['systemctl'] : ['ln', 'chpst']),
|
|
1327
1327
|
])
|
|
1328
|
-
requireArchPackages(['python-fastembed', 'python-fastapi', '
|
|
1328
|
+
requireArchPackages(['python-fastembed', 'python-fastapi', 'uvicorn'])
|
|
1329
1329
|
|
|
1330
1330
|
const scriptContent = FASTEMBED_SCRIPT_TEXT
|
|
1331
1331
|
const result = buildFastembedActions(scriptContent, manager)
|
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 {
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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 {
|
package/src/opencode/plugin.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* suemo OpenCode plugin (v0.1.
|
|
2
|
+
* suemo OpenCode plugin (v0.1.10)
|
|
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.
|
|
15
|
+
const PLUGIN_VERSION = '0.1.10'
|
|
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.
|
|
41
|
+
const MEMORY_INSTRUCTIONS = `## Suemo Persistent Memory — Protocol (v0.1.10)
|
|
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 '@mdrv/surreal-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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
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
|
-
}
|