@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
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @memorax/memorax-code
2
2
 
3
- MemoraX Code adds persistent coding memory to Codex, Claude Code, DeepSeek
4
- Harness, and OpenCode.
3
+ MemoraX Code adds persistent coding memory to Codex, Claude Code,
4
+ CodeBuddy/WorkBuddy, DeepSeek Harness, OpenCode, and Trae.
5
5
 
6
6
  ## Requirements
7
7
 
8
8
  - Node.js 20 or newer (Node.js 24 LTS recommended) and npm.
9
- - At least one of Codex, Claude Code, DeepSeek Harness, OpenCode Desktop, or
10
- the OpenCode CLI.
9
+ - At least one of Codex, Claude Code, CodeBuddy/WorkBuddy, DeepSeek Harness,
10
+ OpenCode Desktop or CLI, or Trae.
11
11
  - Python 3 only for Repo Memory operations.
12
12
 
13
13
  ## Install
@@ -67,6 +67,9 @@ $env:Path = "$NpmGlobalBin;$env:Path"
67
67
  After the first installation, restart or refresh the detected coding agents
68
68
  before opening a new session. In Codex, enable **MemoraX Code Codex Adapter**
69
69
  from Plugins or `/plugins` if it is not already enabled.
70
+ For Trae, open Settings and enable **Global Hooks** once before starting a new
71
+ Trae session; setup installs the managed Hooks and Skill but cannot switch that
72
+ Trae setting reliably.
70
73
 
71
74
  ## Verify
72
75
 
@@ -22,6 +22,10 @@ import { discoverDshProfiles } from "../lib/dsh-plugin-install.mjs";
22
22
  import { ensureClaudeCommandEnv } from "../lib/resolve-claude-command.mjs";
23
23
  import { ensureCodexCommandEnv } from "../lib/resolve-codex-command.mjs";
24
24
  import { defaultCodeBuddyHome, ensureCodeBuddyCommandEnv } from "../lib/resolve-codebuddy-command.mjs";
25
+ import {
26
+ defaultTraeHome,
27
+ traeInstallationDetected,
28
+ } from "../lib/memorax-code-trae-adapter/src/adapter-paths.mjs";
25
29
  import { reconcileSetup } from "../lib/setup-reconcile.mjs";
26
30
  import { detectSetupMemoryPreferences } from "../lib/setup-memory-preferences.mjs";
27
31
  import { ensureTrialSetupCredential } from "../lib/trial-setup.mjs";
@@ -41,11 +45,13 @@ const RED = "\x1b[31m";
41
45
  const BOLD = "\x1b[1m";
42
46
  const RESET = "\x1b[0m";
43
47
  const DSH_OPTIONAL_ENV = "MEMORAX_CODE_DSH_ADAPTER_OPTIONAL";
48
+ const SETUP_CLIENTS = ["codex", "claude", "opencode", "codebuddy", "trae"];
44
49
 
45
50
  const skipCodexPluginInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CODEX_PLUGIN_INSTALL);
46
51
  const skipClaudeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CLAUDE_ADAPTER_INSTALL);
47
52
  const skipOpenCodeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_OPENCODE_ADAPTER_INSTALL);
48
53
  const skipCodeBuddyAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CODEBUDDY_ADAPTER_INSTALL);
54
+ const skipTraeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_TRAE_ADAPTER_INSTALL);
49
55
  const updateMode = truthyEnv(process.env.MEMORAX_CODE_SETUP_UPDATE);
50
56
  const automaticUpdateMode = truthyEnv(process.env.MEMORAX_CODE_SETUP_AUTOMATIC_UPDATE);
51
57
  const setupMode = setupModeFromEnvironment(process.env.MEMORAX_CODE_SETUP_MODE);
@@ -68,8 +74,10 @@ const claudeRuntime = ensureClaudeCommandEnv();
68
74
  const claudeCommand = claudeRuntime.command;
69
75
  const codeBuddyRuntime = ensureCodeBuddyCommandEnv();
70
76
  const codeBuddyCommand = codeBuddyRuntime.command;
71
- const previousClients = readPersistedClientSelection();
72
- const existingSetup = previousClients !== undefined;
77
+ const persistedClientSelection = readPersistedClientSelection();
78
+ const existingSetup = persistedClientSelection !== undefined;
79
+ const previousClients = persistedClientSelection?.selected ?? [];
80
+ const explicitClientChoices = persistedClientSelection?.explicit ?? [];
73
81
  const persistedDshSelection = readPersistedDshSelection();
74
82
  const dshEnabledByConfig = persistedDshSelection !== false;
75
83
  let dshProfiles = [];
@@ -114,7 +122,7 @@ try {
114
122
  process.exit(1);
115
123
  }
116
124
  runCommonPreflight();
117
- const requestedClients = ["codex", "claude", "opencode", "codebuddy"];
125
+ const requestedClients = SETUP_CLIENTS;
118
126
  const codexPreflight = requestedClients.includes("codex") && !skipCodexPluginInstall
119
127
  ? runCodexPreflight({
120
128
  integrationSelected: !existingSetup || previousClients.includes("codex"),
@@ -135,17 +143,33 @@ const codebuddyPreflight = requestedClients.includes("codebuddy") && !skipCodeBu
135
143
  integrationSelected: !existingSetup || previousClients.includes("codebuddy"),
136
144
  })
137
145
  : { ok: true };
146
+ const traePreflight = requestedClients.includes("trae") && !skipTraeAdapterInstall
147
+ ? runTraePreflight({
148
+ integrationSelected: !existingSetup || previousClients.includes("trae"),
149
+ })
150
+ : { ok: true };
138
151
  const detectedClients = requestedClients.filter((client) => {
139
152
  if (client === "codex") return !skipCodexPluginInstall && codexPreflight.ok;
140
153
  if (client === "claude") return !skipClaudeAdapterInstall && claudePreflight.ok;
141
154
  if (client === "opencode") return !skipOpenCodeAdapterInstall && opencodePreflight.ok;
142
- return !skipCodeBuddyAdapterInstall && codebuddyPreflight.ok;
155
+ if (client === "codebuddy") return !skipCodeBuddyAdapterInstall && codebuddyPreflight.ok;
156
+ return !skipTraeAdapterInstall && traePreflight.ok;
143
157
  });
158
+ const newlyDetectedClients = existingSetup
159
+ ? detectedClients.filter((client) => !explicitClientChoices.includes(client))
160
+ : [];
144
161
  const selectedClients = automaticUpdateMode
145
- ? previousClients
162
+ ? requestedClients.filter((client) => (
163
+ previousClients.includes(client) || newlyDetectedClients.includes(client)
164
+ ))
146
165
  : existingSetup
147
- ? await chooseUpdateClients(previousClients, detectedClients, scriptedAnswers)
166
+ ? await chooseUpdateClients(previousClients, newlyDetectedClients, scriptedAnswers)
148
167
  : detectedClients;
168
+ const clientsWithPersistedIntent = existingSetup
169
+ ? requestedClients.filter((client) => (
170
+ explicitClientChoices.includes(client) || newlyDetectedClients.includes(client)
171
+ ))
172
+ : requestedClients;
149
173
  const installClients = detectedClients.filter((client) => selectedClients.includes(client));
150
174
  if (existingSetup) {
151
175
  log(clientSelectionMessage(selectedClients, { dshSelected }));
@@ -169,7 +193,10 @@ if (requestedClients.includes("opencode") && !skipOpenCodeAdapterInstall && !ope
169
193
  if (requestedClients.includes("codebuddy") && !skipCodeBuddyAdapterInstall && !codebuddyPreflight.ok) {
170
194
  log("CodeBuddy/WorkBuddy runtime was not detected; skipping its adapter setup.");
171
195
  }
172
- if (writeClientSelectionConfig(selectedClients) === "failed") {
196
+ if (requestedClients.includes("trae") && !skipTraeAdapterInstall && !traePreflight.ok) {
197
+ log("Trae runtime or data directory was not detected; skipping its adapter setup.");
198
+ }
199
+ if (writeClientSelectionConfig(selectedClients, clientsWithPersistedIntent) === "failed") {
173
200
  printPostinstallSummary("not-verified");
174
201
  process.exit(1);
175
202
  }
@@ -206,6 +233,7 @@ const codexClientEnabled = installClients.includes("codex");
206
233
  const claudeClientEnabled = installClients.includes("claude");
207
234
  const opencodeClientEnabled = installClients.includes("opencode");
208
235
  const codebuddyClientEnabled = installClients.includes("codebuddy");
236
+ const traeClientEnabled = installClients.includes("trae");
209
237
  const codexClientNewlyEnabled = codexClientEnabled
210
238
  && existingSetup
211
239
  && !previousClients.includes("codex");
@@ -269,6 +297,11 @@ const codebuddySkipReason = setupClientSkipReason({
269
297
  selected: selectedClients.includes("codebuddy"),
270
298
  enabled: codebuddyClientEnabled,
271
299
  });
300
+ const traeSkipReason = setupClientSkipReason({
301
+ explicitlySkipped: skipTraeAdapterInstall,
302
+ selected: selectedClients.includes("trae"),
303
+ enabled: traeClientEnabled,
304
+ });
272
305
 
273
306
  const backendAndAdapters = await startBackendAndCheck({
274
307
  skipCodexAdapter,
@@ -283,6 +316,9 @@ const backendAndAdapters = await startBackendAndCheck({
283
316
  skipCodeBuddyAdapter: !codebuddyClientEnabled,
284
317
  codebuddyAdapterRequired: codebuddyClientEnabled,
285
318
  codebuddySkipReason,
319
+ skipTraeAdapter: !traeClientEnabled,
320
+ traeAdapterRequired: traeClientEnabled,
321
+ traeSkipReason,
286
322
  });
287
323
  const backendAndAdaptersStatus = backendAndAdapters.status;
288
324
  if (backendAndAdaptersStatus === "enabled") {
@@ -295,12 +331,15 @@ if (backendAndAdaptersStatus === "enabled") {
295
331
  dshAdapterEnabled: backendAndAdapters.dshAdapterEnabled,
296
332
  opencodeAdapterEnabled: !skipOpenCodeAdapter,
297
333
  codebuddyAdapterEnabled: codebuddyClientEnabled,
334
+ traeAdapterEnabled: traeClientEnabled,
335
+ traeGlobalHooksActivationRequired: backendAndAdapters.traeGlobalHooksActivationRequired,
298
336
  });
299
337
  printCommonCommands({
300
338
  codexAdapterEnabled: !skipCodexAdapter,
301
339
  claudeAdapterEnabled: !skipClaudeAdapter,
302
340
  opencodeAdapterEnabled: !skipOpenCodeAdapter,
303
341
  codebuddyAdapterEnabled: codebuddyClientEnabled,
342
+ traeAdapterEnabled: traeClientEnabled,
304
343
  });
305
344
  }
306
345
  printPostinstallSummary(
@@ -371,16 +410,15 @@ async function maybeConfigureMemoraxMemory(scriptedAnswers, {
371
410
  }
372
411
  }
373
412
 
374
- async function chooseUpdateClients(previousClients, detectedClients, scriptedAnswers) {
413
+ async function chooseUpdateClients(previousClients, newlyDetectedClients, scriptedAnswers) {
375
414
  const selected = new Set(previousClients);
376
- const availableDisabledClients = detectedClients.filter((client) => !selected.has(client));
377
- if (availableDisabledClients.length === 0) return [...previousClients];
415
+ if (newlyDetectedClients.length === 0) return [...previousClients];
378
416
 
379
417
  let rl;
380
418
  try {
381
- for (const client of availableDisabledClients) {
419
+ for (const client of newlyDetectedClients) {
382
420
  const label = clientLabel(client);
383
- const question = `${label} runtime is available, but its integration is disabled in [clients]. Enable it now? [Y/n]`;
421
+ const question = `${label} runtime is not configured in [clients]. Enable it now? [Y/n]`;
384
422
  let answer;
385
423
  if (scriptedAnswers) {
386
424
  log(question);
@@ -399,7 +437,7 @@ async function chooseUpdateClients(previousClients, detectedClients, scriptedAns
399
437
  } finally {
400
438
  rl?.close();
401
439
  }
402
- return ["codex", "claude", "opencode", "codebuddy"].filter((client) => selected.has(client));
440
+ return SETUP_CLIENTS.filter((client) => selected.has(client));
403
441
  }
404
442
 
405
443
  async function configureMemoraxMemoryFromAnswers(answers, detectedPreferences, {
@@ -753,12 +791,10 @@ function readPersistedClientSelection() {
753
791
  try {
754
792
  const clients = parse(readFileSync(path, "utf8"))?.clients;
755
793
  if (!clients || typeof clients !== "object" || typeof clients.codex !== "boolean" || typeof clients.claude !== "boolean") return undefined;
756
- return [
757
- clients.codex ? "codex" : undefined,
758
- clients.claude ? "claude" : undefined,
759
- clients.opencode === true ? "opencode" : undefined,
760
- clients.codebuddy === true ? "codebuddy" : undefined,
761
- ].filter(Boolean);
794
+ return {
795
+ selected: SETUP_CLIENTS.filter((client) => clients[client] === true),
796
+ explicit: SETUP_CLIENTS.filter((client) => typeof clients[client] === "boolean"),
797
+ };
762
798
  } catch {
763
799
  return undefined;
764
800
  }
@@ -775,22 +811,24 @@ function readPersistedDshSelection() {
775
811
  }
776
812
  }
777
813
 
778
- function writeClientSelectionConfig(clients) {
814
+ function writeClientSelectionConfig(clients, configuredClients = SETUP_CLIENTS) {
779
815
  const path = memoraxCodeConfigPath();
780
816
  return updateConfigFileAtomically({
781
817
  path,
782
- defaultText: setManagedClientSelection(defaultMemoraxCodeConfig(), clients),
783
- transform: (text) => setManagedClientSelection(text, clients),
818
+ defaultText: setManagedClientSelection(defaultMemoraxCodeConfig(), clients, configuredClients),
819
+ transform: (text) => setManagedClientSelection(text, clients, configuredClients),
784
820
  parseToml: parse,
785
821
  warn: (message) => log(message),
786
822
  });
787
823
  }
788
824
 
789
- function setManagedClientSelection(text, clients) {
790
- const withOpenCode = setTomlField(text, "clients", "opencode", String(clients.includes("opencode")));
791
- const withClaude = setTomlField(withOpenCode, "clients", "claude", String(clients.includes("claude")));
792
- const withCodeBuddy = setTomlField(withClaude, "clients", "codebuddy", String(clients.includes("codebuddy")));
793
- return setTomlField(withCodeBuddy, "clients", "codex", String(clients.includes("codex")));
825
+ function setManagedClientSelection(text, clients, configuredClients = SETUP_CLIENTS) {
826
+ let updated = text;
827
+ for (const client of ["opencode", "claude", "codebuddy", "trae", "codex"]) {
828
+ if (!configuredClients.includes(client)) continue;
829
+ updated = setTomlField(updated, "clients", client, String(clients.includes(client)));
830
+ }
831
+ return updated;
794
832
  }
795
833
 
796
834
  function writeMemoraxConfig({ userId, endpoint, outputLanguage, apiKey }) {
@@ -844,6 +882,7 @@ function defaultMemoraxCodeConfig() {
844
882
  "dsh = true # Manage the DeepSeek Harness adapter when Profiles exist.",
845
883
  "opencode = true # Manage the OpenCode adapter.",
846
884
  "codebuddy = true # Manage the CodeBuddy/WorkBuddy adapter.",
885
+ "trae = true # Manage the Trae adapter.",
847
886
  "",
848
887
  "# MemoraX remote-memory connection.",
849
888
  "[memorax]",
@@ -893,6 +932,10 @@ function defaultMemoraxCodeConfig() {
893
932
  "enabled = true # Enable local CodeBuddy session memory trace collection.",
894
933
  "capture_content = true # Store content in local CodeBuddy trace events.",
895
934
  "",
935
+ "[trace.trae]",
936
+ "enabled = true # Enable local Trae session memory trace collection.",
937
+ "capture_content = true # Store content in local Trae trace events.",
938
+ "",
896
939
  ].join("\n");
897
940
  }
898
941
 
@@ -965,6 +1008,9 @@ function runCommonPreflight() {
965
1008
  if (skipCodeBuddyAdapterInstall) {
966
1009
  log("CodeBuddy/WorkBuddy adapter setup is disabled for this setup; other client setup can still continue.");
967
1010
  }
1011
+ if (skipTraeAdapterInstall) {
1012
+ log("Trae adapter setup is disabled for this setup; other client setup can still continue.");
1013
+ }
968
1014
  return {};
969
1015
  }
970
1016
 
@@ -1053,6 +1099,18 @@ function runCodeBuddyPreflight({ integrationSelected = true } = {}) {
1053
1099
  return { ok: true };
1054
1100
  }
1055
1101
 
1102
+ function runTraePreflight({ integrationSelected = true } = {}) {
1103
+ const home = defaultTraeHome();
1104
+ const detected = traeInstallationDetected();
1105
+ log(`Trae data directory: ${existsSync(home) ? `found (${home})` : "not detected"}`);
1106
+ log(`Trae application: ${detected ? "detected" : "not detected"}`);
1107
+ if (!detected) return { ok: false };
1108
+ log(integrationSelected
1109
+ ? "Keeping Trae provider settings unchanged and installing the shared memory Global Hooks and Skill."
1110
+ : "Keeping Trae provider settings unchanged while checking whether to enable its integration.");
1111
+ return { ok: true };
1112
+ }
1113
+
1056
1114
  function installedPluginCache() {
1057
1115
  for (const marketplaceName of [CLI_MARKETPLACE_NAME, PERSONAL_MARKETPLACE_NAME]) {
1058
1116
  const versions = installedPluginCacheVersions(marketplaceName);
@@ -1121,6 +1179,9 @@ async function startBackendAndCheck({
1121
1179
  skipCodeBuddyAdapter = false,
1122
1180
  codebuddyAdapterRequired = !skipCodeBuddyAdapter,
1123
1181
  codebuddySkipReason,
1182
+ skipTraeAdapter = false,
1183
+ traeAdapterRequired = !skipTraeAdapter,
1184
+ traeSkipReason,
1124
1185
  } = {}) {
1125
1186
  const adapterFlags = clientLifecycleFlags({ clientMode });
1126
1187
  const startArgs = ["start", ...adapterFlags];
@@ -1142,6 +1203,7 @@ async function startBackendAndCheck({
1142
1203
  claudeAdapterRequired,
1143
1204
  opencodeAdapterRequired,
1144
1205
  codebuddyAdapterRequired,
1206
+ traeAdapterRequired,
1145
1207
  }),
1146
1208
  onEvent: (event) => {
1147
1209
  if (event.type === "start" && event.attempt === 1) {
@@ -1174,6 +1236,8 @@ async function startBackendAndCheck({
1174
1236
  opencodeSkipReason,
1175
1237
  skipCodeBuddyAdapter,
1176
1238
  codebuddySkipReason,
1239
+ skipTraeAdapter,
1240
+ traeSkipReason,
1177
1241
  });
1178
1242
  }
1179
1243
  },
@@ -1186,6 +1250,9 @@ async function startBackendAndCheck({
1186
1250
  dshAdapterUnavailable: result.status === "enabled" && statusResult
1187
1251
  ? dshAdapterUnavailable(statusResult)
1188
1252
  : false,
1253
+ traeGlobalHooksActivationRequired: result.status === "enabled" && statusResult
1254
+ ? traeGlobalHooksActivationRequired(statusResult)
1255
+ : false,
1189
1256
  };
1190
1257
  }
1191
1258
 
@@ -1198,6 +1265,8 @@ function printReconcileFailure(result, {
1198
1265
  opencodeSkipReason,
1199
1266
  skipCodeBuddyAdapter,
1200
1267
  codebuddySkipReason,
1268
+ skipTraeAdapter,
1269
+ traeSkipReason,
1201
1270
  }) {
1202
1271
  if (result.reason === "hook-runtime-activation-failed") {
1203
1272
  logRed("Client Hook runtime activation failed; automatic lifecycle recovery was skipped.");
@@ -1216,6 +1285,7 @@ function printReconcileFailure(result, {
1216
1285
  claudeSkipReason,
1217
1286
  opencodeSkipReason,
1218
1287
  codebuddySkipReason,
1288
+ traeSkipReason,
1219
1289
  });
1220
1290
  }
1221
1291
  }
@@ -1230,6 +1300,11 @@ function dshAdapterUnavailable(statusResult) {
1230
1300
  return /\bDSH adapter:\s*unavailable\b/im.test(stripAnsi(output));
1231
1301
  }
1232
1302
 
1303
+ function traeGlobalHooksActivationRequired(statusResult) {
1304
+ const output = `${statusResult.stdout ?? ""}\n${statusResult.stderr ?? ""}`;
1305
+ return /\bTrae adapter:\s*ok\b[^\r\n]*\bhook-runtime=unverified\b/im.test(stripAnsi(output));
1306
+ }
1307
+
1233
1308
  function pendingClientHookRuntimeEnv() {
1234
1309
  return {
1235
1310
  MEMORAX_CODE_PENDING_CLIENT_HOOK_RUNTIME_V1: JSON.stringify({
@@ -1252,10 +1327,10 @@ function clientLifecycleFlags({ clientMode = "all" } = {}) {
1252
1327
  }
1253
1328
 
1254
1329
  function clientModeFor(clients, { includeDsh = false } = {}) {
1255
- const selected = ["codex", "claude", "dsh", "opencode", "codebuddy"].filter((client) => (
1330
+ const selected = ["codex", "claude", "dsh", "opencode", "codebuddy", "trae"].filter((client) => (
1256
1331
  client === "dsh" ? includeDsh : clients.includes(client)
1257
1332
  ));
1258
- if (selected.length === 5) return "all";
1333
+ if (selected.length === 6) return "all";
1259
1334
  return selected.length > 0 ? selected.join(",") : "none";
1260
1335
  }
1261
1336
 
@@ -1273,6 +1348,7 @@ function clientSelectionMessage(clients, { dshSelected = false } = {}) {
1273
1348
  "DeepSeek Harness",
1274
1349
  clients.includes("opencode") ? "OpenCode" : undefined,
1275
1350
  clients.includes("codebuddy") ? "CodeBuddy/WorkBuddy" : undefined,
1351
+ clients.includes("trae") ? "Trae" : undefined,
1276
1352
  ].filter(Boolean);
1277
1353
  return `Configuring MemoraX Code for ${joinedLabels(labels)}.`;
1278
1354
  }
@@ -1280,11 +1356,13 @@ function clientSelectionMessage(clients, { dshSelected = false } = {}) {
1280
1356
  const hasClaude = clients.includes("claude");
1281
1357
  const hasOpenCode = clients.includes("opencode");
1282
1358
  const hasCodeBuddy = clients.includes("codebuddy");
1359
+ const hasTrae = clients.includes("trae");
1283
1360
  const labels = [
1284
1361
  hasCodex ? "Codex" : undefined,
1285
1362
  hasClaude ? "Claude Code" : undefined,
1286
1363
  hasOpenCode ? "OpenCode" : undefined,
1287
1364
  hasCodeBuddy ? "CodeBuddy/WorkBuddy" : undefined,
1365
+ hasTrae ? "Trae" : undefined,
1288
1366
  ].filter(Boolean);
1289
1367
  if (labels.length > 0) return `Configuring MemoraX Code for ${joinedLabels(labels)}.`;
1290
1368
  return "Skipping client adapter setup for this setup.";
@@ -1294,7 +1372,8 @@ function clientLabel(client) {
1294
1372
  if (client === "codex") return "Codex";
1295
1373
  if (client === "claude") return "Claude Code";
1296
1374
  if (client === "opencode") return "OpenCode";
1297
- return "CodeBuddy/WorkBuddy";
1375
+ if (client === "codebuddy") return "CodeBuddy/WorkBuddy";
1376
+ return "Trae";
1298
1377
  }
1299
1378
 
1300
1379
  function detectedClientMessage(clients, dshProfiles = []) {
@@ -1453,12 +1532,15 @@ function printNextSteps({
1453
1532
  dshAdapterEnabled = false,
1454
1533
  opencodeAdapterEnabled = true,
1455
1534
  codebuddyAdapterEnabled = true,
1535
+ traeAdapterEnabled = true,
1536
+ traeGlobalHooksActivationRequired = false,
1456
1537
  } = {}) {
1457
1538
  const clientText = enabledClientText({
1458
1539
  codexAdapterEnabled,
1459
1540
  claudeAdapterEnabled,
1460
1541
  opencodeAdapterEnabled,
1461
1542
  codebuddyAdapterEnabled,
1543
+ traeAdapterEnabled,
1462
1544
  });
1463
1545
  if (clientText && existingSetup) {
1464
1546
  logGreen(`${bold("The new Hook runtime is active")}; existing sessions with the stable shell select it on their next user prompt.`);
@@ -1474,11 +1556,15 @@ function printNextSteps({
1474
1556
  if (codexAdapterEnabled && !existingSetup) {
1475
1557
  logGreen(`After restart, ${bold("enable the MemoraX Code Codex Adapter plugin")} from Codex Plugins or CLI \`/plugins\` if it is not already enabled.`);
1476
1558
  }
1559
+ if (traeAdapterEnabled && traeGlobalHooksActivationRequired) {
1560
+ logGreen(`${bold("Open Trae Settings and enable Global Hooks once")}, then start a new Trae session.`);
1561
+ }
1477
1562
  const statusCommands = statusCommandText({
1478
1563
  codexAdapterEnabled,
1479
1564
  claudeAdapterEnabled,
1480
1565
  opencodeAdapterEnabled,
1481
1566
  codebuddyAdapterEnabled,
1567
+ traeAdapterEnabled,
1482
1568
  });
1483
1569
  if (clientText || !dshAdapterEnabled) {
1484
1570
  log(`If MemoraX Code is not active ${existingSetup ? "on the next prompt" : "in new sessions"}, run ${statusCommands}.`);
@@ -1493,12 +1579,14 @@ function enabledClientText({
1493
1579
  claudeAdapterEnabled = true,
1494
1580
  opencodeAdapterEnabled = true,
1495
1581
  codebuddyAdapterEnabled = true,
1582
+ traeAdapterEnabled = true,
1496
1583
  } = {}) {
1497
1584
  const labels = [
1498
1585
  codexAdapterEnabled ? "Codex" : undefined,
1499
1586
  claudeAdapterEnabled ? "Claude Code" : undefined,
1500
1587
  opencodeAdapterEnabled ? "OpenCode" : undefined,
1501
1588
  codebuddyAdapterEnabled ? "CodeBuddy/WorkBuddy" : undefined,
1589
+ traeAdapterEnabled ? "Trae" : undefined,
1502
1590
  ].filter(Boolean);
1503
1591
  if (labels.length < 2) return labels[0] ?? "";
1504
1592
  if (labels.length === 2) return `${labels[0]} or ${labels[1]}`;
@@ -1510,12 +1598,14 @@ function statusCommandText({
1510
1598
  claudeAdapterEnabled = true,
1511
1599
  opencodeAdapterEnabled = true,
1512
1600
  codebuddyAdapterEnabled = true,
1601
+ traeAdapterEnabled = true,
1513
1602
  } = {}) {
1514
1603
  const commands = ["`memorax-code status`"];
1515
1604
  if (codexAdapterEnabled) commands.push("`memorax-code-codex status`");
1516
1605
  if (claudeAdapterEnabled) commands.push("`memorax-code-claude status`");
1517
1606
  if (opencodeAdapterEnabled) commands.push("`memorax-code-opencode status`");
1518
1607
  if (codebuddyAdapterEnabled) commands.push("`memorax-code-codebuddy status`");
1608
+ if (traeAdapterEnabled) commands.push("`memorax-code-trae status`");
1519
1609
  if (commands.length === 1) return commands[0];
1520
1610
  if (commands.length === 2) return `${commands[0]} and ${commands[1]}`;
1521
1611
  return `${commands.slice(0, -1).join(", ")}, and ${commands.at(-1)}`;
@@ -1595,19 +1685,21 @@ function readMemoraxInstallStatus() {
1595
1685
  }
1596
1686
  }
1597
1687
 
1598
- function printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason, codebuddySkipReason } = {}) {
1688
+ function printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason, codebuddySkipReason, traeSkipReason } = {}) {
1599
1689
  logRed("MemoraX Code is not enabled for new client sessions.");
1600
- logRed("Check `memorax-code status`, the selected adapter status commands, and `memorax-code-codebuddy status` for Backend and integration details.");
1601
- logRed("If Codex, Claude Code, OpenCode, CodeBuddy/WorkBuddy, or DeepSeek Harness is open, restart or refresh it after fixing the reported status.");
1690
+ logRed("Check `memorax-code status` and the selected adapter status commands for Backend and integration details.");
1691
+ logRed("If Codex, Claude Code, OpenCode, CodeBuddy/WorkBuddy, Trae, or DeepSeek Harness is open, restart or refresh it after fixing the reported status.");
1602
1692
  if (codexSkipReason) printCodexSkippedDiagnostics(codexSkipReason);
1603
1693
  if (claudeSkipReason) printClaudeSkippedDiagnostics(claudeSkipReason);
1604
1694
  if (opencodeSkipReason) printOpenCodeSkippedDiagnostics(opencodeSkipReason);
1605
1695
  if (codebuddySkipReason) printCodeBuddySkippedDiagnostics(codebuddySkipReason);
1696
+ if (traeSkipReason) printTraeSkippedDiagnostics(traeSkipReason);
1606
1697
  printCommonCommands({
1607
1698
  codexAdapterEnabled: !codexSkipReason,
1608
1699
  claudeAdapterEnabled: !claudeSkipReason,
1609
1700
  opencodeAdapterEnabled: !opencodeSkipReason,
1610
1701
  codebuddyAdapterEnabled: !codebuddySkipReason,
1702
+ traeAdapterEnabled: !traeSkipReason,
1611
1703
  });
1612
1704
  }
1613
1705
 
@@ -1633,6 +1725,11 @@ function printCodeBuddySkippedDiagnostics() {
1633
1725
  log("Run `memorax-code start --clients codebuddy` after installing CodeBuddy/WorkBuddy, then restart or refresh it.");
1634
1726
  }
1635
1727
 
1728
+ function printTraeSkippedDiagnostics() {
1729
+ logRed("Trae adapter setup was skipped for this setup, so MemoraX Code left Trae unchanged.");
1730
+ log("Run `memorax-code start --clients trae` after installing Trae, then enable Global Hooks in Trae Settings and start a new session.");
1731
+ }
1732
+
1636
1733
  function printFailureSuggestions() {
1637
1734
  logRed("Suggested recovery: run `memorax-code stop`, then `memorax-code start`, then `memorax-code status`.");
1638
1735
  logRed("If the Backend port is busy, stop the process using 127.0.0.1:8787 and retry `memorax-code start`.");
@@ -1663,6 +1760,7 @@ function printCommonCommands({
1663
1760
  claudeAdapterEnabled = true,
1664
1761
  opencodeAdapterEnabled = true,
1665
1762
  codebuddyAdapterEnabled = true,
1763
+ traeAdapterEnabled = true,
1666
1764
  } = {}) {
1667
1765
  log("Common commands:");
1668
1766
  log("- `memorax-code status`: check the local backend and adapter state.");
@@ -1673,6 +1771,7 @@ function printCommonCommands({
1673
1771
  if (claudeAdapterEnabled) log("- `memorax-code-claude sessions`: verify recent native Claude Code session registration.");
1674
1772
  if (opencodeAdapterEnabled) log("- `memorax-code-opencode doctor`: verify the managed OpenCode plugin, runtime evidence, and Backend health.");
1675
1773
  if (codebuddyAdapterEnabled) log("- `memorax-code-codebuddy status`: verify the managed CodeBuddy/WorkBuddy plugin and Hook integration.");
1774
+ if (traeAdapterEnabled) log("- `memorax-code-trae status`: verify the managed Trae Global Hooks and Skill integration.");
1676
1775
  }
1677
1776
 
1678
1777
  function memoraxCodeEnabled(statusResult, {
@@ -1680,6 +1779,7 @@ function memoraxCodeEnabled(statusResult, {
1680
1779
  claudeAdapterRequired = true,
1681
1780
  opencodeAdapterRequired = true,
1682
1781
  codebuddyAdapterRequired = true,
1782
+ traeAdapterRequired = true,
1683
1783
  } = {}) {
1684
1784
  const output = `${statusResult.stdout ?? ""}\n${statusResult.stderr ?? ""}`;
1685
1785
  const normalized = stripAnsi(output);
@@ -1692,12 +1792,14 @@ function memoraxCodeEnabled(statusResult, {
1692
1792
  const claudeAdapterOk = /Claude adapter:\s*ok\b/im.test(normalized);
1693
1793
  const opencodeAdapterOk = /OpenCode adapter:\s*ok\b/im.test(normalized);
1694
1794
  const codebuddyAdapterOk = /CodeBuddy adapter:\s*ok\b/im.test(normalized);
1795
+ const traeAdapterOk = /Trae adapter:\s*ok\b/im.test(normalized);
1695
1796
  return backendOk
1696
1797
  && serviceOk
1697
1798
  && (!codexAdapterRequired || codexAdapterOk)
1698
1799
  && (!claudeAdapterRequired || claudeAdapterOk)
1699
1800
  && (!opencodeAdapterRequired || opencodeAdapterOk)
1700
- && (!codebuddyAdapterRequired || codebuddyAdapterOk);
1801
+ && (!codebuddyAdapterRequired || codebuddyAdapterOk)
1802
+ && (!traeAdapterRequired || traeAdapterOk);
1701
1803
  }
1702
1804
 
1703
1805
  function log(message) {
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runTraeAdapterCli } from "../lib/run-entrypoint.mjs";
3
+
4
+ await runTraeAdapterCli();