@oharness/engine 0.4.0 → 0.5.1

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 (117) hide show
  1. package/dist/agent/agent.d.ts +63 -0
  2. package/dist/agent/agent.js +257 -7
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/memory-backup.d.ts +38 -0
  5. package/dist/agent/memory-backup.js +126 -0
  6. package/dist/agent/memory-backup.js.map +1 -0
  7. package/dist/agent/memory-consolidate.d.ts +47 -0
  8. package/dist/agent/memory-consolidate.js +118 -0
  9. package/dist/agent/memory-consolidate.js.map +1 -0
  10. package/dist/agent/memory-errors.d.ts +73 -0
  11. package/dist/agent/memory-errors.js +74 -0
  12. package/dist/agent/memory-errors.js.map +1 -0
  13. package/dist/agent/memory-extract.d.ts +36 -0
  14. package/dist/agent/memory-extract.js +169 -0
  15. package/dist/agent/memory-extract.js.map +1 -0
  16. package/dist/agent/memory-limits.d.ts +115 -0
  17. package/dist/agent/memory-limits.js +109 -0
  18. package/dist/agent/memory-limits.js.map +1 -0
  19. package/dist/agent/memory-links.d.ts +21 -0
  20. package/dist/agent/memory-links.js +45 -0
  21. package/dist/agent/memory-links.js.map +1 -0
  22. package/dist/agent/memory-merge.d.ts +34 -0
  23. package/dist/agent/memory-merge.js +152 -0
  24. package/dist/agent/memory-merge.js.map +1 -0
  25. package/dist/agent/memory-provider.d.ts +73 -0
  26. package/dist/agent/memory-provider.js +2 -0
  27. package/dist/agent/memory-provider.js.map +1 -0
  28. package/dist/agent/memory-recall.d.ts +72 -0
  29. package/dist/agent/memory-recall.js +192 -0
  30. package/dist/agent/memory-recall.js.map +1 -0
  31. package/dist/agent/memory-redact.d.ts +15 -0
  32. package/dist/agent/memory-redact.js +48 -0
  33. package/dist/agent/memory-redact.js.map +1 -0
  34. package/dist/agent/memory-review.d.ts +47 -0
  35. package/dist/agent/memory-review.js +127 -0
  36. package/dist/agent/memory-review.js.map +1 -0
  37. package/dist/agent/memory-usage.d.ts +24 -0
  38. package/dist/agent/memory-usage.js +68 -0
  39. package/dist/agent/memory-usage.js.map +1 -0
  40. package/dist/agent/memory.d.ts +137 -14
  41. package/dist/agent/memory.js +431 -130
  42. package/dist/agent/memory.js.map +1 -1
  43. package/dist/agent/permissions.d.ts +10 -2
  44. package/dist/agent/permissions.js +22 -3
  45. package/dist/agent/permissions.js.map +1 -1
  46. package/dist/agent/session.d.ts +8 -1
  47. package/dist/agent/session.js +9 -0
  48. package/dist/agent/session.js.map +1 -1
  49. package/dist/agent/store.d.ts +3 -0
  50. package/dist/agent/store.js.map +1 -1
  51. package/dist/agent/titles.js +2 -2
  52. package/dist/auth/providers/official.d.ts +13 -0
  53. package/dist/auth/providers/official.js +38 -3
  54. package/dist/auth/providers/official.js.map +1 -1
  55. package/dist/config.d.ts +20 -1
  56. package/dist/config.js +31 -1
  57. package/dist/config.js.map +1 -1
  58. package/dist/core/audit.d.ts +19 -0
  59. package/dist/core/types.d.ts +6 -0
  60. package/dist/core/types.js +12 -0
  61. package/dist/core/types.js.map +1 -1
  62. package/dist/harness.d.ts +7 -1
  63. package/dist/harness.js +33 -2
  64. package/dist/harness.js.map +1 -1
  65. package/dist/providers/builtin.d.ts +20 -0
  66. package/dist/providers/builtin.js +82 -0
  67. package/dist/providers/builtin.js.map +1 -1
  68. package/dist/providers/catalog.js +30 -3
  69. package/dist/providers/catalog.js.map +1 -1
  70. package/dist/providers/index.d.ts +2 -2
  71. package/dist/providers/index.js +1 -1
  72. package/dist/providers/index.js.map +1 -1
  73. package/dist/providers/piai.js +17 -8
  74. package/dist/providers/piai.js.map +1 -1
  75. package/dist/providers/registry.d.ts +5 -0
  76. package/dist/providers/registry.js +10 -2
  77. package/dist/providers/registry.js.map +1 -1
  78. package/dist/providers/types.d.ts +31 -0
  79. package/dist/providers/types.js +36 -0
  80. package/dist/providers/types.js.map +1 -1
  81. package/dist/runtime-plugins/builtin/memory-coordinator.d.ts +79 -0
  82. package/dist/runtime-plugins/builtin/memory-coordinator.js +169 -0
  83. package/dist/runtime-plugins/builtin/memory-coordinator.js.map +1 -0
  84. package/dist/runtime-plugins/builtin/memory-migrate.d.ts +35 -0
  85. package/dist/runtime-plugins/builtin/memory-migrate.js +141 -0
  86. package/dist/runtime-plugins/builtin/memory-migrate.js.map +1 -0
  87. package/dist/runtime-plugins/builtin/memory.d.ts +144 -5
  88. package/dist/runtime-plugins/builtin/memory.js +1016 -112
  89. package/dist/runtime-plugins/builtin/memory.js.map +1 -1
  90. package/dist/runtime-plugins/builtin/studio.js +21 -4
  91. package/dist/runtime-plugins/builtin/studio.js.map +1 -1
  92. package/dist/runtime-plugins/cloud-connector.js +4 -1
  93. package/dist/runtime-plugins/cloud-connector.js.map +1 -1
  94. package/dist/runtime-plugins/extensions.d.ts +9 -0
  95. package/dist/runtime-plugins/extensions.js +15 -0
  96. package/dist/runtime-plugins/extensions.js.map +1 -1
  97. package/dist/runtime-plugins/host.js +25 -2
  98. package/dist/runtime-plugins/host.js.map +1 -1
  99. package/dist/runtime-plugins/types.d.ts +15 -0
  100. package/dist/tools/builtin/ask.d.ts +9 -0
  101. package/dist/tools/builtin/ask.js +71 -0
  102. package/dist/tools/builtin/ask.js.map +1 -0
  103. package/dist/tools/builtin/index.d.ts +1 -0
  104. package/dist/tools/builtin/index.js +3 -0
  105. package/dist/tools/builtin/index.js.map +1 -1
  106. package/dist/tools/builtin/memory.d.ts +5 -5
  107. package/dist/tools/builtin/memory.js +151 -40
  108. package/dist/tools/builtin/memory.js.map +1 -1
  109. package/dist/tools/index.d.ts +2 -0
  110. package/dist/tools/index.js +1 -0
  111. package/dist/tools/index.js.map +1 -1
  112. package/dist/tools/questions.d.ts +89 -0
  113. package/dist/tools/questions.js +97 -0
  114. package/dist/tools/questions.js.map +1 -0
  115. package/dist/tools/types.d.ts +7 -0
  116. package/dist/tools/types.js.map +1 -1
  117. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-coordinator.js","sourceRoot":"","sources":["../../../src/runtime-plugins/builtin/memory-coordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { Logger } from "../../util/logger.ts";
2
+ /**
3
+ * Where memory lives, and moving it there from where it used to.
4
+ *
5
+ * Notes used to sit in `<project>/.oharness/memory`, inside the repository
6
+ * tree: one copy per clone and per worktree, one `git add .` away from being
7
+ * committed for everyone, and gone with the folder. They now sit under the
8
+ * user directory, keyed by the same project id that sessions and cloud sync
9
+ * already use, so every clone of a repository shares one set.
10
+ */
11
+ /** Written into a project's notes directory once its old notes have been considered. */
12
+ export declare const LEGACY_MARKER = ".imported-legacy.json";
13
+ export interface MemoryDirectories {
14
+ project: string;
15
+ /** Absent when the user directory is not writable. */
16
+ user?: string;
17
+ /** Notes copied from the old location on this start. */
18
+ migrated: number;
19
+ }
20
+ export declare function legacyMemoryDirectory(cwd: string): string;
21
+ export declare function resolveMemoryDirectories(options: {
22
+ cwd: string;
23
+ /** A directory the user configured; used as is, with nothing migrated into it. */
24
+ configured?: string;
25
+ logger?: Logger;
26
+ }): Promise<MemoryDirectories>;
27
+ /**
28
+ * Copy notes from the old directory into the new one, once.
29
+ *
30
+ * Only into an empty directory: merging two sets of notes is sync's job, with
31
+ * its conflict handling, not a startup step's. The marker makes it once — a
32
+ * note someone later deletes in the new place must not return from the old
33
+ * one on the next launch. The old directory is left untouched.
34
+ */
35
+ export declare function importLegacyMemory(legacy: string, target: string): Promise<number>;
@@ -0,0 +1,141 @@
1
+ import { constants } from "node:fs";
2
+ import { copyFile, lstat, mkdir, readdir, stat, writeFile } from "node:fs/promises";
3
+ import { createHash } from "node:crypto";
4
+ import path from "node:path";
5
+ import { readPluginFile, readUserFile, updateRuntimePluginConfig, writeUserFile } from "../../config-files.js";
6
+ import { userPath } from "../../paths.js";
7
+ import { projectId } from "../../storage/project.js";
8
+ /**
9
+ * Where memory lives, and moving it there from where it used to.
10
+ *
11
+ * Notes used to sit in `<project>/.oharness/memory`, inside the repository
12
+ * tree: one copy per clone and per worktree, one `git add .` away from being
13
+ * committed for everyone, and gone with the folder. They now sit under the
14
+ * user directory, keyed by the same project id that sessions and cloud sync
15
+ * already use, so every clone of a repository shares one set.
16
+ */
17
+ /** Written into a project's notes directory once its old notes have been considered. */
18
+ export const LEGACY_MARKER = ".imported-legacy.json";
19
+ export function legacyMemoryDirectory(cwd) {
20
+ return path.join(cwd, ".oharness", "memory");
21
+ }
22
+ export async function resolveMemoryDirectories(options) {
23
+ const legacy = legacyMemoryDirectory(options.cwd);
24
+ let user = userPath("memory", "user");
25
+ try {
26
+ await mkdir(user, { recursive: true });
27
+ }
28
+ catch (error) {
29
+ options.logger?.warn("User-level memory unavailable: the user directory is not writable", { error: String(error) });
30
+ user = undefined;
31
+ }
32
+ if (options.configured) {
33
+ return { project: path.resolve(options.cwd, options.configured), ...(user ? { user } : {}), migrated: 0 };
34
+ }
35
+ const target = userPath("memory", "projects", await projectId(options.cwd));
36
+ try {
37
+ await mkdir(target, { recursive: true });
38
+ }
39
+ catch (error) {
40
+ // A container whose home is a read-only layer still has a project volume.
41
+ options.logger?.warn("Memory stays in the project folder: the user directory is not writable", { error: String(error) });
42
+ return { project: legacy, ...(user ? { user } : {}), migrated: 0 };
43
+ }
44
+ let migrated = 0;
45
+ try {
46
+ migrated = await importLegacyMemory(legacy, target);
47
+ if (migrated)
48
+ options.logger?.info("Moved memory notes into the user directory", { count: migrated, from: legacy, to: target });
49
+ }
50
+ catch (error) {
51
+ options.logger?.warn("Could not import memory notes from the project folder", { error: String(error) });
52
+ }
53
+ return { project: target, ...(user ? { user } : {}), migrated };
54
+ }
55
+ /**
56
+ * Copy notes from the old directory into the new one, once.
57
+ *
58
+ * Only into an empty directory: merging two sets of notes is sync's job, with
59
+ * its conflict handling, not a startup step's. The marker makes it once — a
60
+ * note someone later deletes in the new place must not return from the old
61
+ * one on the next launch. The old directory is left untouched.
62
+ */
63
+ export async function importLegacyMemory(legacy, target) {
64
+ const marker = path.join(target, LEGACY_MARKER);
65
+ if (await exists(marker))
66
+ return 0;
67
+ let names;
68
+ try {
69
+ if ((await lstat(legacy)).isSymbolicLink())
70
+ return 0;
71
+ names = (await readdir(legacy)).filter((name) => name.endsWith(".md"));
72
+ }
73
+ catch {
74
+ return 0;
75
+ }
76
+ if (!names.length)
77
+ return 0;
78
+ const existing = (await readdir(target)).filter((name) => name.endsWith(".md"));
79
+ if (existing.length) {
80
+ await writeFile(marker, JSON.stringify({ from: legacy, skipped: "target already had notes", at: Date.now() }) + "\n");
81
+ return 0;
82
+ }
83
+ let copied = 0;
84
+ for (const name of names) {
85
+ const from = path.join(legacy, name);
86
+ const info = await lstat(from);
87
+ if (info.isSymbolicLink() || !info.isFile())
88
+ continue;
89
+ try {
90
+ await copyFile(from, path.join(target, name), constants.COPYFILE_EXCL);
91
+ copied++;
92
+ }
93
+ catch (error) {
94
+ if (error.code !== "EEXIST")
95
+ throw error;
96
+ }
97
+ }
98
+ await carrySyncSettings(legacy, target);
99
+ await writeFile(marker, JSON.stringify({ from: legacy, copied, at: Date.now() }) + "\n");
100
+ return copied;
101
+ }
102
+ const digest = (value) => createHash("sha256").update(value).digest("hex");
103
+ const object = (x) => !!x && typeof x === "object" && !Array.isArray(x);
104
+ /**
105
+ * Sync consent is keyed by directory. Without carrying it, a person who had
106
+ * switched cloud sync off for the old directory would find it silently on for
107
+ * the new one — the one outcome of a migration that cannot be undone, since
108
+ * an upload cannot be recalled. The baseline goes with it, so the first sync
109
+ * afterwards reconciles rather than treating every note as new.
110
+ */
111
+ async function carrySyncSettings(legacy, target) {
112
+ const from = digest(path.resolve(legacy));
113
+ const to = digest(path.resolve(target));
114
+ const config = readPluginFile()?.runtimePlugins?.find((plugin) => plugin.id === "memory")?.config;
115
+ const consent = object(config) && object(config.syncTargets) ? config.syncTargets[from] : undefined;
116
+ if (!object(consent))
117
+ return;
118
+ await updateRuntimePluginConfig("memory", (current) => {
119
+ const targets = object(current.syncTargets) ? current.syncTargets : {};
120
+ if (targets[to])
121
+ return current;
122
+ return { ...current, syncTargets: { ...targets, [to]: consent } };
123
+ });
124
+ if (typeof consent.userId === "string" && consent.userId && typeof consent.origin === "string") {
125
+ const oldState = `memory-sync/${digest(`${consent.origin}:${consent.userId}:${from}`)}.json`;
126
+ const newState = `memory-sync/${digest(`${consent.origin}:${consent.userId}:${to}`)}.json`;
127
+ const state = readUserFile(oldState);
128
+ if (state && !readUserFile(newState))
129
+ await writeUserFile(newState, state);
130
+ }
131
+ }
132
+ async function exists(file) {
133
+ try {
134
+ await stat(file);
135
+ return true;
136
+ }
137
+ catch {
138
+ return false;
139
+ }
140
+ }
141
+ //# sourceMappingURL=memory-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-migrate.js","sourceRoot":"","sources":["../../../src/runtime-plugins/builtin/memory-migrate.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,64 @@
1
1
  import { MemoryStore } from "../../agent/memory.ts";
2
- import type { MemoryNote } from "../../agent/memory.ts";
2
+ import type { MemoryNote, MemoryStores } from "../../agent/memory.ts";
3
+ import type { MemoryPolicy, MemoryScope } from "../../agent/memory-limits.ts";
4
+ import type { BackupReason } from "../../agent/memory-backup.ts";
5
+ import type { MemoryFailureInfo } from "../../agent/memory-errors.ts";
6
+ import type { MergeField } from "../../agent/memory-merge.ts";
7
+ import type { ExtractedNote, ExtractionResult } from "../../agent/memory-provider.ts";
3
8
  import type { RuntimePlugin } from "../types.ts";
9
+ import { MemorySyncCoordinator } from "./memory-coordinator.ts";
4
10
  type Identity = {
5
11
  userId: string;
6
12
  origin: string;
7
13
  };
14
+ /** What the sync server says it will accept, for this account. Announced by the server; never assumed here. */
15
+ export interface SyncQuota {
16
+ maxNotes?: number;
17
+ maxChanges?: number;
18
+ maxNoteBytes?: number;
19
+ tombstoneDays?: number;
20
+ tier?: "free" | "paid";
21
+ }
22
+ type NoteRef = {
23
+ id: string;
24
+ summary: string;
25
+ };
26
+ /** What the last pass that brought anything down brought down, and which notes it merged on its own. */
27
+ export interface PullSummary {
28
+ at: number;
29
+ created: NoteRef[];
30
+ updated: NoteRef[];
31
+ deleted: NoteRef[];
32
+ merged?: NoteRef[];
33
+ }
8
34
  interface Options {
9
35
  cwd: string;
10
36
  directory: string;
37
+ /** Which notes this service holds. User-level notes belong to no project. */
38
+ scope?: MemoryScope;
39
+ policy?: MemoryPolicy;
40
+ onWarning?(message: string): void;
11
41
  identity(): Promise<Identity | undefined>;
12
42
  token(): Promise<string | undefined>;
13
43
  /** Same destination as session sync. The Cloud identity origin remains the consent pin. */
14
44
  syncUrl?(): string;
15
45
  fetch?: typeof fetch;
46
+ /** Background check interval while the directory is busy. Defaults to a minute. */
16
47
  pollMs?: number;
48
+ /** Longest a quiet directory waits between checks. Defaults to five times `pollMs`. */
49
+ maxPollMs?: number;
50
+ /** Delay between a local write and the pass that uploads it. */
51
+ debounceMs?: number;
52
+ /** A project directory unused for this long is not checked in the background. */
53
+ activeWindowMs?: number;
54
+ /** Defaults to the process's shared coordinator. */
55
+ coordinator?: MemorySyncCoordinator;
56
+ }
57
+ export interface MemoryPluginOptions extends Omit<Options, "scope"> {
58
+ /** User-level notes directory. Omitted when it could not be created. */
59
+ userDirectory?: string;
60
+ /** One reply from the small model, for merge proposals. Without it merges are drafted by hand. */
61
+ generate?(system: string, prompt: string, signal?: AbortSignal): Promise<string>;
17
62
  }
18
63
  type Conflict = {
19
64
  id: string;
@@ -21,50 +66,144 @@ type Conflict = {
21
66
  cloud: MemoryNote | null;
22
67
  localHash: string | null;
23
68
  cloudHash: string | null;
69
+ /** The version both sides started from, when this machine kept a copy of it. */
70
+ base: MemoryNote | null;
71
+ /** What both sides changed in ways that could not be combined. */
72
+ fields: MergeField[];
24
73
  };
25
- /** One project's local notes and explicit per-device/account sync consent. */
74
+ /** One scope's local notes and explicit per-device/account sync consent. */
26
75
  export declare class MemoryService {
27
76
  readonly store: MemoryStore;
77
+ readonly scope: MemoryScope;
28
78
  private readonly options;
29
79
  private readonly target;
80
+ private readonly coordinator;
81
+ private readonly syncTarget;
82
+ private detach?;
30
83
  private controller?;
31
- private timer?;
32
84
  private running?;
33
85
  private closed;
34
86
  private disabling;
35
87
  private conflicts;
36
88
  private error?;
37
89
  private lastSync?;
90
+ private lastPull?;
91
+ private lastChanged;
38
92
  private binding?;
39
93
  private settingsRevision;
40
94
  private retryAt;
41
95
  private snapshotCache?;
96
+ private quota?;
97
+ /** The server predates `have`, so every snapshot carries every note. */
98
+ private legacyServer;
42
99
  constructor(options: Options);
100
+ get isClosed(): boolean;
43
101
  private consent;
44
102
  private stateFile;
45
103
  private allowed;
104
+ private eligible;
105
+ /**
106
+ * Hand this directory to the coordinator. It is checked straight away, then
107
+ * as the coordinator decides; a local write brings the next check forward.
108
+ * Calling it again does nothing.
109
+ */
46
110
  start(): void;
111
+ /** These notes are in use: check the cloud soon, if it has been a while. */
112
+ activity(): void;
47
113
  status(): Promise<{
114
+ lastPull?: PullSummary | undefined;
115
+ quota?: SyncQuota | undefined;
116
+ scope: "user" | "project";
48
117
  signedIn: boolean;
49
118
  enabled: boolean;
50
119
  ready: boolean;
51
120
  syncing: boolean;
52
121
  lastSync: number | undefined;
53
122
  error: string | undefined;
123
+ failure: MemoryFailureInfo | undefined;
54
124
  accountChanged: boolean;
55
125
  conflicts: Conflict[];
56
126
  location: string;
57
127
  entries: (MemoryNote & {
58
128
  hash: string | null;
59
129
  })[];
130
+ omitted: number;
60
131
  }>;
61
132
  enable(enabled: boolean): Promise<void>;
62
133
  sync(): Promise<void>;
134
+ /**
135
+ * One reconciliation. Resolves with whether anything went up or came down.
136
+ *
137
+ * A note both sides changed since the last sync is merged field by field
138
+ * when the changes do not touch (memory-merge.ts), and held back as a
139
+ * conflict only when they do. A held note stops nothing else: every other
140
+ * note still goes up and comes down, and the held one keeps its baseline
141
+ * until someone chooses.
142
+ */
63
143
  private perform;
64
- resolve(id: string, choice: string): Promise<void>;
144
+ /** Where copies of notes at their baseline are kept, beside the baseline file. */
145
+ private baseDir;
146
+ /** The last synced version of a note, only when it is exactly the one the baseline records. */
147
+ private readBase;
148
+ private writeBaseNote;
149
+ /** Keep the baseline copies in step with the baseline hashes, writing only what moved. */
150
+ private writeBases;
151
+ /**
152
+ * Write a batch cloud first, for changes made without anyone reviewing each
153
+ * note (consolidation).
154
+ *
155
+ * Every note in the batch must be fully in sync, the same here, in the cloud
156
+ * and in the baseline, or the batch is refused before anything is written.
157
+ * The commit carries the manifest version those checks read, so a change
158
+ * from another device in between is refused by the server rather than
159
+ * becoming a conflict. Only once the cloud has accepted the batch is it
160
+ * written here. It needs the network; there is no offline fallback.
161
+ */
162
+ commitFirst(edits: ReadonlyArray<{
163
+ id: string;
164
+ note?: MemoryNote;
165
+ expectedHash: string | null;
166
+ }>, reason: BackupReason): Promise<void>;
167
+ /**
168
+ * Whether changes here should go through the cloud first: sync is on and
169
+ * bound to the account signed in now. Otherwise they are ordinary local
170
+ * edits that a later sync uploads.
171
+ */
172
+ syncReady(): Promise<boolean>;
173
+ /** The plan the sync service last announced for this account, if any. */
174
+ get tier(): SyncQuota["tier"];
175
+ /** Largest note body this machine and the sync service will both accept. */
176
+ noteBytesLimit(): number;
177
+ /** Changes grouped to fit the server's announced change quota and a request size its body limit accepts. */
178
+ private batches;
179
+ private snapshot;
180
+ private commit;
181
+ /** A request carrying `have`, retried without it once against a server that predates the field. */
182
+ private call;
183
+ /**
184
+ * Settle a conflict. Whatever is set aside is backed up first, whichever side
185
+ * it came from, and the baseline moves to the cloud's version so the next
186
+ * sync uploads the outcome.
187
+ *
188
+ * `local` keeps this machine's version. `cloud` takes the cloud's. `both`
189
+ * keeps this machine's version under the note's id and the cloud's as a new
190
+ * note beside it. `manual` saves `merged`, written by a person from all three.
191
+ */
192
+ resolve(id: string, choice: string, merged?: Record<string, unknown>): Promise<void>;
193
+ private readQuota;
65
194
  private validateSnapshot;
66
195
  private request;
67
196
  close(): Promise<void>;
68
197
  }
69
- export declare function createMemoryPlugin(options: Options, onReady: (service: MemoryService) => void): RuntimePlugin;
198
+ export declare function acquireMemoryService(options: Options): {
199
+ service: MemoryService;
200
+ release(): Promise<void>;
201
+ };
202
+ /**
203
+ * Write what an extraction pass proposed. New notes first, so every
204
+ * `[[new:N]]` placeholder has an id to become; then the notes that used a
205
+ * placeholder are rewritten with it.
206
+ */
207
+ export declare function commitExtracted(stores: MemoryStores, notes: readonly ExtractedNote[]): Promise<ExtractionResult>;
208
+ export declare function createMemoryPlugin(options: MemoryPluginOptions, onReady: (service: MemoryService, user?: MemoryService) => void): RuntimePlugin;
70
209
  export {};