@memorax/memorax-code 0.1.10 → 0.1.12

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 (84) hide show
  1. package/README.md +7 -4
  2. package/bin/memorax-code-setup.mjs +136 -34
  3. package/bin/memorax-code-trae.mjs +4 -0
  4. package/docs/configuration.md +111 -54
  5. package/docs/troubleshooting.md +50 -8
  6. package/lib/memorax-code-backend/dist/clients/claude/transcript-turn.js +2 -2
  7. package/lib/memorax-code-backend/dist/clients/codex/rollout-turn.js +1 -1
  8. package/lib/memorax-code-backend/dist/clients/trae/lifecycle.js +53 -0
  9. package/lib/memorax-code-backend/dist/clients/trae/memory-hook-runtime.js +302 -0
  10. package/lib/memorax-code-backend/dist/clients/trae/turn-id.js +16 -0
  11. package/lib/memorax-code-backend/dist/config/memorax-code.js +14 -1
  12. package/lib/memorax-code-backend/dist/entrypoints/backend-cli.js +22 -4
  13. package/lib/memorax-code-backend/dist/lifecycle/active-clients.js +3 -0
  14. package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +14 -2
  15. package/lib/memorax-code-backend/dist/lifecycle/client-selection.js +5 -3
  16. package/lib/memorax-code-backend/dist/lifecycle/orchestrator.js +62 -9
  17. package/lib/memorax-code-backend/dist/memory/hook-command.js +34 -2
  18. package/lib/memorax-code-backend/dist/memory/reminder-trace-recorder.js +5 -1
  19. package/lib/memorax-code-backend/dist/memory/service.js +12 -0
  20. package/lib/memorax-code-backend/dist/trace/config.js +12 -1
  21. package/lib/memorax-code-backend/dist/trace/context.js +26 -1
  22. package/lib/memorax-code-backend/package.json +1 -1
  23. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  24. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  25. package/lib/memorax-code-claude-adapter/package.json +1 -1
  26. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +3 -1
  27. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  28. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  29. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  30. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  31. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  32. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +3 -1
  33. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  34. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  35. package/lib/memorax-code-codebuddy-adapter/.codebuddy-plugin/plugin.json +1 -1
  36. package/lib/memorax-code-codebuddy-adapter/hooks/runtime-hook.mjs +11 -1
  37. package/lib/memorax-code-codebuddy-adapter/package.json +1 -1
  38. package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/SKILL.md +3 -1
  39. package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  40. package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  41. package/lib/memorax-code-codebuddy-adapter/src/config.mjs +86 -23
  42. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  43. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  44. package/lib/memorax-code-codex-adapter/package.json +1 -1
  45. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +3 -1
  46. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  47. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  48. package/lib/memorax-code-dsh-adapter/package.json +1 -1
  49. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +3 -1
  50. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  51. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  52. package/lib/memorax-code-opencode-adapter/package.json +1 -1
  53. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +3 -1
  54. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +16 -3
  55. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +15 -2
  56. package/lib/memorax-code-trae-adapter/hooks/runtime-hook.mjs +340 -0
  57. package/lib/memorax-code-trae-adapter/package.json +9 -0
  58. package/lib/memorax-code-trae-adapter/skills/memorax-code/SKILL.md +87 -0
  59. package/lib/memorax-code-trae-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  60. package/lib/memorax-code-trae-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  61. package/lib/memorax-code-trae-adapter/skills/memorax-code/defaults.json +12 -0
  62. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/memorax-add.md +101 -0
  63. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/memorax-search.md +106 -0
  64. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/personal-read.md +46 -0
  65. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/personal-write.md +120 -0
  66. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-build.md +319 -0
  67. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-read.md +103 -0
  68. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  69. package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-update.md +127 -0
  70. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  71. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  72. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  73. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  74. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  75. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  76. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  77. package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  78. package/lib/memorax-code-trae-adapter/src/adapter-paths.mjs +69 -0
  79. package/lib/memorax-code-trae-adapter/src/cli.mjs +59 -0
  80. package/lib/memorax-code-trae-adapter/src/config.mjs +630 -0
  81. package/lib/memorax-code-trae-adapter/src/runtime-observation.mjs +55 -0
  82. package/lib/resolve-codebuddy-command.mjs +15 -4
  83. package/lib/run-entrypoint.mjs +6 -0
  84. package/package.json +5 -3
@@ -18,6 +18,7 @@ import { claudeAdapterLifecycle } from "../clients/claude/lifecycle.js";
18
18
  import { collectDshAdapterLifecycleStatus, withDshAdapterLifecycleLock, } from "../clients/dsh/lifecycle.js";
19
19
  import { openCodeAdapterLifecycle } from "../clients/opencode/lifecycle.js";
20
20
  import { codeBuddyAdapterLifecycle } from "../clients/codebuddy/lifecycle.js";
21
+ import { traeAdapterLifecycle } from "../clients/trae/lifecycle.js";
21
22
  const PACKAGE_REPLACEMENT_ENV = "MEMORAX_CODE_PACKAGE_REPLACEMENT";
22
23
  const DSH_OPTIONAL_ENV = "MEMORAX_CODE_DSH_ADAPTER_OPTIONAL";
23
24
  const DSH_RECOVERY_ENV = "MEMORAX_CODE_DSH_ADAPTER_RECOVERY";
@@ -62,17 +63,22 @@ export async function collectMemoraxCodeStatus(backendUrl, backendToken, service
62
63
  const codebuddyAdapter = clients.codebuddy
63
64
  ? await codeBuddyAdapterLifecycle.status({ argv, serviceOptions, backendUrl })
64
65
  : undefined;
66
+ const traeAdapter = clients.trae
67
+ ? await traeAdapterLifecycle.status({ argv, serviceOptions, backendUrl })
68
+ : undefined;
65
69
  const codexReady = codexAdapter ? isAdapterReady(codexAdapter) : true;
66
70
  const claudeReady = claudeAdapter ? isAdapterReady(claudeAdapter) : true;
67
71
  const dshReady = dshAdapter ? isAdapterReady(dshAdapter) : true;
68
72
  const opencodeReady = opencodeAdapter ? isAdapterReady(opencodeAdapter) : true;
69
73
  const codebuddyReady = codebuddyAdapter ? isAdapterReady(codebuddyAdapter) : true;
74
+ const traeReady = traeAdapter ? isAdapterReady(traeAdapter) : true;
70
75
  const optionalDshUnavailable = isOptionalUnavailableDshAdapter(dshAdapter);
71
76
  return {
72
77
  ok: backend.ok
73
78
  && codexReady
74
79
  && opencodeReady
75
80
  && codebuddyReady
81
+ && traeReady
76
82
  && (isOptionalUnconfiguredClaudeAdapter(claudeAdapter, codexAdapter) || claudeReady)
77
83
  && (optionalDshUnavailable || dshReady),
78
84
  action: "status",
@@ -83,6 +89,7 @@ export async function collectMemoraxCodeStatus(backendUrl, backendToken, service
83
89
  ...(dshAdapter ? { dshAdapter } : {}),
84
90
  ...(opencodeAdapter ? { opencodeAdapter } : {}),
85
91
  ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
92
+ ...(traeAdapter ? { traeAdapter } : {}),
86
93
  };
87
94
  }
88
95
  export async function startMemoraxCodeService(serviceOptions, argv, commitReadyState) {
@@ -203,11 +210,15 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
203
210
  const deselectedCodeBuddy = previousClients?.codebuddy && !clients.codebuddy
204
211
  ? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
205
212
  : undefined;
213
+ const deselectedTrae = previousClients?.trae && !clients.trae
214
+ ? await traeAdapterLifecycle.disable({ argv, serviceOptions })
215
+ : undefined;
206
216
  if (deselectedCodex?.ok === false
207
217
  || deselectedClaude?.ok === false
208
218
  || deselectedDsh?.ok === false
209
219
  || deselectedOpenCode?.ok === false
210
- || deselectedCodeBuddy?.ok === false) {
220
+ || deselectedCodeBuddy?.ok === false
221
+ || deselectedTrae?.ok === false) {
211
222
  const recovery = await recoverPreparationFailure("adapter_disable_failed");
212
223
  return {
213
224
  ok: false,
@@ -220,6 +231,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
220
231
  : {}),
221
232
  ...(deselectedOpenCode ? { opencodeAdapter: deselectedOpenCode } : {}),
222
233
  ...(deselectedCodeBuddy ? { codebuddyAdapter: deselectedCodeBuddy } : {}),
234
+ ...(deselectedTrae ? { traeAdapter: deselectedTrae } : {}),
223
235
  };
224
236
  }
225
237
  // The marker is a conservative cleanup scope, not a readiness signal. Persist
@@ -262,6 +274,9 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
262
274
  const codebuddyAdapter = clients.codebuddy
263
275
  ? await codeBuddyAdapterLifecycle.prepareEnable({ argv, serviceOptions, backendUrl })
264
276
  : undefined;
277
+ const traeAdapter = clients.trae
278
+ ? await traeAdapterLifecycle.prepareEnable({ argv, serviceOptions, backendUrl })
279
+ : undefined;
265
280
  if (opencodeAdapter?.ok === false) {
266
281
  const recovery = await recoverPreparationFailure("opencode_adapter_enable_failed");
267
282
  return {
@@ -273,6 +288,21 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
273
288
  ...(recovery.dshAdapter ? { dshAdapter: recovery.dshAdapter } : {}),
274
289
  opencodeAdapter,
275
290
  ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
291
+ ...(traeAdapter ? { traeAdapter } : {}),
292
+ };
293
+ }
294
+ if (traeAdapter?.ok === false) {
295
+ const recovery = await recoverPreparationFailure("trae_adapter_enable_failed");
296
+ return {
297
+ ok: false,
298
+ action: "start",
299
+ backend: recovery.backend,
300
+ ...(codexAdapter ? { codexAdapter } : {}),
301
+ ...(claudeAdapter ? { claudeAdapter } : {}),
302
+ ...(recovery.dshAdapter ? { dshAdapter: recovery.dshAdapter } : {}),
303
+ ...(opencodeAdapter ? { opencodeAdapter } : {}),
304
+ ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
305
+ traeAdapter,
276
306
  };
277
307
  }
278
308
  const preparedDshAdapter = markOptionalDshAdapter(quiescedDsh?.ok === false
@@ -291,6 +321,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
291
321
  dshAdapter: recovery.dshAdapter ?? preparedDshAdapter,
292
322
  ...(opencodeAdapter ? { opencodeAdapter } : {}),
293
323
  ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
324
+ ...(traeAdapter ? { traeAdapter } : {}),
294
325
  };
295
326
  }
296
327
  const backend = await startBackendService(serviceOptions);
@@ -304,6 +335,9 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
304
335
  const disabledCodeBuddy = codebuddyAdapter
305
336
  ? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
306
337
  : undefined;
338
+ const disabledTrae = traeAdapter
339
+ ? await traeAdapterLifecycle.disable({ argv, serviceOptions })
340
+ : undefined;
307
341
  return {
308
342
  ok: false,
309
343
  action: "start",
@@ -313,6 +347,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
313
347
  ...(preparedDshAdapter ? { dshAdapter: preparedDshAdapter } : {}),
314
348
  ...(disabledOpenCode ? { opencodeAdapter: disabledOpenCode } : {}),
315
349
  ...(disabledCodeBuddy ? { codebuddyAdapter: disabledCodeBuddy } : {}),
350
+ ...(disabledTrae ? { traeAdapter: disabledTrae } : {}),
316
351
  };
317
352
  }
318
353
  const dshAdapter = markOptionalDshAdapter(preparedDshAdapter?.installed === true
@@ -330,6 +365,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
330
365
  ...(dshAdapter ? { dshAdapter } : {}),
331
366
  ...(opencodeAdapter ? { opencodeAdapter } : {}),
332
367
  ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
368
+ ...(traeAdapter ? { traeAdapter } : {}),
333
369
  };
334
370
  }
335
371
  function expectedBackendUrl(serviceOptions) {
@@ -373,14 +409,16 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
373
409
  dsh: activeClients.dsh && !clients.dsh,
374
410
  opencode: activeClients.opencode && !clients.opencode,
375
411
  codebuddy: activeClients.codebuddy && !clients.codebuddy,
412
+ trae: activeClients.trae && !clients.trae,
376
413
  }
377
414
  : undefined;
378
415
  const hasRemainingClients = remaining?.codex === true
379
416
  || remaining?.claude === true
380
417
  || remaining?.dsh === true
381
418
  || remaining?.opencode === true
382
- || remaining?.codebuddy === true;
383
- const backendOnlyStop = !clients.codex && !clients.claude && !clients.dsh && !clients.opencode && !clients.codebuddy;
419
+ || remaining?.codebuddy === true
420
+ || remaining?.trae === true;
421
+ const backendOnlyStop = !clients.codex && !clients.claude && !clients.dsh && !clients.opencode && !clients.codebuddy && !clients.trae;
384
422
  const packageReplacement = isPackageReplacement();
385
423
  const needsBackendStop = packageReplacement || backendOnlyStop || !hasRemainingClients;
386
424
  const quiescedDsh = clients.dsh && dshLifecycle
@@ -432,11 +470,15 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
432
470
  const codebuddyAdapter = clients.codebuddy
433
471
  ? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
434
472
  : undefined;
473
+ const traeAdapter = clients.trae
474
+ ? await traeAdapterLifecycle.disable({ argv, serviceOptions })
475
+ : undefined;
435
476
  const adaptersOk = codexAdapter?.ok !== false
436
477
  && claudeAdapter?.ok !== false
437
478
  && dshAdapter?.ok !== false
438
479
  && opencodeAdapter?.ok !== false
439
- && codebuddyAdapter?.ok !== false;
480
+ && codebuddyAdapter?.ok !== false
481
+ && traeAdapter?.ok !== false;
440
482
  const backend = stoppedBackend
441
483
  ?? (adaptersOk
442
484
  ? preservedBackendResult(serviceOptions, "active_clients_remaining")
@@ -446,7 +488,8 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
446
488
  && claudeAdapter?.ok !== false
447
489
  && dshAdapter?.ok !== false
448
490
  && opencodeAdapter?.ok !== false
449
- && codebuddyAdapter?.ok !== false;
491
+ && codebuddyAdapter?.ok !== false
492
+ && traeAdapter?.ok !== false;
450
493
  return {
451
494
  report: {
452
495
  ok,
@@ -457,6 +500,7 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
457
500
  ...(dshAdapter ? { dshAdapter } : {}),
458
501
  ...(opencodeAdapter ? { opencodeAdapter } : {}),
459
502
  ...(codebuddyAdapter ? { codebuddyAdapter } : {}),
503
+ ...(traeAdapter ? { traeAdapter } : {}),
460
504
  },
461
505
  remainingClients: packageReplacement
462
506
  ? activeClients
@@ -568,11 +612,15 @@ async function executeMemoraxCodeUninstall(serviceOptions, argv, context, dshLif
568
612
  const codebuddyPlugin = clients.codebuddy
569
613
  ? await codeBuddyAdapterLifecycle.remove({ argv, serviceOptions })
570
614
  : undefined;
615
+ const traePlugin = clients.trae
616
+ ? await traeAdapterLifecycle.remove({ argv, serviceOptions })
617
+ : undefined;
571
618
  const pluginCleanupOk = codexPlugin?.ok !== false
572
619
  && claudePlugin?.ok !== false
573
620
  && dshPlugin?.ok !== false
574
621
  && opencodePlugin?.ok !== false
575
- && codebuddyPlugin?.ok !== false;
622
+ && codebuddyPlugin?.ok !== false
623
+ && traePlugin?.ok !== false;
576
624
  const npmPackageRemoval = !pluginCleanupOk
577
625
  ? skippedNpmPackageRemoval("plugin_cleanup_failed")
578
626
  : canRemoveSharedPackage
@@ -597,12 +645,14 @@ async function executeMemoraxCodeUninstall(serviceOptions, argv, context, dshLif
597
645
  ...(dshAdapter ? { dshAdapter } : {}),
598
646
  ...(opencodeAdapter ? { opencodeAdapter } : {}),
599
647
  ...(codebuddyPlugin ? { codebuddyPlugin } : {}),
648
+ ...(traePlugin ? { traePlugin } : {}),
600
649
  npmPackageRemoval,
601
650
  removesPlugin: codexPlugin?.ok === true
602
651
  || claudePlugin?.ok === true
603
652
  || (dshPlugin?.ok === true && dshPlugin.skipped !== true)
604
653
  || opencodePlugin?.ok === true
605
- || codebuddyPlugin?.ok === true,
654
+ || codebuddyPlugin?.ok === true
655
+ || traePlugin?.ok === true,
606
656
  removesUserState: false,
607
657
  };
608
658
  }
@@ -728,7 +778,8 @@ function includesManagedClients(selection, required) {
728
778
  && (!required.claude || selection.claude)
729
779
  && (!required.dsh || selection.dsh)
730
780
  && (!required.opencode || selection.opencode)
731
- && (!required.codebuddy || selection.codebuddy === true);
781
+ && (!required.codebuddy || selection.codebuddy === true)
782
+ && (!required.trae || selection.trae === true);
732
783
  }
733
784
  function isPackageReplacement() {
734
785
  return truthyEnv(process.env[PACKAGE_REPLACEMENT_ENV]);
@@ -858,7 +909,9 @@ export function isAdapterReady(report) {
858
909
  && report.claudeSkills?.ok !== false
859
910
  && report.opencodeSkills?.ok !== false
860
911
  && report.codebuddyHooks?.ok !== false
861
- && report.codebuddySkills?.ok !== false;
912
+ && report.codebuddySkills?.ok !== false
913
+ && report.traeHooks?.ok !== false
914
+ && report.traeSkills?.ok !== false;
862
915
  }
863
916
  export function isOptionalUnavailableDshAdapter(report) {
864
917
  return Boolean(report?.optional === true && !isAdapterReady(report));
@@ -1,5 +1,6 @@
1
1
  import { isRecord } from "../shared/record.js";
2
2
  import { codeBuddyPromptDigest, parseCodeBuddyTurnId } from "../clients/codebuddy/turn-id.js";
3
+ import { parseTraeTurnId, traePromptDigest } from "../clients/trae/turn-id.js";
3
4
  export const MEMORY_HOOK_COMMAND_VERSION = 1;
4
5
  export const INVALID_MEMORY_HOOK_COMMAND = "invalid memory Hook command";
5
6
  const BASE_COMMAND_KEYS = [
@@ -15,6 +16,7 @@ const TURN_START_KEYS = {
15
16
  opencode: new Set([...BASE_COMMAND_KEYS, "userMessageId", "prompt"]),
16
17
  dsh: new Set(["version", "client", "sessionId", "turn", "startSeq", "cwd", "prompt"]),
17
18
  codebuddy: new Set([...BASE_COMMAND_KEYS, "turnId", "prompt", "transcriptPath"]),
19
+ trae: new Set([...BASE_COMMAND_KEYS, "turnId", "prompt"]),
18
20
  };
19
21
  const WRITEBACK_KEYS = {
20
22
  codex: new Set([...BASE_COMMAND_KEYS, "turnId", "lastAssistantMessage", "transcriptPath"]),
@@ -42,6 +44,7 @@ const WRITEBACK_KEYS = {
42
44
  "events",
43
45
  ]),
44
46
  codebuddy: new Set([...BASE_COMMAND_KEYS, "turnId", "transcriptPath"]),
47
+ trae: new Set([...BASE_COMMAND_KEYS, "turnId", "prompt", "lastAssistantMessage"]),
45
48
  };
46
49
  const SKILL_REMINDER_KEYS = {
47
50
  codex: new Set([...BASE_COMMAND_KEYS, "turnId", "transcriptPath", "content", "triggers"]),
@@ -49,6 +52,7 @@ const SKILL_REMINDER_KEYS = {
49
52
  dsh: new Set(["version", "client", "sessionId", "turn", "cwd", "content", "triggers"]),
50
53
  opencode: new Set([...BASE_COMMAND_KEYS, "userMessageId", "content", "triggers"]),
51
54
  codebuddy: new Set([...BASE_COMMAND_KEYS, "turnId", "transcriptPath", "content", "triggers"]),
55
+ trae: new Set([...BASE_COMMAND_KEYS, "turnId", "content", "triggers"]),
52
56
  };
53
57
  export function parseTurnStartCommand(value) {
54
58
  if (!isRecord(value))
@@ -56,7 +60,9 @@ export function parseTurnStartCommand(value) {
56
60
  const base = parseCommandBase(value, TURN_START_KEYS);
57
61
  if (!base)
58
62
  return invalidCommand();
59
- const prompt = requiredStringField(value, "prompt");
63
+ const prompt = base.client === "trae"
64
+ ? requiredContentField(value, "prompt")
65
+ : requiredStringField(value, "prompt");
60
66
  if (!prompt)
61
67
  return invalidCommand();
62
68
  if (base.client === "dsh") {
@@ -113,6 +119,12 @@ export function parseTurnStartCommand(value) {
113
119
  return invalidCommand();
114
120
  return { ok: true, command: { ...base, client: "codebuddy", turnId, prompt, transcriptPath } };
115
121
  }
122
+ if (base.client === "trae") {
123
+ const turnId = requiredStringField(value, "turnId");
124
+ if (!turnId || !validTraeTurnId(turnId, base.sessionId, prompt))
125
+ return invalidCommand();
126
+ return { ok: true, command: { ...base, client: "trae", turnId, prompt } };
127
+ }
116
128
  const promptId = requiredStringField(value, "promptId");
117
129
  const transcriptPath = requiredStringField(value, "transcriptPath");
118
130
  if (!promptId || !transcriptPath)
@@ -184,6 +196,15 @@ export function parseWritebackCommand(value) {
184
196
  return invalidCommand();
185
197
  return { ok: true, command: { ...base, client: "codebuddy", turnId, transcriptPath } };
186
198
  }
199
+ if (base.client === "trae") {
200
+ const turnId = requiredStringField(value, "turnId");
201
+ const prompt = requiredContentField(value, "prompt");
202
+ const lastAssistantMessage = requiredContentField(value, "lastAssistantMessage");
203
+ if (!turnId || !prompt || !lastAssistantMessage || !validTraeTurnId(turnId, base.sessionId, prompt)) {
204
+ return invalidCommand();
205
+ }
206
+ return { ok: true, command: { ...base, client: "trae", turnId, prompt, lastAssistantMessage } };
207
+ }
187
208
  const lastAssistantMessage = requiredStringField(value, "lastAssistantMessage");
188
209
  if (!lastAssistantMessage)
189
210
  return invalidCommand();
@@ -266,6 +287,12 @@ export function parseSkillReminderCommand(value) {
266
287
  return invalidCommand();
267
288
  return { ok: true, command: { ...base, client: "codebuddy", turnId, transcriptPath, content, triggers } };
268
289
  }
290
+ if (base.client === "trae") {
291
+ const turnId = requiredStringField(value, "turnId");
292
+ if (!turnId || !parseTraeTurnId({ sessionId: base.sessionId, turnId }))
293
+ return invalidCommand();
294
+ return { ok: true, command: { ...base, client: "trae", turnId, content, triggers } };
295
+ }
269
296
  const transcriptPath = requiredStringField(value, "transcriptPath");
270
297
  if (!transcriptPath)
271
298
  return invalidCommand();
@@ -310,7 +337,8 @@ function parseCommandBase(value, allowedKeys) {
310
337
  && client !== "claude-code"
311
338
  && client !== "opencode"
312
339
  && client !== "dsh"
313
- && client !== "codebuddy")
340
+ && client !== "codebuddy"
341
+ && client !== "trae")
314
342
  return undefined;
315
343
  const clientKeys = allowedKeys[client];
316
344
  if (!clientKeys || Object.keys(value).some((key) => !clientKeys.has(key)))
@@ -372,6 +400,10 @@ function validCodeBuddyTurnId(turnId, sessionId, prompt) {
372
400
  const identity = parseCodeBuddyTurnId({ sessionId, turnId });
373
401
  return Boolean(identity && (prompt === undefined || identity.promptDigest === codeBuddyPromptDigest(prompt)));
374
402
  }
403
+ function validTraeTurnId(turnId, sessionId, prompt) {
404
+ const identity = parseTraeTurnId({ sessionId, turnId });
405
+ return Boolean(identity && identity.promptDigest === traePromptDigest(prompt));
406
+ }
375
407
  function invalidCommand() {
376
408
  return { ok: false, error: INVALID_MEMORY_HOOK_COMMAND };
377
409
  }
@@ -1,5 +1,5 @@
1
1
  import { parseSkillReminderCommand, } from "./hook-command.js";
2
- import { traceContextFromClaudeHookBody, traceContextFromDshSkillReminder, traceContextFromHookBody, traceContextFromOpenCodeHookBody, traceContextFromCodeBuddyHookBody, } from "../trace/context.js";
2
+ import { traceContextFromClaudeHookBody, traceContextFromDshSkillReminder, traceContextFromHookBody, traceContextFromOpenCodeHookBody, traceContextFromCodeBuddyHookBody, traceContextFromTraeHookBody, } from "../trace/context.js";
3
3
  import { recordTraceEvent } from "../trace/store.js";
4
4
  export function createMemoryReminderTraceRecorder(options = {}) {
5
5
  return {
@@ -49,6 +49,8 @@ function traceContextForReminder(command) {
49
49
  return traceContextFromDshSkillReminder(command);
50
50
  if (command.client === "codebuddy")
51
51
  return traceContextFromCodeBuddyHookBody(command);
52
+ if (command.client === "trae")
53
+ return traceContextFromTraeHookBody(command);
52
54
  return traceContextFromOpenCodeHookBody(command);
53
55
  }
54
56
  function reminderSource(command) {
@@ -60,6 +62,8 @@ function reminderSource(command) {
60
62
  return "dsh-cordis";
61
63
  if (command.client === "codebuddy")
62
64
  return "codebuddy-hook";
65
+ if (command.client === "trae")
66
+ return "trae-hook";
63
67
  return "opencode-plugin";
64
68
  }
65
69
  async function recordTraceBestEffort(label, promise, diagnosticLogger) {
@@ -4,6 +4,7 @@ import { createClaudeMemoryHookRuntime, } from "../clients/claude/memory-hook-ru
4
4
  import { createDshMemoryHookRuntime, } from "../clients/dsh/memory-hook-runtime.js";
5
5
  import { createOpenCodeMemoryHookRuntime, } from "../clients/opencode/memory-hook-runtime.js";
6
6
  import { createCodeBuddyMemoryHookRuntime } from "../clients/codebuddy/memory-hook-runtime.js";
7
+ import { createTraeMemoryHookRuntime } from "../clients/trae/memory-hook-runtime.js";
7
8
  import { createMemoryTurnCoordinator } from "./turn-coordinator.js";
8
9
  import { createRepositoryMemorySessionRuntime, } from "./repository-session.js";
9
10
  import { createPendingQuotaNoticeRuntime } from "./quota-notice.js";
@@ -56,6 +57,12 @@ export function createMemoryService(options = {}) {
56
57
  repositoryMemorySession,
57
58
  turnCoordinator,
58
59
  });
60
+ const traeHook = createTraeMemoryHookRuntime({
61
+ ...options,
62
+ pendingQuotaNotice,
63
+ repositoryMemorySession,
64
+ turnCoordinator,
65
+ });
59
66
  let closed = false;
60
67
  return {
61
68
  async recordTurnStart(command) {
@@ -70,6 +77,8 @@ export function createMemoryService(options = {}) {
70
77
  return await dshHook.recordTurnStart(command);
71
78
  case "codebuddy":
72
79
  return await codeBuddyHook.recordTurnStart(command);
80
+ case "trae":
81
+ return await traeHook.recordTurnStart(command);
73
82
  }
74
83
  return unsupportedMemoryHookCommand(command);
75
84
  },
@@ -85,6 +94,8 @@ export function createMemoryService(options = {}) {
85
94
  return await dshHook.writeback(command);
86
95
  case "codebuddy":
87
96
  return await codeBuddyHook.writeback(command);
97
+ case "trae":
98
+ return await traeHook.writeback(command);
88
99
  }
89
100
  return unsupportedMemoryHookCommand(command);
90
101
  },
@@ -100,6 +111,7 @@ export function createMemoryService(options = {}) {
100
111
  openCodeHook.close();
101
112
  dshHook.close();
102
113
  codeBuddyHook.close();
114
+ traeHook.close();
103
115
  turnCoordinator.close();
104
116
  repositoryMemorySession.close();
105
117
  automaticWriteback.close();
@@ -4,7 +4,7 @@ import { join } from "node:path";
4
4
  import { loadMemoraxCodeConfig } from "../config/memorax-code.js";
5
5
  import { isTraceClient } from "./context.js";
6
6
  export const TRACE_CLIENTS = ["codex", "claude", "dsh", "opencode"];
7
- export const TRACE_RUNTIME_CLIENTS = [...TRACE_CLIENTS, "codebuddy"];
7
+ export const TRACE_RUNTIME_CLIENTS = [...TRACE_CLIENTS, "codebuddy", "trae"];
8
8
  export const CODEX_TRACE_DEFAULT_CONFIG = {
9
9
  enabled: true,
10
10
  captureContent: true,
@@ -36,12 +36,16 @@ export const OPENCODE_TRACE_DEFAULT_CONFIG = {
36
36
  export const CODEBUDDY_TRACE_DEFAULT_CONFIG = {
37
37
  ...OPENCODE_TRACE_DEFAULT_CONFIG,
38
38
  };
39
+ export const TRAE_TRACE_DEFAULT_CONFIG = {
40
+ ...OPENCODE_TRACE_DEFAULT_CONFIG,
41
+ };
39
42
  const TRACE_DEFAULT_CONFIGS = {
40
43
  codex: CODEX_TRACE_DEFAULT_CONFIG,
41
44
  claude: CLAUDE_TRACE_DEFAULT_CONFIG,
42
45
  dsh: DSH_TRACE_DEFAULT_CONFIG,
43
46
  opencode: OPENCODE_TRACE_DEFAULT_CONFIG,
44
47
  codebuddy: CODEBUDDY_TRACE_DEFAULT_CONFIG,
48
+ trae: TRAE_TRACE_DEFAULT_CONFIG,
45
49
  };
46
50
  const TRACE_ENV_PREFIXES = {
47
51
  codex: "MEMORAX_CODE_CODEX_TRACE",
@@ -49,6 +53,7 @@ const TRACE_ENV_PREFIXES = {
49
53
  dsh: "MEMORAX_CODE_DSH_TRACE",
50
54
  opencode: "MEMORAX_CODE_OPENCODE_TRACE",
51
55
  codebuddy: "MEMORAX_CODE_CODEBUDDY_TRACE",
56
+ trae: "MEMORAX_CODE_TRAE_TRACE",
52
57
  };
53
58
  export const TRACE_CLEANUP_DEBOUNCE_MS = 60 * 60 * 1000;
54
59
  export const TRACE_CURRENT_TURN_TTL_MS = 30 * 60 * 1000;
@@ -71,6 +76,9 @@ export function openCodeTraceConfigFromEnv(env = process.env, fileConfig) {
71
76
  export function codeBuddyTraceConfigFromEnv(env = process.env, fileConfig) {
72
77
  return clientTraceConfigFromEnv("codebuddy", env, fileConfig);
73
78
  }
79
+ export function traeTraceConfigFromEnv(env = process.env, fileConfig) {
80
+ return clientTraceConfigFromEnv("trae", env, fileConfig);
81
+ }
74
82
  export function clientTraceConfigFromEnv(client, env = process.env, fileConfig) {
75
83
  assertTraceClient(client);
76
84
  const config = fileConfig ?? loadMemoraxCodeConfig(memoraxCodeHomeForTrace(env), { warn: () => undefined });
@@ -103,6 +111,9 @@ export function openCodeTracePaths(memoraxCodeHome = memoraxCodeHomeForTrace(pro
103
111
  export function codeBuddyTracePaths(memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
104
112
  return clientTracePaths("codebuddy", memoraxCodeHome);
105
113
  }
114
+ export function traeTracePaths(memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
115
+ return clientTracePaths("trae", memoraxCodeHome);
116
+ }
106
117
  export function clientTracePaths(client, memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
107
118
  assertTraceClient(client);
108
119
  const root = join(memoraxCodeHome, "debug", "traces", client);
@@ -82,6 +82,26 @@ export function traceContextFromCodeBuddyHookBody(body, capturedAt = new Date().
82
82
  capturedAt,
83
83
  });
84
84
  }
85
+ export function traceContextFromTraeHookBody(body, capturedAt = new Date().toISOString()) {
86
+ if (!isRecord(body))
87
+ return undefined;
88
+ const sessionId = stringField(body, "session_id") ?? stringField(body, "sessionId");
89
+ const turnId = stringField(body, "turn_id") ?? stringField(body, "turnId");
90
+ if (!sessionId || !turnId)
91
+ return undefined;
92
+ const cwd = stringField(body, "cwd");
93
+ return pruneTraceContext({
94
+ schemaVersion: "1",
95
+ client: "trae",
96
+ sessionId,
97
+ turnId,
98
+ cwd,
99
+ memoryProject: resolveMemoryProject(cwd),
100
+ workspaceKind: stringField(body, "workspace_kind") ?? stringField(body, "workspaceKind"),
101
+ contextOrigin: "trae-hook-body",
102
+ capturedAt,
103
+ });
104
+ }
85
105
  export function traceContextFromDshTurnStart(body, capturedAt = new Date().toISOString()) {
86
106
  return traceContextFromDshBody(body, "dsh-cordis-turn-start", capturedAt);
87
107
  }
@@ -149,7 +169,12 @@ function pruneRecord(value) {
149
169
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
150
170
  }
151
171
  export function isTraceClient(value) {
152
- return value === "codex" || value === "claude" || value === "dsh" || value === "opencode" || value === "codebuddy";
172
+ return value === "codex"
173
+ || value === "claude"
174
+ || value === "dsh"
175
+ || value === "opencode"
176
+ || value === "codebuddy"
177
+ || value === "trae";
153
178
  }
154
179
  function traceContextFromDshBody(body, contextOrigin, capturedAt) {
155
180
  if (!isRecord(body))
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memorax-code/backend",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Local memory integration, lifecycle, trace, and diagnostics for MemoraX Code.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorax-code-claude-adapter",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Memory skill and local hooks for MemoraX Code in Claude Code.",
5
5
  "author": {
6
6
  "name": "MemoraX Code Maintainers"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "version": 1,
3
- "shellVersion": "0.1.10",
3
+ "shellVersion": "0.1.12",
4
4
  "runtimeAbi": 1
5
5
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memorax-code/claude-adapter",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Claude Code Hook adapter for MemoraX Code memory services.",
@@ -74,7 +74,9 @@ Examples:
74
74
 
75
75
  ## Shared Rules
76
76
 
77
- For MemoraX Code coding memory, run `memorax-cli` from the active task workspace. The installed Hook and session binding supply the authoritative workspace root; do not run Git commands to discover or replace it. The Backend resolves repository scope from that trusted workspace and read-only filesystem Git metadata.
77
+ For MemoraX Code coding memory, run the platform command from the active task workspace. In Windows PowerShell, use `memorax-cli.cmd`; on macOS and Linux, use `memorax-cli`. Never invoke `memorax-cli.ps1`. Never run `Set-ExecutionPolicy` or otherwise change PowerShell execution policy for MemoraX commands. If an unqualified Windows invocation is blocked before the CLI starts with `UnauthorizedAccess` or `PSSecurityException`, retry the same command once with `memorax-cli.cmd`, preserving all arguments, the active workspace, and environment variables.
78
+
79
+ The installed Hook and session binding supply the authoritative workspace root; do not run Git commands to discover or replace it. The Backend resolves repository scope from that trusted workspace and read-only filesystem Git metadata.
78
80
 
79
81
  Repo memory and personal memory remain local `.repo_memory` authorities. Resolve their repository root exactly as described by the selected reference, including its Git requirements.
80
82
 
@@ -17,9 +17,22 @@ Do not add positive repair lessons based only on unverified edits or assistant s
17
17
 
18
18
  ## Add Workflow
19
19
 
20
+ Select the executable before constructing any Add command. In Windows PowerShell, use `memorax-cli.cmd`; on macOS and Linux, use `memorax-cli`. Never invoke `memorax-cli.ps1`. Never run `Set-ExecutionPolicy` or otherwise change PowerShell execution policy for MemoraX commands. If an unqualified Windows invocation is blocked before the CLI starts with `UnauthorizedAccess` or `PSSecurityException`, retry that command once with `memorax-cli.cmd`, preserving all arguments, the active workspace, and environment variables.
21
+
20
22
  For a proactive add, write all generated prose in `--memory`, `--reason`, and the confirmation in the language of the user's current request; preserve exact code, API, path, workflow, and project identifiers.
21
23
 
22
- Run from the active task workspace. Pass the memory and reason directly. Put every dynamically generated `--memory` and `--reason` value in single quotes, never double quotes. Treat `$HOME`, backticks, and `$(command)` as literal text inside those quotes. Replace each literal single quote in a value with the exact POSIX sequence `'\''`.
24
+ Run from the active task workspace. Pass the memory and reason directly. Put every dynamically generated `--memory` and `--reason` value in single quotes, never double quotes. Apply the escaping rule for the active shell:
25
+
26
+ - Windows PowerShell: single quotes keep `$HOME`, backticks, and `$(command)` literal. Replace each literal single quote in a value with two single quotes (`''`); for example, `don't` becomes `'don''t'`.
27
+ - macOS and Linux: Treat `$HOME`, backticks, and `$(command)` as literal text inside the quotes. Replace each literal single quote in a value with the exact POSIX sequence `'\''`.
28
+
29
+ Windows PowerShell:
30
+
31
+ ```powershell
32
+ memorax-cli.cmd add --memory 'Concise reusable memory.' --type procedural --reason 'Capture reusable coding memory.'
33
+ ```
34
+
35
+ macOS and Linux:
23
36
 
24
37
  ```bash
25
38
  memorax-cli add \
@@ -49,7 +62,7 @@ anchors: <stable repository source, tests, or public docs>
49
62
 
50
63
  Keep the card under 1,100 characters when practical. It must guide future investigation while still requiring live-code inspection.
51
64
 
52
- Pass a completed multi-line card as one single-quoted `--memory` argument:
65
+ Pass a completed multi-line card as one single-quoted `--memory` argument. On Windows PowerShell, the command must start with `memorax-cli.cmd add`; on macOS and Linux, use the form shown below.
53
66
 
54
67
  ```bash
55
68
  memorax-cli add \
@@ -69,7 +82,7 @@ anchors: stable/source/path' \
69
82
  --reason 'Capture verified reusable coding memory.'
70
83
  ```
71
84
 
72
- If add fails, report the exact failure and do not retry automatically, bypass the CLI, or call MemoraX directly.
85
+ Except for the pre-start Windows shim correction above, if add fails, report the exact failure and do not retry automatically, bypass the CLI, or call MemoraX directly. Do not retry Add after the CLI may have started.
73
86
 
74
87
  If a successful Add result reports `workspaceScopeFallbackReason: git_metadata_invalid`, malformed or incomplete metadata inside a direct `.git` directory was downgraded to the normalized local folder scope. Add has already been submitted with the reported `effectiveUserId`. Present its `userNotice` once without pausing the current task or asking the user to repair Git first, then continue the current task. After the repository or `.git` metadata is repaired, later Search, Add, and automatic writeback in the same client session automatically use the restored Git repository scope.
75
88
 
@@ -4,6 +4,8 @@ Use these instructions only to search reusable coding memory through `memorax-cl
4
4
 
5
5
  ## Scope
6
6
 
7
+ Select the executable before constructing any Search command. In Windows PowerShell, use `memorax-cli.cmd`; on macOS and Linux, use `memorax-cli`. Never invoke `memorax-cli.ps1`. Never run `Set-ExecutionPolicy` or otherwise change PowerShell execution policy for MemoraX commands. If an unqualified Windows invocation is blocked before the CLI starts with `UnauthorizedAccess` or `PSSecurityException`, retry the same command once with `memorax-cli.cmd`, preserving all arguments, the active workspace, and environment variables.
8
+
7
9
  Run the CLI from the active task workspace. The installed Hook and session binding supply the authoritative workspace root; do not run `git rev-parse`, infer the root from Git metadata, or substitute an unrelated working directory. Do not make `memorax-cli status` a mandatory preflight; use it only to diagnose a configuration or scope failure.
8
10
 
9
11
  Coding memory uses `<MemoraX base username>@<normalized repository name>` for Git workspaces and the normalized folder name for genuine non-Git directories. MemoraX Code resolves `.git`, `gitdir`, and `commondir` without executing Git. Linked worktrees share one repository scope; another clone, repository, or non-Git directory retains a different local session key even when its readable name matches.
@@ -12,7 +14,7 @@ If a successful Search result reports `workspaceScopeFallbackReason: git_metadat
12
14
 
13
15
  Require a readable active workspace binding. A CLI command from a linked worktree of the bound repository is valid. If `memorax-cli search` reports `workspace_scope_mismatch` or `workspace_scope_unavailable`, do not bypass the scope or fall back to an unscoped username. Do not change the CLI working directory and retry. Tell the user that memory search was not executed and no request was sent to MemoraX, then present the CLI's `userAction` in natural language. Continue the current task using only live code and documentation.
14
16
 
15
- If `memorax-cli` is not on `PATH`, or memory is disabled, unconfigured, or unavailable, report that briefly and continue with live code or documentation. Authenticate through MemoraX Code configuration; never recover credentials from shell history or place tokens in prompts. Treat injected memory as a hypothesis and verify it against the current checkout.
17
+ If the selected platform command is not on `PATH`, or memory is disabled, unconfigured, or unavailable, report that briefly and continue with live code or documentation. Authenticate through MemoraX Code configuration; never recover credentials from shell history or place tokens in prompts. Treat injected memory as a hypothesis and verify it against the current checkout.
16
18
 
17
19
  ## Search Decision
18
20
 
@@ -50,10 +52,21 @@ State a fact-sized relationship that can change the next action: a target under
50
52
 
51
53
  For a complementary first-round pair, each query must stand alone and cover a different decision boundary. Use a complementary pair only when the provided context gives each decision boundary a distinct exact code, API, path, workflow, or project identifier; otherwise keep one focused combined query that preserves both user-stated facts. Do not merely restate the same question with synonyms. If the user describes only one tightly coupled decision, emit exactly one query. Use one or two stable exact identifiers when they sharpen the query, and integrate them grammatically instead of appending search tags or filler. Use only user-provided anchors and stable terms from live code or documentation; do not reconstruct unseen fact wording from recalled memory.
52
54
 
53
- Pass the query directly with `--query`. Put every dynamically generated query in single quotes, never double quotes. Treat `$HOME`, backticks, and `$(command)` as literal text inside those quotes. Replace each literal single quote in the value with the exact POSIX sequence `'\''`.
55
+ Pass the query directly with `--query`. Put every dynamically generated query in single quotes, never double quotes. Apply the escaping rule for the active shell:
56
+
57
+ - Windows PowerShell: single quotes keep `$HOME`, backticks, and `$(command)` literal. Replace each literal single quote in the value with two single quotes (`''`); for example, `don't` becomes `'don''t'`.
58
+ - macOS and Linux: Treat `$HOME`, backticks, and `$(command)` as literal text inside the quotes. Replace each literal single quote in the value with the exact POSIX sequence `'\''`.
54
59
 
55
60
  Use these actual output shapes as examples. They are queries themselves, not full user prompts or instructions for the user. Each Chinese/English pair is a language variant: choose the one matching the user, never run both merely because both are shown. The comments explain the example only and are not part of emitted query text.
56
61
 
62
+ On Windows PowerShell, the first example must be invoked as:
63
+
64
+ ```powershell
65
+ memorax-cli.cmd search --query 'Trace 生产版本:升级后到达的记录中,应以哪个客户端版本字段判断由旧插件产生,而非新版本上传进程?'
66
+ ```
67
+
68
+ On macOS and Linux, use the `memorax-cli search` forms below. For other Windows examples, preserve every argument but replace the leading executable with `memorax-cli.cmd`.
69
+
57
70
  ```bash
58
71
  # One tightly coupled decision: emit one query.
59
72
  memorax-cli search --query 'Trace 生产版本:升级后到达的记录中,应以哪个客户端版本字段判断由旧插件产生,而非新版本上传进程?'
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorax-code-claude-adapter",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Memory skill and local hooks for MemoraX Code in Claude Code.",
5
5
  "author": {
6
6
  "name": "MemoraX Code Maintainers"