om-memory-system 5.10.1 → 6.1.0-next.237

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 (87) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/opencode/auto-capture-host.d.ts +2 -2
  3. package/dist/adapters/opencode/auto-capture-host.js +5 -15
  4. package/dist/adapters/opencode/auto-capture-summary.js +9 -6
  5. package/dist/adapters/opencode/backfill-models.js +1 -1
  6. package/dist/adapters/opencode/backfill-startup.js +5 -4
  7. package/dist/adapters/opencode/conversation.d.ts +5 -1
  8. package/dist/adapters/opencode/conversation.js +23 -23
  9. package/dist/adapters/opencode/import-command.d.ts +0 -12
  10. package/dist/adapters/opencode/import-command.js +1 -17
  11. package/dist/adapters/opencode/internal-capture-sessions.d.ts +0 -3
  12. package/dist/adapters/opencode/internal-capture-sessions.js +0 -26
  13. package/dist/adapters/opencode/memory-tool.d.ts +3 -4
  14. package/dist/adapters/opencode/memory-tool.js +8 -50
  15. package/dist/adapters/opencode/opencode-host.d.ts +27 -0
  16. package/dist/adapters/opencode/opencode-host.js +30 -0
  17. package/dist/adapters/opencode/opencode-import-models.d.ts +2 -2
  18. package/dist/adapters/opencode/opencode-import-models.js +8 -10
  19. package/dist/adapters/opencode/opencode-provider.d.ts +23 -62
  20. package/dist/adapters/opencode/opencode-provider.js +75 -378
  21. package/dist/adapters/opencode/package-skills.d.ts +1 -6
  22. package/dist/adapters/opencode/package-skills.js +2 -17
  23. package/dist/adapters/opencode/profile-learning.d.ts +1 -2
  24. package/dist/adapters/opencode/profile-learning.js +15 -19
  25. package/dist/adapters/opencode/profile-llm-client.d.ts +3 -2
  26. package/dist/adapters/opencode/profile-llm-client.js +8 -17
  27. package/dist/adapters/opencode/profile-model.d.ts +2 -18
  28. package/dist/adapters/opencode/profile-model.js +18 -69
  29. package/dist/adapters/opencode/prompt-model.d.ts +9 -0
  30. package/dist/adapters/opencode/prompt-model.js +21 -0
  31. package/dist/adapters/opencode/skills-tool.d.ts +3 -3
  32. package/dist/adapters/opencode/skills-tool.js +4 -30
  33. package/dist/adapters/opencode/toast.d.ts +11 -0
  34. package/dist/adapters/opencode/toast.js +11 -0
  35. package/dist/adapters/opencode/user-prompt.d.ts +2 -2
  36. package/dist/adapters/opencode/user-prompt.js +4 -5
  37. package/dist/config-template.d.ts +1 -1
  38. package/dist/config-template.js +2 -6
  39. package/dist/config.d.ts +0 -9
  40. package/dist/config.js +0 -9
  41. package/dist/core/retrieval.d.ts +0 -21
  42. package/dist/core/retrieval.js +0 -29
  43. package/dist/importer/handled-lookup.d.ts +17 -0
  44. package/dist/importer/handled-lookup.js +13 -0
  45. package/dist/importer/importer.js +3 -3
  46. package/dist/importer/ledger.d.ts +9 -0
  47. package/dist/importer/ledger.js +21 -0
  48. package/dist/importer/opencode-reader.d.ts +1 -1
  49. package/dist/importer/opencode-reader.js +88 -34
  50. package/dist/importer/opencode-v2-units.d.ts +16 -0
  51. package/dist/importer/opencode-v2-units.js +93 -0
  52. package/dist/importer/settings-models.d.ts +11 -6
  53. package/dist/importer/settings-models.js +15 -11
  54. package/dist/plugin.d.ts +0 -3
  55. package/dist/plugin.js +1 -7
  56. package/dist/services/global-config-writer.js +2 -3
  57. package/dist/services/settings-snapshot.js +6 -6
  58. package/dist/services/turso/vector-search.js +4 -2
  59. package/dist/shared/api/schemas.d.ts +1 -1
  60. package/dist/utils/memory-limits.d.ts +0 -1
  61. package/dist/utils/memory-limits.js +0 -1
  62. package/dist/v2/adapter.d.ts +16 -84
  63. package/dist/v2/adapter.js +17 -88
  64. package/dist/v2/memory-bridge.js +1 -1
  65. package/dist/v2/plugin.js +27 -16
  66. package/dist/v2/session-events.d.ts +30 -0
  67. package/dist/v2/session-events.js +130 -0
  68. package/dist/v2/startup.d.ts +14 -0
  69. package/dist/v2/startup.js +210 -0
  70. package/dist/v2/tools.d.ts +106 -0
  71. package/dist/v2/tools.js +89 -0
  72. package/dist/web/assets/index-DBSeQOs6.js +171 -0
  73. package/dist/web/index.html +1 -1
  74. package/package.json +2 -14
  75. package/dist/adapters/opencode/in-process-client.d.ts +0 -2
  76. package/dist/adapters/opencode/in-process-client.js +0 -16
  77. package/dist/adapters/opencode/opencode-diagnostics.d.ts +0 -7
  78. package/dist/adapters/opencode/opencode-diagnostics.js +0 -37
  79. package/dist/adapters/opencode/opencode-host-config.d.ts +0 -13
  80. package/dist/adapters/opencode/opencode-host-config.js +0 -53
  81. package/dist/adapters/opencode/opencode-sdk-client.d.ts +0 -6
  82. package/dist/adapters/opencode/opencode-sdk-client.js +0 -38
  83. package/dist/index.d.ts +0 -28
  84. package/dist/index.js +0 -620
  85. package/dist/v2/legacy-client.d.ts +0 -15
  86. package/dist/v2/legacy-client.js +0 -275
  87. package/dist/web/assets/index-DQgI670D.js +0 -171
@@ -0,0 +1,210 @@
1
+ import { memoryClient } from "../services/client.js";
2
+ import { getTags } from "../services/tags.js";
3
+ import { createOpenCodeAutoCaptureHost } from "../adapters/opencode/auto-capture-host.js";
4
+ import { pruneTraces } from "../services/capture-diagnostics.js";
5
+ import { ensureTursoReady } from "../services/turso/ready.js";
6
+ import { tursoConnectionManager } from "../services/turso/connection-manager.js";
7
+ import { isConfigured, CONFIG, initConfigWithLegacyMigration } from "../config.js";
8
+ import { log } from "../services/logger.js";
9
+ import { loadOpencodeProvider } from "../adapters/opencode/opencode-provider-loader.js";
10
+ import { registerOpencodeProfileModel } from "../adapters/opencode/profile-model.js";
11
+ import { showOpencodeNotice } from "../adapters/opencode/toast.js";
12
+ const GLOBAL_PLUGIN_WARMUP_KEY = Symbol.for("omms.plugin.warmedup");
13
+ function logAutoCaptureProviderStatus() {
14
+ if (!CONFIG.autoCaptureEnabled || CONFIG.autoCaptureProviderStatus.ready)
15
+ return;
16
+ log(`Auto-capture disabled by configuration. Issues: ${CONFIG.autoCaptureProviderStatus.issues.join("; ")}.`);
17
+ }
18
+ /** OpenCode's default model as `provider/model`, read through the V2 model API. */
19
+ async function defaultModel(ctx) {
20
+ const result = await ctx.model.default();
21
+ const model = result?.data;
22
+ return model?.providerID && model?.id ? `${model.providerID}/${model.id}` : null;
23
+ }
24
+ /** Connected provider ids from the V2 model list. */
25
+ async function connectedProviders(ctx) {
26
+ const models = await ctx.model.list();
27
+ return [...new Set(models.data.map((model) => model.providerID).filter(Boolean))];
28
+ }
29
+ /** Check providers, then register backfill models and start the automatic backfill. */
30
+ async function startProviderWork(ctx, directory) {
31
+ let connected = [];
32
+ try {
33
+ connected = await connectedProviders(ctx);
34
+ if (connected.length > 0) {
35
+ const { setConnectedProviders } = await loadOpencodeProvider();
36
+ setConnectedProviders(connected);
37
+ log("opencode providers connected", {
38
+ list: connected,
39
+ configured: CONFIG.opencodeProvider || "(not set)",
40
+ });
41
+ }
42
+ else {
43
+ log("opencode provider list empty", undefined, "warn");
44
+ }
45
+ }
46
+ catch (error) {
47
+ log("Failed to initialize opencode provider state", { error: String(error) }, "error");
48
+ }
49
+ const configModel = () => defaultModel(ctx);
50
+ // Run now on a Settings page served by this process can use OpenCode's signed-in models.
51
+ void import("../adapters/opencode/backfill-startup.js")
52
+ .then(({ registerOpencodeBackfillModels }) => registerOpencodeBackfillModels({ connected, directory, configModel }))
53
+ .catch(() => { });
54
+ if (CONFIG.autoBackfill && process.env.OMMS_DISABLE_AUTO_BACKFILL !== "1" && isConfigured()) {
55
+ void import("../adapters/opencode/backfill-startup.js")
56
+ .then(({ startOpencodeBackfill }) => startOpencodeBackfill({
57
+ connected,
58
+ directory,
59
+ configModel,
60
+ notify: (message) => showOpencodeNotice({ title: "Automatic import", message, variant: "info" }),
61
+ }))
62
+ .catch((error) => log("OpenCode backfill failed", { error: error instanceof Error ? error.message : String(error) }, "error"));
63
+ }
64
+ }
65
+ /** Start the shared web app unless one already runs. */
66
+ async function startWebApp() {
67
+ let tursoReadyForWeb = !isConfigured();
68
+ if (CONFIG.webServerEnabled && isConfigured()) {
69
+ try {
70
+ await ensureTursoReady();
71
+ tursoReadyForWeb = true;
72
+ }
73
+ catch (error) {
74
+ log("Turso ready gate failed before web server start", { error: String(error) }, "error");
75
+ showOpencodeNotice({
76
+ title: "Memory Explorer",
77
+ message: "Database migration failed; web UI not started",
78
+ variant: "error",
79
+ });
80
+ }
81
+ }
82
+ if (!CONFIG.webServerEnabled ||
83
+ !tursoReadyForWeb ||
84
+ process.env.OMMS_DISABLE_WEB_AUTOSTART === "1") {
85
+ return;
86
+ }
87
+ const notice = (message, variant) => showOpencodeNotice({ title: "Memory Explorer", message, variant });
88
+ // The shared web app serves the page. This plugin starts it only when none runs.
89
+ void Promise.all([
90
+ import("../services/web-ensure.js"),
91
+ import("../services/web-api-auth.js"),
92
+ import("../services/runtime-handoff.js"),
93
+ ])
94
+ .then(async ([{ ensureWebApp }, { webServerUrl }, { hostReplaceOlder }]) => {
95
+ const baseUrl = webServerUrl(CONFIG.webServerHost, CONFIG.webServerPort);
96
+ // A web app older than the newest recorded copy steps aside for it.
97
+ const replaceOlder = await hostReplaceOlder(CONFIG).catch(() => undefined);
98
+ return ensureWebApp({
99
+ settings: { enabled: CONFIG.webServerEnabled, baseUrl },
100
+ budgetMs: 10_000,
101
+ ...(replaceOlder ? { replaceOlder } : {}),
102
+ }).then((result) => {
103
+ if (result === "running" || result === "started") {
104
+ notice(`Web UI available at ${baseUrl}`, "info");
105
+ }
106
+ else if (result === "port-busy") {
107
+ notice(`Web UI unavailable: another program uses port ${CONFIG.webServerPort}`, "error");
108
+ }
109
+ else if (result === "no-runtime") {
110
+ notice("Web UI unavailable: no Node or Bun runtime found to start it", "error");
111
+ }
112
+ });
113
+ })
114
+ .catch((error) => log("Web app start failed", { error: String(error) }, "error"));
115
+ }
116
+ /**
117
+ * Start OMMS for an OpenCode V2 plugin: config, traces, runtime record, warm-up, models,
118
+ * backfill, web app and shutdown handlers. Returns the dispose function for plugin unload.
119
+ */
120
+ export async function startOpencodeRuntime(ctx, onCleanup = () => { }) {
121
+ const directory = ctx.location.directory;
122
+ initConfigWithLegacyMigration(directory);
123
+ // Runs even with tracing off, so turning it off does not leave old traces behind.
124
+ pruneTraces(CONFIG);
125
+ // Record this copy first: the login item and the other hosts run the newest recorded copy.
126
+ void import("../services/runtime-handoff.js")
127
+ .then(({ registerOwnCopy }) => registerOwnCopy())
128
+ .catch((error) => log("OpenCode runtime record failed", { code: error instanceof Error ? error.name : "unknown" }, "error"));
129
+ if (CONFIG.webServerAutoStart !== undefined && process.env.OMMS_DISABLE_WEB_AUTOSTART !== "1") {
130
+ void import("../services/web-autostart.js")
131
+ .then(({ reconcileWebAutostart }) => reconcileWebAutostart(CONFIG))
132
+ .catch((error) => log("OpenCode login item reconciliation failed", { code: error instanceof Error ? error.name : "unknown" }, "error"));
133
+ }
134
+ logAutoCaptureProviderStatus();
135
+ const tags = getTags(directory);
136
+ const autoCaptureHost = createOpenCodeAutoCaptureHost(ctx);
137
+ if (!globalThis[GLOBAL_PLUGIN_WARMUP_KEY] && isConfigured()) {
138
+ // Fire-and-forget: DB ready + embedding model must not block plugin init.
139
+ void (async () => {
140
+ try {
141
+ await memoryClient.warmup();
142
+ globalThis[GLOBAL_PLUGIN_WARMUP_KEY] = true;
143
+ }
144
+ catch (error) {
145
+ log("Plugin memory warmup failed", { error: String(error) }, "error");
146
+ }
147
+ })();
148
+ }
149
+ // Shared profile dedup, conflict, description, and cleanup calls use OpenCode's host model.
150
+ registerOpencodeProfileModel();
151
+ // In-process backfill, capture, and the capture retry drain use OpenCode's models.
152
+ // Awaited so those paths never run before the registry is filled.
153
+ await import("../adapters/opencode/backfill-startup.js")
154
+ .then(({ registerOpencodeImportModels, registerOpencodeCaptureRetryDrain }) => {
155
+ registerOpencodeImportModels();
156
+ registerOpencodeCaptureRetryDrain(autoCaptureHost, directory);
157
+ })
158
+ .catch(() => { });
159
+ void startProviderWork(ctx, directory);
160
+ await startWebApp();
161
+ let cleanedUp = false;
162
+ const cleanup = async () => {
163
+ if (cleanedUp)
164
+ return;
165
+ cleanedUp = true;
166
+ onCleanup();
167
+ if (memoryClient)
168
+ await memoryClient.close();
169
+ };
170
+ const shutdownHandler = async () => {
171
+ try {
172
+ await cleanup();
173
+ }
174
+ catch (error) {
175
+ log("Shutdown error", { error: String(error) }, "error");
176
+ process.exitCode = 1;
177
+ }
178
+ };
179
+ const beforeExitHandler = () => {
180
+ if (!cleanedUp)
181
+ void cleanup();
182
+ };
183
+ const exitHandler = () => {
184
+ // Best-effort sync close when the host exits without SIGINT/SIGTERM.
185
+ if (cleanedUp)
186
+ return;
187
+ try {
188
+ tursoConnectionManager.closeAllSync();
189
+ }
190
+ catch {
191
+ // ignore: the module may already be torn down
192
+ }
193
+ };
194
+ process.on("SIGINT", shutdownHandler);
195
+ process.on("SIGTERM", shutdownHandler);
196
+ process.on("beforeExit", beforeExitHandler);
197
+ process.on("exit", exitHandler);
198
+ return {
199
+ directory,
200
+ tags,
201
+ autoCaptureHost,
202
+ async dispose() {
203
+ process.off("SIGINT", shutdownHandler);
204
+ process.off("SIGTERM", shutdownHandler);
205
+ process.off("beforeExit", beforeExitHandler);
206
+ process.off("exit", exitHandler);
207
+ await cleanup();
208
+ },
209
+ };
210
+ }
@@ -0,0 +1,106 @@
1
+ import type { Context } from "@opencode/plugin/promise/plugin";
2
+ import type { MemoryOperationContext } from "../core/memory-operations.js";
3
+ export declare const memoryInput: {
4
+ readonly type: "object";
5
+ readonly properties: {
6
+ readonly mode: {
7
+ readonly type: "string";
8
+ readonly enum: readonly ["add", "memorise", "memorize", "recall", "search", "profile", "list", "forget", "help", "migrate", "list-shards", "export", "import", "space"];
9
+ };
10
+ readonly content: {
11
+ readonly type: "string";
12
+ };
13
+ readonly query: {
14
+ readonly type: "string";
15
+ };
16
+ readonly tags: {
17
+ readonly type: "string";
18
+ };
19
+ readonly type: {
20
+ readonly type: "string";
21
+ };
22
+ readonly topic: {
23
+ readonly type: "string";
24
+ };
25
+ readonly done: {
26
+ readonly type: "string";
27
+ };
28
+ readonly doing: {
29
+ readonly type: "string";
30
+ };
31
+ readonly next: {
32
+ readonly type: "string";
33
+ };
34
+ readonly memoryId: {
35
+ readonly type: "string";
36
+ };
37
+ readonly limit: {
38
+ readonly type: "number";
39
+ };
40
+ readonly scope: {
41
+ readonly type: "string";
42
+ readonly enum: readonly ["project", "all-projects"];
43
+ };
44
+ readonly fromPath: {
45
+ readonly type: "string";
46
+ };
47
+ readonly fromHash: {
48
+ readonly type: "string";
49
+ };
50
+ readonly outputPath: {
51
+ readonly type: "string";
52
+ };
53
+ readonly inputPath: {
54
+ readonly type: "string";
55
+ };
56
+ readonly dryRun: {
57
+ readonly type: "boolean";
58
+ };
59
+ readonly allowLinkedSource: {
60
+ readonly type: "boolean";
61
+ };
62
+ readonly spaceAction: {
63
+ readonly type: "string";
64
+ };
65
+ readonly spaceName: {
66
+ readonly type: "string";
67
+ };
68
+ readonly spaceTo: {
69
+ readonly type: "string";
70
+ };
71
+ readonly spaceSince: {
72
+ readonly type: "string";
73
+ };
74
+ readonly spaceUntil: {
75
+ readonly type: "string";
76
+ };
77
+ readonly spaceProject: {
78
+ readonly type: "string";
79
+ };
80
+ readonly spaceIn: {
81
+ readonly type: "string";
82
+ };
83
+ };
84
+ readonly additionalProperties: false;
85
+ };
86
+ /** What OpenCode passes to a tool call that the executors read. */
87
+ export type OpencodeToolCall = {
88
+ readonly sessionID?: string;
89
+ readonly messageID?: string;
90
+ readonly agent?: string;
91
+ };
92
+ export type OpencodeToolExecutor = {
93
+ readonly description: string;
94
+ readonly execute: (args: any, call: OpencodeToolCall) => Promise<string>;
95
+ };
96
+ export type OpencodeTools = {
97
+ readonly memory: OpencodeToolExecutor;
98
+ readonly skills: OpencodeToolExecutor;
99
+ };
100
+ /** The `memory` and `skills` executors over the shared operations. */
101
+ export declare function createOpencodeTools(base: Pick<MemoryOperationContext, "directory" | "tags">, languageName: string): OpencodeTools;
102
+ /**
103
+ * Register each tool as a direct V2 tool, like OpenCode's own read/grep/skill, not a
104
+ * Code Mode catalog entry, so the model can always see and call it (as on Pi).
105
+ */
106
+ export declare function registerOpencodeTools(ctx: Context, tools: OpencodeTools): Promise<void>;
@@ -0,0 +1,89 @@
1
+ import { SKILLS_TOOL_DESCRIPTION, SKILLS_TOOL_INPUT_SCHEMA } from "../core/skills-tool.js";
2
+ import { memoryToolDescription } from "../core/memory-tool-text.js";
3
+ import { runOpencodeMemoryTool } from "../adapters/opencode/memory-tool.js";
4
+ import { runOpencodeSkillsTool } from "../adapters/opencode/skills-tool.js";
5
+ export const memoryInput = {
6
+ type: "object",
7
+ properties: {
8
+ mode: {
9
+ type: "string",
10
+ enum: [
11
+ "add",
12
+ "memorise",
13
+ "memorize",
14
+ "recall",
15
+ "search",
16
+ "profile",
17
+ "list",
18
+ "forget",
19
+ "help",
20
+ "migrate",
21
+ "list-shards",
22
+ "export",
23
+ "import",
24
+ "space",
25
+ ],
26
+ },
27
+ content: { type: "string" },
28
+ query: { type: "string" },
29
+ tags: { type: "string" },
30
+ type: { type: "string" },
31
+ topic: { type: "string" },
32
+ done: { type: "string" },
33
+ doing: { type: "string" },
34
+ next: { type: "string" },
35
+ memoryId: { type: "string" },
36
+ limit: { type: "number" },
37
+ scope: { type: "string", enum: ["project", "all-projects"] },
38
+ fromPath: { type: "string" },
39
+ fromHash: { type: "string" },
40
+ outputPath: { type: "string" },
41
+ inputPath: { type: "string" },
42
+ dryRun: { type: "boolean" },
43
+ allowLinkedSource: { type: "boolean" },
44
+ spaceAction: { type: "string" },
45
+ spaceName: { type: "string" },
46
+ spaceTo: { type: "string" },
47
+ spaceSince: { type: "string" },
48
+ spaceUntil: { type: "string" },
49
+ spaceProject: { type: "string" },
50
+ spaceIn: { type: "string" },
51
+ },
52
+ additionalProperties: false,
53
+ };
54
+ /** The `memory` and `skills` executors over the shared operations. */
55
+ export function createOpencodeTools(base, languageName) {
56
+ return {
57
+ memory: {
58
+ description: memoryToolDescription(languageName),
59
+ execute: (args, call) => runOpencodeMemoryTool(args, base, call.sessionID),
60
+ },
61
+ skills: {
62
+ description: SKILLS_TOOL_DESCRIPTION,
63
+ execute: (args) => runOpencodeSkillsTool(args, base.directory),
64
+ },
65
+ };
66
+ }
67
+ /**
68
+ * Register each tool as a direct V2 tool, like OpenCode's own read/grep/skill, not a
69
+ * Code Mode catalog entry, so the model can always see and call it (as on Pi).
70
+ */
71
+ export async function registerOpencodeTools(ctx, tools) {
72
+ const definition = (name, input) => ({
73
+ name,
74
+ description: tools[name].description,
75
+ input: input,
76
+ options: { codemode: false },
77
+ execute: async (args, toolContext) => ({
78
+ content: await tools[name].execute(args, {
79
+ sessionID: toolContext?.sessionID,
80
+ messageID: toolContext?.messageID,
81
+ agent: toolContext?.agent,
82
+ }),
83
+ }),
84
+ });
85
+ await ctx.tool.transform((editor) => {
86
+ editor.add(definition("memory", memoryInput));
87
+ editor.add(definition("skills", SKILLS_TOOL_INPUT_SCHEMA));
88
+ });
89
+ }