@memorax/memorax-code 0.1.11 → 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.
- package/README.md +7 -4
- package/bin/memorax-code-setup.mjs +136 -34
- package/bin/memorax-code-trae.mjs +4 -0
- package/docs/configuration.md +106 -52
- package/docs/troubleshooting.md +45 -6
- package/lib/memorax-code-backend/dist/clients/claude/transcript-turn.js +2 -2
- package/lib/memorax-code-backend/dist/clients/codex/rollout-turn.js +1 -1
- package/lib/memorax-code-backend/dist/clients/trae/lifecycle.js +53 -0
- package/lib/memorax-code-backend/dist/clients/trae/memory-hook-runtime.js +302 -0
- package/lib/memorax-code-backend/dist/clients/trae/turn-id.js +16 -0
- package/lib/memorax-code-backend/dist/config/memorax-code.js +14 -1
- package/lib/memorax-code-backend/dist/entrypoints/backend-cli.js +22 -4
- package/lib/memorax-code-backend/dist/lifecycle/active-clients.js +3 -0
- package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +14 -2
- package/lib/memorax-code-backend/dist/lifecycle/client-selection.js +5 -3
- package/lib/memorax-code-backend/dist/lifecycle/orchestrator.js +62 -9
- package/lib/memorax-code-backend/dist/memory/hook-command.js +34 -2
- package/lib/memorax-code-backend/dist/memory/reminder-trace-recorder.js +5 -1
- package/lib/memorax-code-backend/dist/memory/service.js +12 -0
- package/lib/memorax-code-backend/dist/trace/config.js +12 -1
- package/lib/memorax-code-backend/dist/trace/context.js +26 -1
- package/lib/memorax-code-backend/package.json +1 -1
- package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
- package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-claude-adapter/package.json +1 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-codebuddy-adapter/.codebuddy-plugin/plugin.json +1 -1
- package/lib/memorax-code-codebuddy-adapter/package.json +1 -1
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
- package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-codex-adapter/package.json +1 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-dsh-adapter/package.json +1 -1
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-opencode-adapter/package.json +1 -1
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +3 -1
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +16 -3
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +15 -2
- package/lib/memorax-code-trae-adapter/hooks/runtime-hook.mjs +340 -0
- package/lib/memorax-code-trae-adapter/package.json +9 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/SKILL.md +87 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/defaults.json +12 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/memorax-add.md +101 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/memorax-search.md +106 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/personal-write.md +120 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-build.md +319 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-read.md +103 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-templates.md +390 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/references/repo-update.md +127 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-trae-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
- package/lib/memorax-code-trae-adapter/src/adapter-paths.mjs +69 -0
- package/lib/memorax-code-trae-adapter/src/cli.mjs +59 -0
- package/lib/memorax-code-trae-adapter/src/config.mjs +630 -0
- package/lib/memorax-code-trae-adapter/src/runtime-observation.mjs +55 -0
- package/lib/run-entrypoint.mjs +6 -0
- 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,
|
|
4
|
-
Harness, and
|
|
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,
|
|
10
|
-
|
|
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
|
|
72
|
-
const existingSetup =
|
|
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 =
|
|
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
|
-
?
|
|
162
|
+
? requestedClients.filter((client) => (
|
|
163
|
+
previousClients.includes(client) || newlyDetectedClients.includes(client)
|
|
164
|
+
))
|
|
146
165
|
: existingSetup
|
|
147
|
-
? await chooseUpdateClients(previousClients,
|
|
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 (
|
|
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,
|
|
413
|
+
async function chooseUpdateClients(previousClients, newlyDetectedClients, scriptedAnswers) {
|
|
375
414
|
const selected = new Set(previousClients);
|
|
376
|
-
|
|
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
|
|
419
|
+
for (const client of newlyDetectedClients) {
|
|
382
420
|
const label = clientLabel(client);
|
|
383
|
-
const question = `${label} runtime is
|
|
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
|
|
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
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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
|
-
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
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 ===
|
|
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
|
|
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) {
|