myagentmemory 0.4.12 → 0.4.14

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.
@@ -0,0 +1,429 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { COMMAND_DESCRIPTIONS, COMMAND_OPTIONS, COMMANDS, GLOBAL_OPTIONS, OPTION_SPECS, optionDescription, PLUGIN_COMMAND_DESCRIPTIONS, PLUGIN_COMMAND_OPTIONS, PLUGIN_COMMANDS, SCRATCHPAD_ACTION_DESCRIPTIONS, SCRATCHPAD_ACTION_OPTIONS, SCRATCHPAD_ACTIONS, SHELL_DESCRIPTIONS, WORKER_ACTION_DESCRIPTIONS, WORKER_ACTION_OPTIONS, WORKER_ACTIONS, } from "./cli-spec.js";
5
+ function words(values) {
6
+ return values.join(" ");
7
+ }
8
+ function zshOptionValue(command, option) {
9
+ if (option === "--target") {
10
+ return command === "read"
11
+ ? ":target:(daily long_term scratchpad list topic topics)"
12
+ : ":target:(daily long_term topic)";
13
+ }
14
+ if (option === "--mode")
15
+ return command === "search" ? ":mode:(keyword semantic deep)" : ":mode:(append overwrite)";
16
+ if (option === "--scope")
17
+ return ":scope:(global current)";
18
+ if (option === "--host")
19
+ return command === "web" ? ":host:(127.0.0.1 localhost ::1)" : ":host:(pi codex claude)";
20
+ if (option === "--only")
21
+ return ":agent:(claude codex cursor opencode pi)";
22
+ const value = OPTION_SPECS[option]?.value;
23
+ if (value?.kind === "directory")
24
+ return `:${value.label}:_directories`;
25
+ if (value?.kind === "file")
26
+ return `:${value.label}:_files`;
27
+ if (value)
28
+ return `:${value.label}:`;
29
+ return "";
30
+ }
31
+ function zshOptionSpecs(command, options = COMMAND_OPTIONS[command] ?? []) {
32
+ return options
33
+ .map((option) => `'${option}[${optionDescription(option)}]${zshOptionValue(command, option)}'`)
34
+ .join(" ");
35
+ }
36
+ function fishOption(command, condition, option) {
37
+ const spec = OPTION_SPECS[option];
38
+ const value = spec?.value ? " -r" : "";
39
+ let suggestions = "";
40
+ if (option === "--target")
41
+ suggestions =
42
+ command === "read" ? " -a 'daily long_term scratchpad list topic topics'" : " -a 'daily long_term topic'";
43
+ else if (option === "--mode")
44
+ suggestions = command === "search" ? " -a 'keyword semantic deep'" : " -a 'append overwrite'";
45
+ else if (option === "--scope")
46
+ suggestions = " -a 'global current'";
47
+ else if (option === "--host")
48
+ suggestions = command === "web" ? " -a '127.0.0.1 localhost ::1'" : " -a 'pi codex claude'";
49
+ else if (option === "--only")
50
+ suggestions = " -a 'claude codex cursor opencode pi'";
51
+ else if (spec?.value?.kind === "directory")
52
+ suggestions = " -a '(__fish_complete_directories)'";
53
+ else if (spec?.value?.kind === "file")
54
+ suggestions = " -F";
55
+ return `complete -c agent-memory -n '${condition}' -l ${option.slice(2)}${value}${suggestions} -d '${optionDescription(option)}'`;
56
+ }
57
+ function bashCompletion() {
58
+ return `# agent-memory completion for Bash
59
+ # Installed automatically by: agent-memory completion bash
60
+ # Print this script instead with: agent-memory completion bash --stdout
61
+ _agent_memory_completion() {
62
+ local cur command sub action
63
+ COMPREPLY=()
64
+ cur="\${COMP_WORDS[COMP_CWORD]}"
65
+ command="\${COMP_WORDS[1]}"
66
+ sub="\${COMP_WORDS[2]}"
67
+ action="\${COMP_WORDS[3]}"
68
+
69
+ if [[ "$cur" == --*=* ]]; then return 0; fi
70
+ case "\${COMP_WORDS[COMP_CWORD-1]}" in
71
+ --target)
72
+ if [[ "$command" == read ]]; then COMPREPLY=( $(compgen -W "daily long_term scratchpad list topic topics" -- "$cur") );
73
+ else COMPREPLY=( $(compgen -W "daily long_term topic" -- "$cur") ); fi; return 0 ;;
74
+ --mode)
75
+ if [[ "$command" == search ]]; then COMPREPLY=( $(compgen -W "keyword semantic deep" -- "$cur") );
76
+ else COMPREPLY=( $(compgen -W "append overwrite" -- "$cur") ); fi; return 0 ;;
77
+ --scope) COMPREPLY=( $(compgen -W "global current" -- "$cur") ); return 0 ;;
78
+ --host)
79
+ if [[ "$command" == web ]]; then COMPREPLY=( $(compgen -W "127.0.0.1 localhost ::1" -- "$cur") );
80
+ else COMPREPLY=( $(compgen -W "pi codex claude" -- "$cur") ); fi; return 0 ;;
81
+ --only) COMPREPLY=( $(compgen -W "claude codex cursor opencode pi" -- "$cur") ); return 0 ;;
82
+ --dir|--cwd|--pi|--codex|--claude|--state|--journal|--candidates-dir|--decisions-dir|--auto-dir|--output)
83
+ COMPREPLY=( $(compgen -f -- "$cur") ); return 0 ;;
84
+ esac
85
+
86
+ if (( COMP_CWORD == 1 )); then
87
+ COMPREPLY=( $(compgen -W "${words(COMMANDS)}" -- "$cur") ); return 0
88
+ fi
89
+ if [[ "$command" == plugin && $COMP_CWORD -eq 2 ]]; then
90
+ COMPREPLY=( $(compgen -W "${words(PLUGIN_COMMANDS)}" -- "$cur") ); return 0
91
+ fi
92
+ if [[ "$command" == plugin && "$sub" == worker && $COMP_CWORD -eq 3 ]]; then
93
+ COMPREPLY=( $(compgen -W "${words(WORKER_ACTIONS)}" -- "$cur") ); return 0
94
+ fi
95
+ if [[ "$command" == scratchpad && $COMP_CWORD -eq 2 ]]; then
96
+ COMPREPLY=( $(compgen -W "${words(SCRATCHPAD_ACTIONS)}" -- "$cur") ); return 0
97
+ fi
98
+ if [[ "$command" == completion && $COMP_CWORD -eq 2 ]]; then
99
+ COMPREPLY=( $(compgen -W "bash zsh fish powershell" -- "$cur") ); return 0
100
+ fi
101
+ local command_options=""
102
+ if [[ "$command" == plugin ]]; then
103
+ case "$sub" in
104
+ ${Object.entries(PLUGIN_COMMAND_OPTIONS)
105
+ .map(([command, options]) => ` ${command}) command_options="${words(options)}" ;;`)
106
+ .join("\n")}
107
+ esac
108
+ if [[ "$sub" == worker && -n "$action" ]]; then
109
+ case "$action" in
110
+ ${Object.entries(WORKER_ACTION_OPTIONS)
111
+ .map(([action, options]) => ` ${action}) command_options="${words(options)}" ;;`)
112
+ .join("\n")}
113
+ esac
114
+ fi
115
+ elif [[ "$command" == scratchpad && -n "$sub" ]]; then
116
+ case "$sub" in
117
+ ${Object.entries(SCRATCHPAD_ACTION_OPTIONS)
118
+ .map(([action, options]) => ` ${action}) command_options="${words(options)}" ;;`)
119
+ .join("\n")}
120
+ esac
121
+ else
122
+ case "$command" in
123
+ ${Object.entries(COMMAND_OPTIONS)
124
+ .map(([command, options]) => ` ${command}) command_options="${words(options)}" ;;`)
125
+ .join("\n")}
126
+ esac
127
+ fi
128
+ COMPREPLY=( $(compgen -W "${words(GLOBAL_OPTIONS)} $command_options" -- "$cur") )
129
+ }
130
+ complete -F _agent_memory_completion agent-memory
131
+ `;
132
+ }
133
+ function zshCompletion() {
134
+ return `#compdef agent-memory
135
+ # agent-memory completion for Zsh
136
+ # Installed automatically by: agent-memory completion zsh
137
+ # Print this script instead with: agent-memory completion zsh --stdout
138
+ _agent-memory() {
139
+ local -a commands plugin_commands worker_actions scratchpad_actions shells
140
+ local command="$words[2]"
141
+ local subcommand="$words[3]"
142
+ local action="$words[4]"
143
+ local command_position=$CURRENT
144
+ commands=(${COMMANDS.map((command) => `'${command}:${COMMAND_DESCRIPTIONS[command] ?? command}'`).join(" ")})
145
+ plugin_commands=(${PLUGIN_COMMANDS.map((command) => `'${command}:${PLUGIN_COMMAND_DESCRIPTIONS[command]}'`).join(" ")})
146
+ worker_actions=(${WORKER_ACTIONS.map((action) => `'${action}:${WORKER_ACTION_DESCRIPTIONS[action]}'`).join(" ")})
147
+ scratchpad_actions=(${SCRATCHPAD_ACTIONS.map((action) => `'${action}:${SCRATCHPAD_ACTION_DESCRIPTIONS[action]}'`).join(" ")})
148
+ shells=(${Object.entries(SHELL_DESCRIPTIONS)
149
+ .map(([shell, description]) => `'${shell}:${description}'`)
150
+ .join(" ")})
151
+
152
+ _arguments -C \\
153
+ '(-h --help)'{-h,--help}'[show help]' \\
154
+ '(-V --version)'{-V,--version}'[show version]' \\
155
+ '--json[emit structured JSON]' \\
156
+ '--dir[memory directory]:directory:_directories' \\
157
+ '1:command:->command' \\
158
+ '*::argument:->args'
159
+
160
+ case $state in
161
+ command) _describe 'command' commands ;;
162
+ args)
163
+ case $command in
164
+ plugin)
165
+ if (( command_position == 3 )); then _describe 'plugin command' plugin_commands
166
+ elif [[ "$subcommand" == worker ]] && (( command_position == 4 )); then _describe 'worker action' worker_actions
167
+ else
168
+ if [[ "$subcommand" == worker && -n "$action" ]]; then
169
+ case "$action" in
170
+ ${Object.entries(WORKER_ACTION_OPTIONS)
171
+ .map(([action, options]) => ` ${action}) _arguments ${zshOptionSpecs(`plugin:worker:${action}`, options)} ;;`)
172
+ .join("\n")}
173
+ esac
174
+ else
175
+ case "$subcommand" in
176
+ ${Object.entries(PLUGIN_COMMAND_OPTIONS)
177
+ .map(([command, options]) => ` ${command}) _arguments ${zshOptionSpecs(`plugin:${command}`, options)} ;;`)
178
+ .join("\n")}
179
+ esac
180
+ fi
181
+ fi ;;
182
+ scratchpad)
183
+ if (( command_position == 3 )); then _describe 'action' scratchpad_actions
184
+ else
185
+ case "$subcommand" in
186
+ ${Object.entries(SCRATCHPAD_ACTION_OPTIONS)
187
+ .map(([action, options]) => ` ${action}) _arguments ${zshOptionSpecs("scratchpad", options)} ;;`)
188
+ .join("\n")}
189
+ esac
190
+ fi ;;
191
+ completion)
192
+ if (( command_position == 3 )); then _describe 'shell' shells
193
+ else _arguments ${zshOptionSpecs("completion")}; fi ;;
194
+ ${Object.keys(COMMAND_OPTIONS)
195
+ .filter((command) => command !== "plugin" && command !== "scratchpad" && command !== "completion")
196
+ .map((command) => ` ${command}) _arguments ${zshOptionSpecs(command)} ;;`)
197
+ .join("\n")}
198
+ *) _arguments ;;
199
+ esac ;;
200
+ esac
201
+ }
202
+ compdef _agent-memory agent-memory
203
+ `;
204
+ }
205
+ function fishCompletion() {
206
+ const lines = [
207
+ "# agent-memory completion for Fish",
208
+ "# Installed automatically by: agent-memory completion fish",
209
+ "# Print this script instead with: agent-memory completion fish --stdout",
210
+ "complete -c agent-memory -f",
211
+ ...COMMANDS.map((command) => `complete -c agent-memory -n '__fish_use_subcommand' -a '${command}' -d '${COMMAND_DESCRIPTIONS[command] ?? command}'`),
212
+ ...PLUGIN_COMMANDS.map((command) => `complete -c agent-memory -n '__fish_seen_subcommand_from plugin; and not __fish_seen_subcommand_from ${words(PLUGIN_COMMANDS)}' -a '${command}' -d '${PLUGIN_COMMAND_DESCRIPTIONS[command]}'`),
213
+ ...WORKER_ACTIONS.map((action) => `complete -c agent-memory -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from worker; and not __fish_seen_subcommand_from ${words(WORKER_ACTIONS)}' -a '${action}' -d '${WORKER_ACTION_DESCRIPTIONS[action]}'`),
214
+ ...SCRATCHPAD_ACTIONS.map((action) => `complete -c agent-memory -n '__fish_seen_subcommand_from scratchpad; and not __fish_seen_subcommand_from ${words(SCRATCHPAD_ACTIONS)}' -a '${action}' -d '${SCRATCHPAD_ACTION_DESCRIPTIONS[action]}'`),
215
+ ...Object.entries(SHELL_DESCRIPTIONS).map(([shell, description]) => `complete -c agent-memory -n '__fish_seen_subcommand_from completion' -a '${shell}' -d '${description}'`),
216
+ "complete -c agent-memory -l dir -r -a '(__fish_complete_directories)' -d 'override the active memory directory'",
217
+ "complete -c agent-memory -l json -d 'emit command-specific structured JSON'",
218
+ "complete -c agent-memory -s h -l help -d 'show help for the selected command'",
219
+ "complete -c agent-memory -s V -l version -d 'print the installed version and exit'",
220
+ ];
221
+ for (const [command, options] of Object.entries(COMMAND_OPTIONS)) {
222
+ if (command === "scratchpad")
223
+ continue;
224
+ for (const option of options) {
225
+ lines.push(fishOption(command, `__fish_seen_subcommand_from ${command}`, option));
226
+ }
227
+ }
228
+ for (const [subcommand, options] of Object.entries(PLUGIN_COMMAND_OPTIONS)) {
229
+ if (subcommand === "worker")
230
+ continue;
231
+ for (const option of options) {
232
+ lines.push(fishOption(`plugin:${subcommand}`, `__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from ${subcommand}`, option));
233
+ }
234
+ }
235
+ for (const [action, options] of Object.entries(WORKER_ACTION_OPTIONS)) {
236
+ for (const option of options) {
237
+ lines.push(fishOption(`plugin:worker:${action}`, `__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from worker; and __fish_seen_subcommand_from ${action}`, option));
238
+ }
239
+ }
240
+ for (const [action, options] of Object.entries(SCRATCHPAD_ACTION_OPTIONS)) {
241
+ for (const option of options) {
242
+ lines.push(fishOption("scratchpad", `__fish_seen_subcommand_from scratchpad; and __fish_seen_subcommand_from ${action}`, option));
243
+ }
244
+ }
245
+ return `${lines.join("\n")}\n`;
246
+ }
247
+ function powershellCompletion() {
248
+ const psOptions = (options) => (options.length ? `@('${options.join("','")}')` : "@()");
249
+ const optionCases = Object.entries(COMMAND_OPTIONS)
250
+ .map(([command, options]) => ` '${command}' { $candidates += ${psOptions(options)} }`)
251
+ .join("\n");
252
+ const pluginOptionCases = Object.entries(PLUGIN_COMMAND_OPTIONS)
253
+ .map(([command, options]) => ` '${command}' { $candidates += ${psOptions(options)} }`)
254
+ .join("\n");
255
+ const workerOptionCases = Object.entries(WORKER_ACTION_OPTIONS)
256
+ .map(([action, options]) => ` '${action}' { $candidates += ${psOptions(options)} }`)
257
+ .join("\n");
258
+ const scratchpadOptionCases = Object.entries(SCRATCHPAD_ACTION_OPTIONS)
259
+ .map(([action, options]) => ` '${action}' { $candidates += ${psOptions(options)} }`)
260
+ .join("\n");
261
+ return `# agent-memory completion for PowerShell
262
+ # Installed automatically by: agent-memory completion powershell
263
+ # Print this script instead with: agent-memory completion powershell --stdout
264
+ Register-ArgumentCompleter -Native -CommandName agent-memory -ScriptBlock {
265
+ param($wordToComplete, $commandAst, $cursorPosition)
266
+ $tokens = @($commandAst.CommandElements | ForEach-Object { $_.ToString() })
267
+ $commands = @('${COMMANDS.join("','")}')
268
+ $pluginCommands = @('${PLUGIN_COMMANDS.join("','")}')
269
+ $workerActions = @('${WORKER_ACTIONS.join("','")}')
270
+ $scratchpadActions = @('${SCRATCHPAD_ACTIONS.join("','")}')
271
+ $shells = @('bash','zsh','fish','powershell')
272
+ $commandDescriptions = @{
273
+ ${Object.entries(COMMAND_DESCRIPTIONS)
274
+ .map(([command, description]) => ` '${command}' = '${description}'`)
275
+ .join("\n")}
276
+ }
277
+ $pluginCommandDescriptions = @{
278
+ ${Object.entries(PLUGIN_COMMAND_DESCRIPTIONS)
279
+ .map(([command, description]) => ` '${command}' = '${description}'`)
280
+ .join("\n")}
281
+ }
282
+ $workerActionDescriptions = @{
283
+ ${Object.entries(WORKER_ACTION_DESCRIPTIONS)
284
+ .map(([action, description]) => ` '${action}' = '${description}'`)
285
+ .join("\n")}
286
+ }
287
+ $scratchpadActionDescriptions = @{
288
+ ${Object.entries(SCRATCHPAD_ACTION_DESCRIPTIONS)
289
+ .map(([action, description]) => ` '${action}' = '${description}'`)
290
+ .join("\n")}
291
+ }
292
+ $shellDescriptions = @{
293
+ ${Object.entries(SHELL_DESCRIPTIONS)
294
+ .map(([shell, description]) => ` '${shell}' = '${description}'`)
295
+ .join("\n")}
296
+ }
297
+ $optionDescriptions = @{
298
+ ${Object.keys(OPTION_SPECS)
299
+ .map((option) => ` '${option}' = '${optionDescription(option)}'`)
300
+ .join("\n")}
301
+ }
302
+ $globalOptions = @('${GLOBAL_OPTIONS.join("','")}')
303
+ $command = if ($tokens.Count -gt 1) { $tokens[1] } else { '' }
304
+ $subcommand = if ($tokens.Count -gt 2) { $tokens[2] } else { '' }
305
+ $action = if ($tokens.Count -gt 3) { $tokens[3] } else { '' }
306
+ $candidates = @()
307
+ $candidateDescriptions = @{}
308
+
309
+ if ($tokens.Count -le 2) { $candidates = $commands + $globalOptions; $candidateDescriptions = $commandDescriptions }
310
+ elseif ($command -eq 'plugin' -and $tokens.Count -le 4 -and $tokens[2] -eq 'worker') { $candidates = $workerActions + $globalOptions; $candidateDescriptions = $workerActionDescriptions }
311
+ elseif ($command -eq 'plugin' -and $tokens.Count -le 3) { $candidates = $pluginCommands + $globalOptions; $candidateDescriptions = $pluginCommandDescriptions }
312
+ elseif ($command -eq 'scratchpad' -and $tokens.Count -le 3) { $candidates = $scratchpadActions + $globalOptions; $candidateDescriptions = $scratchpadActionDescriptions }
313
+ elseif ($command -eq 'completion' -and $tokens.Count -le 3) { $candidates = $shells; $candidateDescriptions = $shellDescriptions }
314
+ else {
315
+ $candidates = $globalOptions
316
+ $candidateDescriptions = $optionDescriptions
317
+ if ($command -eq 'plugin') {
318
+ if ($subcommand -eq 'worker' -and $action) {
319
+ switch ($action) {
320
+ ${workerOptionCases}
321
+ }
322
+ } else {
323
+ switch ($subcommand) {
324
+ ${pluginOptionCases}
325
+ }
326
+ }
327
+ } elseif ($command -eq 'scratchpad') {
328
+ switch ($subcommand) {
329
+ ${scratchpadOptionCases}
330
+ }
331
+ } else {
332
+ switch ($command) {
333
+ ${optionCases}
334
+ }
335
+ }
336
+ }
337
+
338
+ $candidates | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
339
+ $description = if ($candidateDescriptions.ContainsKey($_)) { $candidateDescriptions[$_] } elseif ($optionDescriptions.ContainsKey($_)) { $optionDescriptions[$_] } else { $_ }
340
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $description)
341
+ }
342
+ }
343
+ `;
344
+ }
345
+ export function generateCompletion(shell) {
346
+ switch (shell) {
347
+ case "bash":
348
+ return bashCompletion();
349
+ case "zsh":
350
+ return zshCompletion();
351
+ case "fish":
352
+ return fishCompletion();
353
+ case "powershell":
354
+ return powershellCompletion();
355
+ }
356
+ }
357
+ export function detectCompletionShell(environment = process.env, platform = process.platform) {
358
+ const shell = path.basename(environment.SHELL ?? "").toLowerCase();
359
+ if (shell === "bash" || shell === "zsh" || shell === "fish")
360
+ return shell;
361
+ if (shell.includes("pwsh") || shell.includes("powershell"))
362
+ return "powershell";
363
+ if (platform === "win32" && environment.PSModulePath)
364
+ return "powershell";
365
+ return null;
366
+ }
367
+ function writeCompletionFile(filePath, content) {
368
+ fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o755 });
369
+ fs.writeFileSync(filePath, content, { mode: 0o644 });
370
+ }
371
+ function ensureProfileBlock(filePath, lines) {
372
+ const start = "# >>> agent-memory completion >>>";
373
+ const end = "# <<< agent-memory completion <<<";
374
+ const block = `${start}\n${lines.join("\n")}\n${end}`;
375
+ const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : "";
376
+ const startIndex = current.indexOf(start);
377
+ const endIndex = startIndex === -1 ? -1 : current.indexOf(end, startIndex);
378
+ let updated;
379
+ if (startIndex !== -1 && endIndex !== -1) {
380
+ updated = `${current.slice(0, startIndex)}${block}${current.slice(endIndex + end.length)}`;
381
+ }
382
+ else {
383
+ const separator = current.length === 0 || current.endsWith("\n") ? "" : "\n";
384
+ updated = `${current}${separator}${block}\n`;
385
+ }
386
+ if (updated === current)
387
+ return false;
388
+ fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o755 });
389
+ fs.writeFileSync(filePath, updated, { mode: 0o600 });
390
+ return true;
391
+ }
392
+ export function installCompletion(shell, options = {}) {
393
+ const homeDir = options.homeDir ?? os.homedir();
394
+ const platform = options.platform ?? process.platform;
395
+ const completionDir = path.join(homeDir, ".config", "agent-memory", "completions");
396
+ if (shell === "fish") {
397
+ const completionPath = path.join(homeDir, ".config", "fish", "completions", "agent-memory.fish");
398
+ writeCompletionFile(completionPath, generateCompletion(shell));
399
+ return { shell, completionPath, profileUpdated: false };
400
+ }
401
+ const extension = shell === "powershell" ? "ps1" : shell;
402
+ const completionPath = path.join(completionDir, `agent-memory.${extension}`);
403
+ writeCompletionFile(completionPath, generateCompletion(shell));
404
+ if (shell === "bash") {
405
+ const profilePath = path.join(homeDir, ".bashrc");
406
+ const profileUpdated = ensureProfileBlock(profilePath, [
407
+ `if [[ -r "$HOME/.config/agent-memory/completions/agent-memory.bash" ]]; then`,
408
+ ` source "$HOME/.config/agent-memory/completions/agent-memory.bash"`,
409
+ "fi",
410
+ ]);
411
+ return { shell, completionPath, profilePath, profileUpdated };
412
+ }
413
+ if (shell === "zsh") {
414
+ const profilePath = path.join(homeDir, ".zshrc");
415
+ const profileUpdated = ensureProfileBlock(profilePath, [
416
+ "autoload -Uz compinit",
417
+ "if (( ! $+functions[compdef] )); then compinit; fi",
418
+ `source "$HOME/.config/agent-memory/completions/agent-memory.zsh"`,
419
+ ]);
420
+ return { shell, completionPath, profilePath, profileUpdated };
421
+ }
422
+ const profilePath = platform === "win32"
423
+ ? path.join(homeDir, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1")
424
+ : path.join(homeDir, ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
425
+ const profileUpdated = ensureProfileBlock(profilePath, [
426
+ `. "$HOME/.config/agent-memory/completions/agent-memory.ps1"`,
427
+ ]);
428
+ return { shell, completionPath, profilePath, profileUpdated };
429
+ }
package/dist/core.d.ts CHANGED
@@ -40,6 +40,13 @@ export interface PreviewResult {
40
40
  previewLines: number;
41
41
  previewChars: number;
42
42
  }
43
+ /** Redact common credential shapes before content reaches disk or agent context. */
44
+ export declare function redactSecrets(content: string): {
45
+ content: string;
46
+ redacted: boolean;
47
+ };
48
+ /** Apply trust, lifecycle, and secret policy to complete logical write entries. */
49
+ export declare function filterMemoryForContext(content: string, now?: Date): string;
43
50
  export declare function truncateLines(lines: string[], maxLines: number, mode: TruncateMode): {
44
51
  lines: string[];
45
52
  truncated: boolean;
@@ -166,6 +173,7 @@ export declare function searchRelevantMemories(prompt: string): Promise<string>;
166
173
  export interface QmdSearchResult {
167
174
  path?: string;
168
175
  file?: string;
176
+ context?: string;
169
177
  score?: number;
170
178
  content?: string;
171
179
  chunk?: string;
@@ -175,22 +183,35 @@ export interface QmdSearchResult {
175
183
  }
176
184
  export declare function getQmdResultPath(r: QmdSearchResult): string | undefined;
177
185
  export declare function getQmdResultText(r: QmdSearchResult): string;
178
- export declare function runQmdSearch(mode: "keyword" | "semantic" | "deep", query: string, limit: number): Promise<{
186
+ export declare function runQmdSearch(mode: "keyword" | "semantic" | "deep", query: string, limit: number, options?: {
187
+ signal?: AbortSignal;
188
+ }): Promise<{
179
189
  results: QmdSearchResult[];
180
190
  stderr: string;
181
191
  }>;
192
+ /**
193
+ * Best-effort check of whether vector embeddings are actually usable for
194
+ * semantic/deep search right now. Runs a tiny semantic probe and looks for
195
+ * qmd's "need embeddings" warning. Bounded by a short timeout because the very
196
+ * first semantic query can trigger a model download — returns "unknown" rather
197
+ * than blocking on it. "ready" means the probe ran without the warning; it does
198
+ * not prove the index has content.
199
+ */
200
+ export declare function probeEmbeddings(): Promise<"ready" | "missing" | "unknown">;
182
201
  export interface ToolResult {
183
202
  text: string;
184
203
  details: Record<string, unknown>;
185
204
  isError?: boolean;
186
205
  }
187
206
  export declare function memoryWrite(params: {
207
+ directory?: string;
188
208
  target?: "long_term" | "daily" | "topic";
189
209
  content: string;
190
210
  mode?: "append" | "overwrite";
191
211
  sessionId?: string;
192
212
  topic?: string;
193
213
  date?: string;
214
+ sourceUri?: string;
194
215
  }): Promise<ToolResult>;
195
216
  export declare function scratchpadAction(params: {
196
217
  action: "add" | "done" | "undo" | "clear_done" | "list";