@basicmemory/openclaw-basic-memory 0.24.0 → 1.0.0
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 +24 -12
- package/bm-client.ts +302 -112
- package/commands/cli.ts +5 -6
- package/commands/slash.ts +4 -4
- package/context-engine/basic-memory-context-engine.ts +74 -9
- package/context-engine/types.ts +21 -0
- package/dist/bm-client.d.ts +61 -12
- package/dist/bm-client.js +250 -101
- package/dist/commands/cli.d.ts +1 -1
- package/dist/commands/cli.js +5 -5
- package/dist/commands/slash.d.ts +1 -1
- package/dist/commands/slash.js +4 -3
- package/dist/context-engine/basic-memory-context-engine.d.ts +20 -1
- package/dist/context-engine/basic-memory-context-engine.js +50 -2
- package/dist/context-engine/types.d.ts +9 -0
- package/dist/context-engine/types.js +1 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +79 -69
- package/dist/memory/basic-memory-capability.d.ts +19 -0
- package/dist/memory/basic-memory-capability.js +190 -0
- package/dist/tools/build-context.d.ts +1 -1
- package/dist/tools/build-context.js +12 -4
- package/dist/tools/delete-note.d.ts +1 -1
- package/dist/tools/delete-note.js +2 -1
- package/dist/tools/edit-note.d.ts +1 -1
- package/dist/tools/edit-note.js +22 -12
- package/dist/tools/list-memory-projects.d.ts +1 -1
- package/dist/tools/list-memory-projects.js +2 -1
- package/dist/tools/list-workspaces.d.ts +1 -1
- package/dist/tools/list-workspaces.js +4 -4
- package/dist/tools/move-note.d.ts +1 -1
- package/dist/tools/move-note.js +2 -1
- package/dist/tools/read-note.d.ts +1 -1
- package/dist/tools/read-note.js +2 -1
- package/dist/tools/schema-diff.d.ts +1 -1
- package/dist/tools/schema-diff.js +2 -1
- package/dist/tools/schema-infer.d.ts +1 -1
- package/dist/tools/schema-infer.js +2 -1
- package/dist/tools/schema-validate.d.ts +1 -1
- package/dist/tools/schema-validate.js +2 -1
- package/dist/tools/search-notes.d.ts +1 -1
- package/dist/tools/search-notes.js +13 -6
- package/dist/tools/write-note.d.ts +1 -1
- package/dist/tools/write-note.js +11 -12
- package/index.ts +93 -84
- package/memory/basic-memory-capability.ts +253 -0
- package/openclaw.plugin.json +0 -2
- package/package.json +6 -5
- package/skills/manifest.json +5 -0
- package/skills/memory-agents/SKILL.md +23 -10
- package/skills/memory-capture/SKILL.md +29 -18
- package/skills/memory-comark/SKILL.md +17 -6
- package/skills/memory-continue/SKILL.md +47 -27
- package/skills/memory-curate/SKILL.md +40 -24
- package/skills/memory-defrag/SKILL.md +18 -7
- package/skills/memory-doctor/SKILL.md +93 -0
- package/skills/memory-ingest/SKILL.md +33 -17
- package/skills/memory-lifecycle/SKILL.md +35 -22
- package/skills/memory-literary-analysis/SKILL.md +112 -75
- package/skills/memory-metadata-search/SKILL.md +39 -28
- package/skills/memory-notes/SKILL.md +75 -50
- package/skills/memory-okf/SKILL.md +27 -15
- package/skills/memory-onboarding/SKILL.md +20 -9
- package/skills/memory-onboarding/references/assistant-setup.md +1 -1
- package/skills/memory-onboarding/references/conventions.md +4 -4
- package/skills/memory-onboarding/references/domain-playbooks.md +1 -1
- package/skills/memory-onboarding/references/schema-guide.md +9 -8
- package/skills/memory-quest/SKILL.md +18 -7
- package/skills/memory-reflect/SKILL.md +25 -13
- package/skills/memory-research/SKILL.md +28 -13
- package/skills/memory-schema/SKILL.md +36 -24
- package/skills/memory-tasks/SKILL.md +34 -22
- package/tools/build-context.ts +14 -5
- package/tools/delete-note.ts +2 -2
- package/tools/edit-note.ts +27 -14
- package/tools/list-memory-projects.ts +6 -2
- package/tools/list-workspaces.ts +8 -5
- package/tools/move-note.ts +2 -2
- package/tools/read-note.ts +2 -2
- package/tools/schema-diff.ts +2 -2
- package/tools/schema-infer.ts +2 -2
- package/tools/schema-validate.ts +2 -2
- package/tools/search-notes.ts +18 -7
- package/tools/write-note.ts +12 -12
- package/dist/tools/memory-provider.d.ts +0 -15
- package/dist/tools/memory-provider.js +0 -275
- package/tools/memory-provider.ts +0 -336
package/commands/cli.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry"
|
|
2
|
-
import type
|
|
2
|
+
import { type BmClient, searchResultText } from "../bm-client.ts"
|
|
3
3
|
import type { BasicMemoryConfig } from "../config.ts"
|
|
4
4
|
import { log } from "../logger.ts"
|
|
5
5
|
|
|
@@ -31,13 +31,12 @@ export function registerCli(
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
for (const r of results) {
|
|
34
|
-
const score = r.score ? ` (${
|
|
34
|
+
const score = r.score ? ` (score ${r.score.toFixed(2)})` : ""
|
|
35
35
|
console.log(`- ${r.title}${score}`)
|
|
36
|
-
|
|
36
|
+
const text = searchResultText(r)
|
|
37
|
+
if (text) {
|
|
37
38
|
const preview =
|
|
38
|
-
|
|
39
|
-
? `${r.content.slice(0, 100)}...`
|
|
40
|
-
: r.content
|
|
39
|
+
text.length > 100 ? `${text.slice(0, 100)}...` : text
|
|
41
40
|
console.log(` ${preview}`)
|
|
42
41
|
}
|
|
43
42
|
}
|
package/commands/slash.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { execSync } from "node:child_process"
|
|
|
2
2
|
import { dirname, resolve } from "node:path"
|
|
3
3
|
import { fileURLToPath } from "node:url"
|
|
4
4
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry"
|
|
5
|
-
import type
|
|
5
|
+
import { type BmClient, describeToolError } from "../bm-client.ts"
|
|
6
6
|
import { log } from "../logger.ts"
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
@@ -62,7 +62,7 @@ export function registerCommands(
|
|
|
62
62
|
} catch (err) {
|
|
63
63
|
log.error("/remember failed", err)
|
|
64
64
|
return {
|
|
65
|
-
text:
|
|
65
|
+
text: `Failed to save memory: ${describeToolError(err)}`,
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
},
|
|
@@ -89,7 +89,7 @@ export function registerCommands(
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
const lines = results.map((r, i) => {
|
|
92
|
-
const score = r.score ? ` (${
|
|
92
|
+
const score = r.score ? ` (score ${r.score.toFixed(2)})` : ""
|
|
93
93
|
return `${i + 1}. ${r.title}${score}`
|
|
94
94
|
})
|
|
95
95
|
|
|
@@ -99,7 +99,7 @@ export function registerCommands(
|
|
|
99
99
|
} catch (err) {
|
|
100
100
|
log.error("/recall failed", err)
|
|
101
101
|
return {
|
|
102
|
-
text:
|
|
102
|
+
text: `Failed to search: ${describeToolError(err)}`,
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
},
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AssembleResult,
|
|
3
|
-
BootstrapResult,
|
|
4
|
-
CompactResult,
|
|
5
|
-
ContextEngine,
|
|
6
|
-
SubagentSpawnPreparation,
|
|
7
|
-
} from "openclaw/plugin-sdk"
|
|
8
1
|
import { delegateCompactionToRuntime } from "openclaw/plugin-sdk/core"
|
|
9
2
|
import type { BmClient } from "../bm-client.ts"
|
|
10
3
|
import type { BasicMemoryConfig } from "../config.ts"
|
|
11
4
|
import { selectCaptureTurn } from "../hooks/capture.ts"
|
|
12
5
|
import { loadRecallState } from "../hooks/recall.ts"
|
|
13
6
|
import { log } from "../logger.ts"
|
|
7
|
+
import type {
|
|
8
|
+
AssembleResult,
|
|
9
|
+
BootstrapResult,
|
|
10
|
+
CommitTurnResult,
|
|
11
|
+
CompactResult,
|
|
12
|
+
ContextEngine,
|
|
13
|
+
SubagentSpawnPreparation,
|
|
14
|
+
} from "./types.ts"
|
|
14
15
|
|
|
15
16
|
export const MAX_ASSEMBLE_RECALL_CHARS = 1200
|
|
16
17
|
const TRUNCATED_RECALL_SUFFIX = "\n\n[Basic Memory recall truncated]"
|
|
17
18
|
const SUBAGENT_HANDOFF_FOLDER = "agent/subagents"
|
|
18
19
|
const MAX_SUBAGENT_RECALL_CHARS = 800
|
|
20
|
+
// OpenClaw's reply for "nothing to say", used by heartbeat polls and silent
|
|
21
|
+
// maintenance turns.
|
|
22
|
+
const SILENT_REPLY_TOKEN = "NO_REPLY"
|
|
19
23
|
|
|
20
24
|
type BootstrapParams = Parameters<NonNullable<ContextEngine["bootstrap"]>>[0]
|
|
21
25
|
type AssembleParams = Parameters<ContextEngine["assemble"]>[0]
|
|
22
26
|
type AfterTurnParams = Parameters<NonNullable<ContextEngine["afterTurn"]>>[0]
|
|
27
|
+
type CommitTurnParams = Parameters<NonNullable<ContextEngine["commitTurn"]>>[0]
|
|
23
28
|
type CompactParams = Parameters<ContextEngine["compact"]>[0]
|
|
24
29
|
type PrepareSubagentSpawnParams = Parameters<
|
|
25
30
|
NonNullable<ContextEngine["prepareSubagentSpawn"]>
|
|
@@ -53,6 +58,19 @@ function boundRecallContext(context: string): string {
|
|
|
53
58
|
return `${trimmed}${TRUNCATED_RECALL_SUFFIX}`
|
|
54
59
|
}
|
|
55
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Heartbeat polls and silent replies are host housekeeping, not
|
|
63
|
+
* conversation, so they are acknowledged without being recorded.
|
|
64
|
+
*/
|
|
65
|
+
function isHousekeepingTurn(
|
|
66
|
+
isHeartbeat: boolean | undefined,
|
|
67
|
+
turn: { assistantText: string },
|
|
68
|
+
): boolean {
|
|
69
|
+
return (
|
|
70
|
+
isHeartbeat === true || turn.assistantText.trim() === SILENT_REPLY_TOKEN
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
56
74
|
function slugifySessionKey(sessionKey: string): string {
|
|
57
75
|
return sessionKey
|
|
58
76
|
.toLowerCase()
|
|
@@ -98,7 +116,7 @@ function buildSubagentCompletionUpdate(params: {
|
|
|
98
116
|
}): string {
|
|
99
117
|
const statusLine =
|
|
100
118
|
params.reason === "completed"
|
|
101
|
-
? "Child run completed. Durable conversation capture continues through the normal
|
|
119
|
+
? "Child run completed. Durable conversation capture continues through the normal turn commit path."
|
|
102
120
|
: `Child run ended with reason: ${params.reason}.`
|
|
103
121
|
|
|
104
122
|
return [
|
|
@@ -118,6 +136,18 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
118
136
|
name: "Basic Memory Context Engine",
|
|
119
137
|
version: "0.1.5",
|
|
120
138
|
ownsCompaction: false,
|
|
139
|
+
// OpenClaw 2026.10+ runs an engine for durable turns only when it
|
|
140
|
+
// declares both semantics; otherwise the turn degrades to "legacy" and
|
|
141
|
+
// nothing is captured (#1880).
|
|
142
|
+
// - The fence holds because assemble() passes the host's messages through
|
|
143
|
+
// unchanged and the engine keeps no transcript of its own, so it never
|
|
144
|
+
// reads past the admitted user entry.
|
|
145
|
+
// - Advancement is idempotent because commitTurn() records the
|
|
146
|
+
// advancement key in the conversation note and skips keys it has seen.
|
|
147
|
+
transcriptSemantics: {
|
|
148
|
+
currentTurnFence: "before-current-turn-entry-v1",
|
|
149
|
+
turnAdvancementIdempotency: "atomic-idempotent-v1",
|
|
150
|
+
},
|
|
121
151
|
} as const
|
|
122
152
|
|
|
123
153
|
private readonly sessionState = new Map<string, SessionMemoryState>()
|
|
@@ -171,6 +201,41 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
171
201
|
}
|
|
172
202
|
}
|
|
173
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Capture one accepted turn on hosts with durable turn advancement.
|
|
206
|
+
*
|
|
207
|
+
* The host calls this instead of afterTurn() for admitted turns, and may
|
|
208
|
+
* call it again with the same advancement key after a crash. Errors
|
|
209
|
+
* propagate so the host keeps the turn queued and retries it.
|
|
210
|
+
*/
|
|
211
|
+
async commitTurn(params: CommitTurnParams): Promise<CommitTurnResult> {
|
|
212
|
+
if (!this.cfg.autoCapture) return { status: "committed" }
|
|
213
|
+
|
|
214
|
+
// messages spans exactly the admitted user entry through the terminal
|
|
215
|
+
// entry, so the whole payload is the current turn.
|
|
216
|
+
const turn = selectCaptureTurn(params.messages, this.cfg.captureMinChars)
|
|
217
|
+
if (!turn || isHousekeepingTurn(params.isHeartbeat, turn)) {
|
|
218
|
+
return { status: "committed" }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
log.debug(
|
|
222
|
+
`context-engine commitTurn: session=${params.sessionId} user=${turn.userText.length} assistant=${turn.assistantText.length}`,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
const status = await this.client.indexConversation(
|
|
226
|
+
turn.userText,
|
|
227
|
+
turn.assistantText,
|
|
228
|
+
{ turnKey: params.advancementKey },
|
|
229
|
+
)
|
|
230
|
+
return { status }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Capture fallback for hosts that predate commitTurn().
|
|
235
|
+
*
|
|
236
|
+
* Hosts that route a turn through commitTurn() skip afterTurn() for that
|
|
237
|
+
* turn, so the two paths never record the same exchange.
|
|
238
|
+
*/
|
|
174
239
|
async afterTurn(params: AfterTurnParams): Promise<void> {
|
|
175
240
|
if (!this.cfg.autoCapture) return
|
|
176
241
|
|
|
@@ -179,7 +244,7 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
179
244
|
selectCaptureTurn(newMessages, this.cfg.captureMinChars) ??
|
|
180
245
|
selectCaptureTurn(params.messages, this.cfg.captureMinChars)
|
|
181
246
|
|
|
182
|
-
if (!turn) return
|
|
247
|
+
if (!turn || isHousekeepingTurn(params.isHeartbeat, turn)) return
|
|
183
248
|
|
|
184
249
|
log.debug(
|
|
185
250
|
`context-engine afterTurn: session=${params.sessionId} user=${turn.userText.length} assistant=${turn.assistantText.length}`,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core"
|
|
2
|
+
|
|
3
|
+
// OpenClaw 2026.10 dropped the bare "openclaw/plugin-sdk" entry point that used
|
|
4
|
+
// to export ContextEngine and its result types. Derive them from the public
|
|
5
|
+
// registerContextEngine signature so we depend only on plugin-sdk/core.
|
|
6
|
+
type ContextEngineFactory = Parameters<
|
|
7
|
+
OpenClawPluginApi["registerContextEngine"]
|
|
8
|
+
>[1]
|
|
9
|
+
|
|
10
|
+
export type ContextEngine = Awaited<ReturnType<ContextEngineFactory>>
|
|
11
|
+
export type AssembleResult = Awaited<ReturnType<ContextEngine["assemble"]>>
|
|
12
|
+
export type BootstrapResult = Awaited<
|
|
13
|
+
ReturnType<NonNullable<ContextEngine["bootstrap"]>>
|
|
14
|
+
>
|
|
15
|
+
export type CompactResult = Awaited<ReturnType<ContextEngine["compact"]>>
|
|
16
|
+
export type SubagentSpawnPreparation = NonNullable<
|
|
17
|
+
Awaited<ReturnType<NonNullable<ContextEngine["prepareSubagentSpawn"]>>>
|
|
18
|
+
>
|
|
19
|
+
export type CommitTurnResult = Awaited<
|
|
20
|
+
ReturnType<NonNullable<ContextEngine["commitTurn"]>>
|
|
21
|
+
>
|
package/dist/bm-client.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
export declare class NoteAlreadyExistsError extends Error {
|
|
2
2
|
readonly permalink: string;
|
|
3
|
-
constructor(title: string, permalink: string);
|
|
3
|
+
constructor(title: string, permalink: string, message?: string);
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* bm_write refused a conditional overwrite: the note is no longer the
|
|
7
7
|
* revision named by expected_checksum. Nothing was written; currentChecksum is
|
|
8
|
-
*
|
|
8
|
+
* available revision when supplied by a server. A null value means unknown;
|
|
9
|
+
* 1.0 puts revision details in the refusal message, not a checksum field.
|
|
9
10
|
*/
|
|
10
11
|
export declare class NoteRevisionConflictError extends Error {
|
|
11
12
|
readonly permalink: string | null;
|
|
12
13
|
readonly currentChecksum: string | null;
|
|
13
|
-
constructor(title: string, permalink: string | null, currentChecksum: string | null);
|
|
14
|
+
constructor(title: string, permalink: string | null, currentChecksum: string | null, message?: string);
|
|
14
15
|
}
|
|
15
16
|
/** A BM MCP tool returned isError; toolMessage is the tool's own error text. */
|
|
16
17
|
export declare class BmToolError extends Error {
|
|
@@ -24,7 +25,14 @@ export interface SearchResult {
|
|
|
24
25
|
content: string;
|
|
25
26
|
score?: number;
|
|
26
27
|
file_path: string;
|
|
28
|
+
matched_chunk?: string | null;
|
|
27
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The text to preview for a search hit. `content` is the start of the note,
|
|
32
|
+
* so for a long note (a day of captured conversation) the matching part can
|
|
33
|
+
* sit far below any preview cut-off; the matched chunk is the part that hit.
|
|
34
|
+
*/
|
|
35
|
+
export declare function searchResultText(result: SearchResult): string;
|
|
28
36
|
export interface NoteResult {
|
|
29
37
|
title: string;
|
|
30
38
|
permalink: string;
|
|
@@ -38,7 +46,7 @@ export interface EditNoteResult {
|
|
|
38
46
|
title: string;
|
|
39
47
|
permalink: string;
|
|
40
48
|
file_path: string;
|
|
41
|
-
operation:
|
|
49
|
+
operation: EditOperation;
|
|
42
50
|
checksum?: string | null;
|
|
43
51
|
}
|
|
44
52
|
interface ReadNoteOptions {
|
|
@@ -55,6 +63,7 @@ interface WriteNoteOptions {
|
|
|
55
63
|
/** Checksum of the revision read; overwrite only while it is still current. */
|
|
56
64
|
expectedChecksum?: string;
|
|
57
65
|
}
|
|
66
|
+
export type EditOperation = "append" | "prepend" | "find_replace" | "replace_section" | "insert_before_section" | "insert_after_section";
|
|
58
67
|
interface EditNoteOptions {
|
|
59
68
|
find_text?: string;
|
|
60
69
|
section?: string;
|
|
@@ -74,7 +83,8 @@ export interface ContextResult {
|
|
|
74
83
|
permalink: string;
|
|
75
84
|
relation_type?: string;
|
|
76
85
|
from_entity?: string;
|
|
77
|
-
to_entity?: string;
|
|
86
|
+
to_entity?: string | null;
|
|
87
|
+
to_name?: string | null;
|
|
78
88
|
}>;
|
|
79
89
|
}>;
|
|
80
90
|
}
|
|
@@ -102,10 +112,7 @@ export interface ProjectListResult {
|
|
|
102
112
|
export interface WorkspaceResult {
|
|
103
113
|
tenant_id: string;
|
|
104
114
|
name: string;
|
|
105
|
-
workspace_type: string;
|
|
106
|
-
role: string;
|
|
107
|
-
organization_id?: string | null;
|
|
108
|
-
has_active_subscription: boolean;
|
|
115
|
+
workspace_type: string | null;
|
|
109
116
|
}
|
|
110
117
|
export interface SchemaValidationResult {
|
|
111
118
|
entity_type: string | null;
|
|
@@ -156,21 +163,49 @@ export interface SchemaDiffResult {
|
|
|
156
163
|
}>;
|
|
157
164
|
cardinality_changes: string[];
|
|
158
165
|
}
|
|
166
|
+
export declare function isNoteNotFoundError(err: unknown): boolean;
|
|
167
|
+
export type ConversationCaptureStatus = "committed" | "duplicate";
|
|
168
|
+
/**
|
|
169
|
+
* The server's own explanation of a failed tool call, for showing to an agent.
|
|
170
|
+
* A refusal payload becomes "CODE: message"; other tool text passes through.
|
|
171
|
+
*/
|
|
172
|
+
export declare function describeToolError(err: unknown): string;
|
|
173
|
+
/** describeToolError, but saying plainly when the note does not exist. */
|
|
174
|
+
export declare function describeNoteError(err: unknown): string;
|
|
159
175
|
export declare class BmClient {
|
|
160
176
|
private bmPath;
|
|
161
177
|
private project;
|
|
162
178
|
private cwd?;
|
|
163
179
|
private env?;
|
|
164
180
|
private shouldRun;
|
|
181
|
+
private serviceRunning;
|
|
182
|
+
private startup;
|
|
183
|
+
private startupRetry;
|
|
184
|
+
private projectPath?;
|
|
185
|
+
private prepare?;
|
|
165
186
|
private client;
|
|
166
187
|
private transport;
|
|
167
188
|
private connectPromise;
|
|
168
189
|
private retryDelaysMs;
|
|
190
|
+
private conversationWrites;
|
|
169
191
|
constructor(bmPath: string, project: string);
|
|
192
|
+
/**
|
|
193
|
+
* Connect to BM and create the plugin's project.
|
|
194
|
+
*
|
|
195
|
+
* Returns the startup promise; callers that must not block (the plugin
|
|
196
|
+
* service, which OpenClaw gives only a few seconds) can leave it running.
|
|
197
|
+
* Tool calls made meanwhile wait for it. If it fails, the next tool call
|
|
198
|
+
* runs it again, so a transient failure does not leave the plugin dead.
|
|
199
|
+
*/
|
|
170
200
|
start(options?: {
|
|
171
201
|
cwd?: string;
|
|
172
202
|
env?: Record<string, string>;
|
|
203
|
+
projectPath?: string;
|
|
204
|
+
prepare?: () => Promise<void>;
|
|
173
205
|
}): Promise<void>;
|
|
206
|
+
private runStartup;
|
|
207
|
+
private waitForStartup;
|
|
208
|
+
isServiceRunning(): boolean;
|
|
174
209
|
stop(): Promise<void>;
|
|
175
210
|
private connectWithRetries;
|
|
176
211
|
private ensureConnected;
|
|
@@ -179,9 +214,11 @@ export declare class BmClient {
|
|
|
179
214
|
private disconnectCurrent;
|
|
180
215
|
private callToolRaw;
|
|
181
216
|
private callTool;
|
|
217
|
+
private callStructured;
|
|
182
218
|
private routedProject;
|
|
183
219
|
private routing;
|
|
184
220
|
ensureProject(projectPath: string): Promise<void>;
|
|
221
|
+
private createProject;
|
|
185
222
|
listWorkspaces(): Promise<WorkspaceResult[]>;
|
|
186
223
|
listProjects(workspace?: string): Promise<ProjectListResult[]>;
|
|
187
224
|
search(query?: string, limit?: number, project?: string, metadata?: {
|
|
@@ -195,7 +232,7 @@ export declare class BmClient {
|
|
|
195
232
|
writeNote(title: string, content: string, folder: string, project?: string, overwrite?: boolean, options?: WriteNoteOptions): Promise<NoteResult>;
|
|
196
233
|
buildContext(url: string, depth?: number, project?: string): Promise<ContextResult>;
|
|
197
234
|
recentActivity(timeframe?: string, project?: string): Promise<RecentResult[]>;
|
|
198
|
-
editNote(identifier: string, operation:
|
|
235
|
+
editNote(identifier: string, operation: EditOperation, content: string, options?: EditNoteOptions, project?: string): Promise<EditNoteResult>;
|
|
199
236
|
deleteNote(identifier: string, project?: string): Promise<{
|
|
200
237
|
title: string;
|
|
201
238
|
permalink: string;
|
|
@@ -205,7 +242,19 @@ export declare class BmClient {
|
|
|
205
242
|
schemaValidate(noteType?: string, identifier?: string, project?: string): Promise<SchemaValidationResult>;
|
|
206
243
|
schemaInfer(noteType: string, threshold?: number, project?: string): Promise<SchemaInferResult>;
|
|
207
244
|
schemaDiff(noteType: string, project?: string): Promise<SchemaDiffResult>;
|
|
208
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Append one user/assistant exchange to today's conversation note.
|
|
247
|
+
*
|
|
248
|
+
* With a turnKey the capture is idempotent: the entry carries a marker
|
|
249
|
+
* derived from the key, and a key already present in today's or
|
|
250
|
+
* yesterday's note is reported as a duplicate instead of written again.
|
|
251
|
+
* Yesterday is checked because a host retry can cross midnight.
|
|
252
|
+
*/
|
|
253
|
+
indexConversation(userMessage: string, assistantResponse: string, options?: {
|
|
254
|
+
turnKey?: string;
|
|
255
|
+
}): Promise<ConversationCaptureStatus>;
|
|
256
|
+
private writeConversationEntry;
|
|
257
|
+
private noteContains;
|
|
209
258
|
getProject(): string;
|
|
210
259
|
}
|
|
211
260
|
export {};
|