@memorax/memorax-code 0.1.9 → 0.1.11
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 +10 -0
- package/bin/memorax-code-codebuddy.mjs +4 -0
- package/bin/memorax-code-setup.mjs +182 -65
- package/bin/memorax-code.mjs +74 -45
- package/docs/configuration.md +85 -22
- package/docs/troubleshooting.md +72 -5
- package/lib/automatic-update.mjs +233 -0
- package/lib/memorax-code-adapter-common/src/automatic-update-state.d.mts +24 -0
- package/lib/memorax-code-adapter-common/src/automatic-update-state.mjs +73 -0
- package/lib/memorax-code-adapter-common/src/clients/codebuddy-command.mjs +82 -0
- package/lib/memorax-code-adapter-common/src/config-utils.d.mts +2 -0
- package/lib/memorax-code-adapter-common/src/config-utils.mjs +11 -0
- package/lib/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +3 -0
- package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +45 -10
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +88 -3
- package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +11 -1
- package/lib/memorax-code-backend/dist/app/backend-server.js +2 -2
- package/lib/memorax-code-backend/dist/app/memory-observability.js +2 -2
- package/lib/memorax-code-backend/dist/clients/codebuddy/jsonl-history.js +208 -0
- package/lib/memorax-code-backend/dist/clients/codebuddy/lifecycle.js +44 -0
- package/lib/memorax-code-backend/dist/clients/codebuddy/memory-hook-runtime.js +250 -0
- package/lib/memorax-code-backend/dist/clients/codebuddy/turn-id.js +16 -0
- package/lib/memorax-code-backend/dist/clients/codex/plugin-install.js +129 -7
- package/lib/memorax-code-backend/dist/config/memorax-code.js +14 -1
- package/lib/memorax-code-backend/dist/entrypoints/backend-cli.js +43 -6
- package/lib/memorax-code-backend/dist/lifecycle/active-clients.js +3 -0
- package/lib/memorax-code-backend/dist/lifecycle/automatic-update-scheduler.js +133 -0
- package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +14 -2
- package/lib/memorax-code-backend/dist/lifecycle/client-selection.js +6 -4
- package/lib/memorax-code-backend/dist/lifecycle/orchestrator.js +48 -9
- package/lib/memorax-code-backend/dist/memory/cli.js +4 -2
- package/lib/memorax-code-backend/dist/memory/hook-command.js +31 -1
- 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/shared/windows-cli-invocation.js +10 -1
- package/lib/memorax-code-backend/dist/trace/config.js +12 -0
- package/lib/memorax-code-backend/dist/trace/context.js +21 -1
- package/lib/memorax-code-backend/dist/trace/store.js +12 -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/runtime-hooks/ensure-backend.mjs +2 -0
- package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +3 -0
- 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/memorax-code-adapter-common/src/automatic-update-state.d.mts +24 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/automatic-update-state.mjs +73 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codebuddy-command.mjs +82 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.d.mts +2 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.mjs +11 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +3 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +45 -10
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +88 -3
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +11 -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/runtime-hooks/ensure-backend.mjs +2 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +3 -0
- package/lib/memorax-code-codebuddy-adapter/.codebuddy-plugin/plugin.json +7 -0
- package/lib/memorax-code-codebuddy-adapter/hooks/common-runtime.mjs +13 -0
- package/lib/memorax-code-codebuddy-adapter/hooks/hooks.json +38 -0
- package/lib/memorax-code-codebuddy-adapter/hooks/repo-memory-job.mjs +40 -0
- package/lib/memorax-code-codebuddy-adapter/hooks/runtime-hook.mjs +289 -0
- package/lib/memorax-code-codebuddy-adapter/package.json +9 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/SKILL.md +85 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/defaults.json +12 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-add.md +88 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/memorax-search.md +93 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/personal-write.md +120 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/repo-build.md +319 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/repo-read.md +103 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/repo-templates.md +390 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/references/repo-update.md +127 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-codebuddy-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
- package/lib/memorax-code-codebuddy-adapter/src/cli.mjs +58 -0
- package/lib/memorax-code-codebuddy-adapter/src/config.mjs +340 -0
- package/lib/memorax-code-codebuddy-adapter/src/hook-manifest.mjs +47 -0
- package/lib/memorax-code-codebuddy-adapter/src/runtime-observation.mjs +65 -0
- 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/runtime-hooks/ensure-backend.mjs +4 -1
- package/lib/memorax-code-dsh-adapter/package.json +2 -1
- package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1 -0
- package/lib/memorax-code-opencode-adapter/package.json +1 -1
- package/lib/npm-invocation.mjs +51 -8
- package/lib/resolve-codebuddy-command.mjs +123 -0
- package/lib/run-entrypoint.mjs +25 -1
- package/lib/windows-cli-invocation.mjs +11 -1
- package/lib/windows-user-path.mjs +218 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -54,6 +54,16 @@ Both setup paths automatically detect supported coding agents. Later setup
|
|
|
54
54
|
runs reuse a complete saved configuration; use
|
|
55
55
|
`memorax-code setup --reconfigure` to replace it.
|
|
56
56
|
|
|
57
|
+
On Windows, interactive setup also verifies npm's global command directory and
|
|
58
|
+
adds it to the current setup process and the Windows user `PATH` when needed.
|
|
59
|
+
If the current shell cannot find `memorax-code`, bootstrap setup with:
|
|
60
|
+
|
|
61
|
+
```powershell
|
|
62
|
+
$NpmGlobalBin = (npm prefix -g).Trim()
|
|
63
|
+
$env:Path = "$NpmGlobalBin;$env:Path"
|
|
64
|
+
& (Join-Path $NpmGlobalBin "memorax-code.cmd") setup
|
|
65
|
+
```
|
|
66
|
+
|
|
57
67
|
After the first installation, restart or refresh the detected coding agents
|
|
58
68
|
before opening a new session. In Codex, enable **MemoraX Code Codex Adapter**
|
|
59
69
|
from Plugins or `/plugins` if it is not already enabled.
|
|
@@ -21,6 +21,7 @@ import { stagePackagedClientHookRuntime } from "../lib/client-hook-runtime.mjs";
|
|
|
21
21
|
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
|
+
import { defaultCodeBuddyHome, ensureCodeBuddyCommandEnv } from "../lib/resolve-codebuddy-command.mjs";
|
|
24
25
|
import { reconcileSetup } from "../lib/setup-reconcile.mjs";
|
|
25
26
|
import { detectSetupMemoryPreferences } from "../lib/setup-memory-preferences.mjs";
|
|
26
27
|
import { ensureTrialSetupCredential } from "../lib/trial-setup.mjs";
|
|
@@ -44,12 +45,18 @@ const DSH_OPTIONAL_ENV = "MEMORAX_CODE_DSH_ADAPTER_OPTIONAL";
|
|
|
44
45
|
const skipCodexPluginInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CODEX_PLUGIN_INSTALL);
|
|
45
46
|
const skipClaudeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CLAUDE_ADAPTER_INSTALL);
|
|
46
47
|
const skipOpenCodeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_OPENCODE_ADAPTER_INSTALL);
|
|
48
|
+
const skipCodeBuddyAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CODEBUDDY_ADAPTER_INSTALL);
|
|
47
49
|
const updateMode = truthyEnv(process.env.MEMORAX_CODE_SETUP_UPDATE);
|
|
50
|
+
const automaticUpdateMode = truthyEnv(process.env.MEMORAX_CODE_SETUP_AUTOMATIC_UPDATE);
|
|
48
51
|
const setupMode = setupModeFromEnvironment(process.env.MEMORAX_CODE_SETUP_MODE);
|
|
49
52
|
if (!setupMode) {
|
|
50
53
|
logRed("Setup mode is invalid.");
|
|
51
54
|
process.exit(1);
|
|
52
55
|
}
|
|
56
|
+
if (automaticUpdateMode && !updateMode) {
|
|
57
|
+
logRed("Automatic update setup requires update mode.");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
53
60
|
|
|
54
61
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
55
62
|
const memoraxCodeBin = join(scriptDir, "memorax-code.mjs");
|
|
@@ -59,9 +66,12 @@ const codexRuntime = ensureCodexCommandEnv();
|
|
|
59
66
|
const codexCommand = codexRuntime.command;
|
|
60
67
|
const claudeRuntime = ensureClaudeCommandEnv();
|
|
61
68
|
const claudeCommand = claudeRuntime.command;
|
|
69
|
+
const codeBuddyRuntime = ensureCodeBuddyCommandEnv();
|
|
70
|
+
const codeBuddyCommand = codeBuddyRuntime.command;
|
|
62
71
|
const previousClients = readPersistedClientSelection();
|
|
63
72
|
const existingSetup = previousClients !== undefined;
|
|
64
73
|
const persistedDshSelection = readPersistedDshSelection();
|
|
74
|
+
const dshEnabledByConfig = persistedDshSelection !== false;
|
|
65
75
|
let dshProfiles = [];
|
|
66
76
|
let dshProfilesVerified = true;
|
|
67
77
|
try {
|
|
@@ -73,13 +83,17 @@ try {
|
|
|
73
83
|
}
|
|
74
84
|
const dshSelected = dshProfilesVerified
|
|
75
85
|
&& dshProfiles.length > 0
|
|
76
|
-
&&
|
|
77
|
-
if (!
|
|
86
|
+
&& dshEnabledByConfig;
|
|
87
|
+
if (automaticUpdateMode && !existingSetup) {
|
|
88
|
+
logRed("Automatic update setup requires an existing [clients] selection.");
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
if (!automaticUpdateMode && !canPromptOnStderr()) {
|
|
78
92
|
logRed("Setup requires an interactive terminal.");
|
|
79
93
|
log("Run `memorax-code setup` from a terminal, or use `memorax-code status` to inspect an existing setup.");
|
|
80
94
|
process.exit(1);
|
|
81
95
|
}
|
|
82
|
-
const scriptedAnswers = process.stdin.isTTY !== true
|
|
96
|
+
const scriptedAnswers = !automaticUpdateMode && process.stdin.isTTY !== true
|
|
83
97
|
? parseScriptedAnswers(readFileSync(0, "utf8"))
|
|
84
98
|
: undefined;
|
|
85
99
|
if (seedMissingMemoraxCodeConfig() === "failed") {
|
|
@@ -100,7 +114,7 @@ try {
|
|
|
100
114
|
process.exit(1);
|
|
101
115
|
}
|
|
102
116
|
runCommonPreflight();
|
|
103
|
-
const requestedClients = ["codex", "claude", "opencode"];
|
|
117
|
+
const requestedClients = ["codex", "claude", "opencode", "codebuddy"];
|
|
104
118
|
const codexPreflight = requestedClients.includes("codex") && !skipCodexPluginInstall
|
|
105
119
|
? runCodexPreflight({
|
|
106
120
|
integrationSelected: !existingSetup || previousClients.includes("codex"),
|
|
@@ -116,14 +130,22 @@ const opencodePreflight = requestedClients.includes("opencode") && !skipOpenCode
|
|
|
116
130
|
integrationSelected: !existingSetup || previousClients.includes("opencode"),
|
|
117
131
|
})
|
|
118
132
|
: { ok: true };
|
|
133
|
+
const codebuddyPreflight = requestedClients.includes("codebuddy") && !skipCodeBuddyAdapterInstall
|
|
134
|
+
? runCodeBuddyPreflight({
|
|
135
|
+
integrationSelected: !existingSetup || previousClients.includes("codebuddy"),
|
|
136
|
+
})
|
|
137
|
+
: { ok: true };
|
|
119
138
|
const detectedClients = requestedClients.filter((client) => {
|
|
120
139
|
if (client === "codex") return !skipCodexPluginInstall && codexPreflight.ok;
|
|
121
140
|
if (client === "claude") return !skipClaudeAdapterInstall && claudePreflight.ok;
|
|
122
|
-
return !skipOpenCodeAdapterInstall && opencodePreflight.ok;
|
|
141
|
+
if (client === "opencode") return !skipOpenCodeAdapterInstall && opencodePreflight.ok;
|
|
142
|
+
return !skipCodeBuddyAdapterInstall && codebuddyPreflight.ok;
|
|
123
143
|
});
|
|
124
|
-
const selectedClients =
|
|
125
|
-
?
|
|
126
|
-
:
|
|
144
|
+
const selectedClients = automaticUpdateMode
|
|
145
|
+
? previousClients
|
|
146
|
+
: existingSetup
|
|
147
|
+
? await chooseUpdateClients(previousClients, detectedClients, scriptedAnswers)
|
|
148
|
+
: detectedClients;
|
|
127
149
|
const installClients = detectedClients.filter((client) => selectedClients.includes(client));
|
|
128
150
|
if (existingSetup) {
|
|
129
151
|
log(clientSelectionMessage(selectedClients, { dshSelected }));
|
|
@@ -144,12 +166,16 @@ if (requestedClients.includes("claude") && !skipClaudeAdapterInstall && !claudeP
|
|
|
144
166
|
if (requestedClients.includes("opencode") && !skipOpenCodeAdapterInstall && !opencodePreflight.ok) {
|
|
145
167
|
log("OpenCode runtime or configuration was not detected; skipping its adapter setup.");
|
|
146
168
|
}
|
|
169
|
+
if (requestedClients.includes("codebuddy") && !skipCodeBuddyAdapterInstall && !codebuddyPreflight.ok) {
|
|
170
|
+
log("CodeBuddy/WorkBuddy runtime was not detected; skipping its adapter setup.");
|
|
171
|
+
}
|
|
147
172
|
if (writeClientSelectionConfig(selectedClients) === "failed") {
|
|
148
173
|
printPostinstallSummary("not-verified");
|
|
149
174
|
process.exit(1);
|
|
150
175
|
}
|
|
151
|
-
const
|
|
152
|
-
|
|
176
|
+
const lifecycleClients = automaticUpdateMode ? selectedClients : installClients;
|
|
177
|
+
const clientMode = clientModeFor(lifecycleClients, {
|
|
178
|
+
includeDsh: dshProfilesVerified && dshEnabledByConfig,
|
|
153
179
|
});
|
|
154
180
|
let memoraxConfigResult = "skipped";
|
|
155
181
|
if (!updateMode) {
|
|
@@ -179,11 +205,12 @@ if (memoraxConfigResult === "configured") {
|
|
|
179
205
|
const codexClientEnabled = installClients.includes("codex");
|
|
180
206
|
const claudeClientEnabled = installClients.includes("claude");
|
|
181
207
|
const opencodeClientEnabled = installClients.includes("opencode");
|
|
208
|
+
const codebuddyClientEnabled = installClients.includes("codebuddy");
|
|
182
209
|
const codexClientNewlyEnabled = codexClientEnabled
|
|
183
210
|
&& existingSetup
|
|
184
211
|
&& !previousClients.includes("codex");
|
|
185
212
|
const codexPluginRequiresActivation = codexClientEnabled
|
|
186
|
-
&& codexPreflight.
|
|
213
|
+
&& codexPreflight.pluginRegistration.ready !== true;
|
|
187
214
|
const codexHooksBeforeUpdate = codexClientEnabled
|
|
188
215
|
&& existingSetup
|
|
189
216
|
&& !codexClientNewlyEnabled
|
|
@@ -202,9 +229,19 @@ if (codexClientEnabled && result.status !== 0) {
|
|
|
202
229
|
|
|
203
230
|
if (codexClientEnabled && result.status === 0) {
|
|
204
231
|
if (existingSetup && (codexClientNewlyEnabled || codexPluginRequiresActivation)) {
|
|
205
|
-
activateCodexPluginHooks();
|
|
232
|
+
const activationResult = activateCodexPluginHooks();
|
|
233
|
+
if (automaticUpdateMode && activationResult !== "activated") {
|
|
234
|
+
logRed("Automatic update stopped because the current MemoraX Code Codex Hooks could not be activated and trusted.");
|
|
235
|
+
printPostinstallSummary("not-verified");
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
206
238
|
} else if (existingSetup) {
|
|
207
|
-
|
|
239
|
+
const trustResult = maybeTrustUpdatedCodexPluginHooks(codexHooksBeforeUpdate);
|
|
240
|
+
if (automaticUpdateMode && trustResult !== "trusted" && trustResult !== "unchanged") {
|
|
241
|
+
logRed("Automatic update stopped because the current MemoraX Code Codex Hooks could not be verified and trusted.");
|
|
242
|
+
printPostinstallSummary("not-verified");
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
208
245
|
} else {
|
|
209
246
|
activateCodexPluginHooks();
|
|
210
247
|
}
|
|
@@ -227,6 +264,11 @@ const opencodeSkipReason = setupClientSkipReason({
|
|
|
227
264
|
selected: selectedClients.includes("opencode"),
|
|
228
265
|
enabled: opencodeClientEnabled,
|
|
229
266
|
});
|
|
267
|
+
const codebuddySkipReason = setupClientSkipReason({
|
|
268
|
+
explicitlySkipped: skipCodeBuddyAdapterInstall,
|
|
269
|
+
selected: selectedClients.includes("codebuddy"),
|
|
270
|
+
enabled: codebuddyClientEnabled,
|
|
271
|
+
});
|
|
230
272
|
|
|
231
273
|
const backendAndAdapters = await startBackendAndCheck({
|
|
232
274
|
skipCodexAdapter,
|
|
@@ -238,6 +280,9 @@ const backendAndAdapters = await startBackendAndCheck({
|
|
|
238
280
|
skipOpenCodeAdapter,
|
|
239
281
|
opencodeAdapterRequired: !skipOpenCodeAdapter,
|
|
240
282
|
opencodeSkipReason,
|
|
283
|
+
skipCodeBuddyAdapter: !codebuddyClientEnabled,
|
|
284
|
+
codebuddyAdapterRequired: codebuddyClientEnabled,
|
|
285
|
+
codebuddySkipReason,
|
|
241
286
|
});
|
|
242
287
|
const backendAndAdaptersStatus = backendAndAdapters.status;
|
|
243
288
|
if (backendAndAdaptersStatus === "enabled") {
|
|
@@ -249,11 +294,13 @@ if (backendAndAdaptersStatus === "enabled") {
|
|
|
249
294
|
claudeAdapterEnabled: !skipClaudeAdapter,
|
|
250
295
|
dshAdapterEnabled: backendAndAdapters.dshAdapterEnabled,
|
|
251
296
|
opencodeAdapterEnabled: !skipOpenCodeAdapter,
|
|
297
|
+
codebuddyAdapterEnabled: codebuddyClientEnabled,
|
|
252
298
|
});
|
|
253
299
|
printCommonCommands({
|
|
254
300
|
codexAdapterEnabled: !skipCodexAdapter,
|
|
255
301
|
claudeAdapterEnabled: !skipClaudeAdapter,
|
|
256
302
|
opencodeAdapterEnabled: !skipOpenCodeAdapter,
|
|
303
|
+
codebuddyAdapterEnabled: codebuddyClientEnabled,
|
|
257
304
|
});
|
|
258
305
|
}
|
|
259
306
|
printPostinstallSummary(
|
|
@@ -352,7 +399,7 @@ async function chooseUpdateClients(previousClients, detectedClients, scriptedAns
|
|
|
352
399
|
} finally {
|
|
353
400
|
rl?.close();
|
|
354
401
|
}
|
|
355
|
-
return ["codex", "claude", "opencode"].filter((client) => selected.has(client));
|
|
402
|
+
return ["codex", "claude", "opencode", "codebuddy"].filter((client) => selected.has(client));
|
|
356
403
|
}
|
|
357
404
|
|
|
358
405
|
async function configureMemoraxMemoryFromAnswers(answers, detectedPreferences, {
|
|
@@ -552,7 +599,7 @@ function inspectCodexPluginHooksForUpdate() {
|
|
|
552
599
|
return report?.hooks;
|
|
553
600
|
}
|
|
554
601
|
|
|
555
|
-
|
|
602
|
+
function maybeTrustUpdatedCodexPluginHooks(previousHooks) {
|
|
556
603
|
if (!previousHooks) {
|
|
557
604
|
warnUpdatedHookTrustSkipped("Existing Codex hooks could not be inspected before the plugin cache refresh.");
|
|
558
605
|
return "skipped";
|
|
@@ -574,21 +621,6 @@ async function maybeTrustUpdatedCodexPluginHooks(scriptedAnswers, previousHooks)
|
|
|
574
621
|
if (report.hooks.length === 0) return "unchanged";
|
|
575
622
|
|
|
576
623
|
printUpdatedCodexHooks(report.hooks, previousHooks);
|
|
577
|
-
if (!canPromptForUpdate()) {
|
|
578
|
-
warnUpdatedHookTrustSkipped("This update is running without an interactive terminal, so the new or changed Hooks remain untrusted.");
|
|
579
|
-
return "skipped";
|
|
580
|
-
}
|
|
581
|
-
const answer = await updatedHookTrustAnswer(scriptedAnswers);
|
|
582
|
-
if (answer === undefined) {
|
|
583
|
-
warnUpdatedHookTrustSkipped("No Hook authorization response was received, so the new or changed Hooks remain untrusted.");
|
|
584
|
-
return "skipped";
|
|
585
|
-
}
|
|
586
|
-
const normalizedAnswer = answer.trim();
|
|
587
|
-
if (normalizedAnswer && !/^y(?:es)?$/i.test(normalizedAnswer)) {
|
|
588
|
-
warnUpdatedHookTrustSkipped("Hook authorization was declined, so the new or changed Hooks remain untrusted.");
|
|
589
|
-
return "skipped";
|
|
590
|
-
}
|
|
591
|
-
|
|
592
624
|
const trustEnv = hookTrustCommandEnv(HOOK_TRUST_SELECTION_ENV, report.hooks);
|
|
593
625
|
const trusted = runNodeMemoraxCodeCommand(codexPluginHookArgs("trust-hooks", ["--yes"]), {
|
|
594
626
|
env: trustEnv,
|
|
@@ -598,7 +630,7 @@ async function maybeTrustUpdatedCodexPluginHooks(scriptedAnswers, previousHooks)
|
|
|
598
630
|
logGreen(`Trusted ${report.hooks.length} new or changed MemoraX Code Codex Hook${report.hooks.length === 1 ? "" : "s"}.`);
|
|
599
631
|
return "trusted";
|
|
600
632
|
}
|
|
601
|
-
warnUpdatedHookTrustSkipped("The
|
|
633
|
+
warnUpdatedHookTrustSkipped("The verified Hooks changed again or could not be written to Codex config.");
|
|
602
634
|
return "failed";
|
|
603
635
|
}
|
|
604
636
|
|
|
@@ -659,7 +691,7 @@ function hookTrustCommandEnv(name, hooks) {
|
|
|
659
691
|
|
|
660
692
|
function printUpdatedCodexHooks(hooks, previousHooks) {
|
|
661
693
|
const previousByKey = new Map(previousHooks.map((hook) => [hook.key, hook.currentHash]));
|
|
662
|
-
log("This MemoraX Code update includes new or changed Codex Hooks that
|
|
694
|
+
log("This MemoraX Code update includes new or changed Codex Hooks that will be trusted automatically after verification:");
|
|
663
695
|
for (const hook of hooks) {
|
|
664
696
|
const change = previousByKey.has(hook.key) ? "changed" : "new";
|
|
665
697
|
const label = hook.statusMessage ? ` (${hook.statusMessage})` : "";
|
|
@@ -669,19 +701,6 @@ function printUpdatedCodexHooks(hooks, previousHooks) {
|
|
|
669
701
|
}
|
|
670
702
|
}
|
|
671
703
|
|
|
672
|
-
async function updatedHookTrustAnswer(scriptedAnswers) {
|
|
673
|
-
if (scriptedAnswers) {
|
|
674
|
-
log("Trust these new or changed Codex Hooks? [Y/n]");
|
|
675
|
-
return scriptedAnswers.shift();
|
|
676
|
-
}
|
|
677
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
678
|
-
try {
|
|
679
|
-
return await rl.question(`${PREFIX} Trust these new or changed Codex Hooks? [Y/n] `);
|
|
680
|
-
} finally {
|
|
681
|
-
rl.close();
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
704
|
function parseScriptedAnswers(input) {
|
|
686
705
|
if (input.length === 0) return [];
|
|
687
706
|
const answers = input.split(/\r?\n/);
|
|
@@ -704,10 +723,6 @@ function activateCodexPluginHooks() {
|
|
|
704
723
|
return "failed";
|
|
705
724
|
}
|
|
706
725
|
|
|
707
|
-
function canPromptForUpdate() {
|
|
708
|
-
return canPromptOnStderr();
|
|
709
|
-
}
|
|
710
|
-
|
|
711
726
|
function canPromptOnStderr() {
|
|
712
727
|
return process.env.MEMORAX_CODE_SETUP_ASSUME_INTERACTIVE === "1"
|
|
713
728
|
|| (process.stdin.isTTY === true && process.stderr.isTTY === true);
|
|
@@ -742,6 +757,7 @@ function readPersistedClientSelection() {
|
|
|
742
757
|
clients.codex ? "codex" : undefined,
|
|
743
758
|
clients.claude ? "claude" : undefined,
|
|
744
759
|
clients.opencode === true ? "opencode" : undefined,
|
|
760
|
+
clients.codebuddy === true ? "codebuddy" : undefined,
|
|
745
761
|
].filter(Boolean);
|
|
746
762
|
} catch {
|
|
747
763
|
return undefined;
|
|
@@ -773,7 +789,8 @@ function writeClientSelectionConfig(clients) {
|
|
|
773
789
|
function setManagedClientSelection(text, clients) {
|
|
774
790
|
const withOpenCode = setTomlField(text, "clients", "opencode", String(clients.includes("opencode")));
|
|
775
791
|
const withClaude = setTomlField(withOpenCode, "clients", "claude", String(clients.includes("claude")));
|
|
776
|
-
|
|
792
|
+
const withCodeBuddy = setTomlField(withClaude, "clients", "codebuddy", String(clients.includes("codebuddy")));
|
|
793
|
+
return setTomlField(withCodeBuddy, "clients", "codex", String(clients.includes("codex")));
|
|
777
794
|
}
|
|
778
795
|
|
|
779
796
|
function writeMemoraxConfig({ userId, endpoint, outputLanguage, apiKey }) {
|
|
@@ -826,6 +843,7 @@ function defaultMemoraxCodeConfig() {
|
|
|
826
843
|
"claude = true # Manage the Claude adapter.",
|
|
827
844
|
"dsh = true # Manage the DeepSeek Harness adapter when Profiles exist.",
|
|
828
845
|
"opencode = true # Manage the OpenCode adapter.",
|
|
846
|
+
"codebuddy = true # Manage the CodeBuddy/WorkBuddy adapter.",
|
|
829
847
|
"",
|
|
830
848
|
"# MemoraX remote-memory connection.",
|
|
831
849
|
"[memorax]",
|
|
@@ -871,6 +889,10 @@ function defaultMemoraxCodeConfig() {
|
|
|
871
889
|
"enabled = true # Enable local OpenCode session memory trace collection.",
|
|
872
890
|
"capture_content = true # Store content in local OpenCode trace events.",
|
|
873
891
|
"",
|
|
892
|
+
"[trace.codebuddy]",
|
|
893
|
+
"enabled = true # Enable local CodeBuddy session memory trace collection.",
|
|
894
|
+
"capture_content = true # Store content in local CodeBuddy trace events.",
|
|
895
|
+
"",
|
|
874
896
|
].join("\n");
|
|
875
897
|
}
|
|
876
898
|
|
|
@@ -940,6 +962,9 @@ function runCommonPreflight() {
|
|
|
940
962
|
if (skipOpenCodeAdapterInstall) {
|
|
941
963
|
log("OpenCode adapter setup is disabled for this setup; other client setup can still continue.");
|
|
942
964
|
}
|
|
965
|
+
if (skipCodeBuddyAdapterInstall) {
|
|
966
|
+
log("CodeBuddy/WorkBuddy adapter setup is disabled for this setup; other client setup can still continue.");
|
|
967
|
+
}
|
|
943
968
|
return {};
|
|
944
969
|
}
|
|
945
970
|
|
|
@@ -956,11 +981,21 @@ function runCodexPreflight({ integrationSelected = true } = {}) {
|
|
|
956
981
|
}
|
|
957
982
|
const pluginCache = installedPluginCache();
|
|
958
983
|
log(`Existing Codex plugin cache: ${pluginCache.versions.length > 0 ? `found (${pluginCache.versions.join(", ")})` : "not installed"}`);
|
|
984
|
+
const pluginRegistration = inspectCodexPluginRegistrationForSetup();
|
|
985
|
+
if (!pluginRegistration.verified) {
|
|
986
|
+
log("Codex plugin state: could not be verified; setup will attempt a full activation.");
|
|
987
|
+
} else if (!pluginRegistration.registered) {
|
|
988
|
+
log("Codex plugin state: not installed in Codex; setup will repair it.");
|
|
989
|
+
} else if (!pluginRegistration.enabled) {
|
|
990
|
+
log("Codex plugin state: disabled; setup will attempt to enable it.");
|
|
991
|
+
} else {
|
|
992
|
+
log(`Codex plugin state: enabled${pluginRegistration.version ? ` (${pluginRegistration.version})` : ""}.`);
|
|
993
|
+
}
|
|
959
994
|
log(`Codex client process: ${codexClientRunning() ? "running" : "not detected"}`);
|
|
960
995
|
log(integrationSelected
|
|
961
996
|
? "Keeping Codex provider config unchanged and enabling the shared memory hook integration."
|
|
962
997
|
: "Keeping Codex provider config unchanged while checking whether to enable its integration.");
|
|
963
|
-
return { ok: true, pluginCache };
|
|
998
|
+
return { ok: true, pluginCache, pluginRegistration };
|
|
964
999
|
}
|
|
965
1000
|
|
|
966
1001
|
function runClaudePreflight({ integrationSelected = true } = {}) {
|
|
@@ -999,6 +1034,25 @@ function runOpenCodePreflight({ integrationSelected = true } = {}) {
|
|
|
999
1034
|
return { ok: true };
|
|
1000
1035
|
}
|
|
1001
1036
|
|
|
1037
|
+
function runCodeBuddyPreflight({ integrationSelected = true } = {}) {
|
|
1038
|
+
const version = runExternalCommand(codeBuddyCommand, ["--version"], { print: false, timeout: 10_000 });
|
|
1039
|
+
const runtimeLabel = codeBuddyRuntime.source === "app-bundled"
|
|
1040
|
+
? "WorkBuddy App CodeBuddy runtime"
|
|
1041
|
+
: codeBuddyRuntime.source === "path"
|
|
1042
|
+
? "CodeBuddy CLI"
|
|
1043
|
+
: codeBuddyRuntime.source === "configured"
|
|
1044
|
+
? "Configured CodeBuddy runtime"
|
|
1045
|
+
: "CodeBuddy CLI";
|
|
1046
|
+
log(`${runtimeLabel}: ${commandSummary(version) ?? "not runnable"}`);
|
|
1047
|
+
const home = defaultCodeBuddyHome();
|
|
1048
|
+
log(`WorkBuddy data directory: ${existsSync(home) ? "found" : "not detected"}`);
|
|
1049
|
+
if (version.status !== 0) return { ok: false };
|
|
1050
|
+
log(integrationSelected
|
|
1051
|
+
? "Keeping CodeBuddy provider config unchanged and enabling the shared memory Hook integration."
|
|
1052
|
+
: "Keeping CodeBuddy provider config unchanged while checking whether to enable its integration.");
|
|
1053
|
+
return { ok: true };
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1002
1056
|
function installedPluginCache() {
|
|
1003
1057
|
for (const marketplaceName of [CLI_MARKETPLACE_NAME, PERSONAL_MARKETPLACE_NAME]) {
|
|
1004
1058
|
const versions = installedPluginCacheVersions(marketplaceName);
|
|
@@ -1009,6 +1063,38 @@ function installedPluginCache() {
|
|
|
1009
1063
|
return { marketplaceName: CLI_MARKETPLACE_NAME, versions: [] };
|
|
1010
1064
|
}
|
|
1011
1065
|
|
|
1066
|
+
function inspectCodexPluginRegistrationForSetup() {
|
|
1067
|
+
const result = runNodeMemoraxCodeCommand(["codex-plugin", "registration", "--json"], {
|
|
1068
|
+
print: false,
|
|
1069
|
+
timeout: 10_000,
|
|
1070
|
+
});
|
|
1071
|
+
if (result.status !== 0) {
|
|
1072
|
+
return { verified: false, ready: false, registered: false, enabled: false };
|
|
1073
|
+
}
|
|
1074
|
+
try {
|
|
1075
|
+
const report = JSON.parse(String(result.stdout ?? ""));
|
|
1076
|
+
if (!report
|
|
1077
|
+
|| report.ok !== true
|
|
1078
|
+
|| report.action !== "codex-plugin-registration"
|
|
1079
|
+
|| typeof report.available !== "boolean"
|
|
1080
|
+
|| typeof report.registered !== "boolean"
|
|
1081
|
+
|| typeof report.enabled !== "boolean"
|
|
1082
|
+
|| (report.version !== undefined && typeof report.version !== "string")) {
|
|
1083
|
+
return { verified: false, ready: false, registered: false, enabled: false };
|
|
1084
|
+
}
|
|
1085
|
+
return {
|
|
1086
|
+
verified: true,
|
|
1087
|
+
ready: report.registered && report.enabled,
|
|
1088
|
+
available: report.available,
|
|
1089
|
+
registered: report.registered,
|
|
1090
|
+
enabled: report.enabled,
|
|
1091
|
+
...(report.version ? { version: report.version } : {}),
|
|
1092
|
+
};
|
|
1093
|
+
} catch {
|
|
1094
|
+
return { verified: false, ready: false, registered: false, enabled: false };
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1012
1098
|
function installedPluginCacheVersions(marketplaceName) {
|
|
1013
1099
|
const cacheRoot = join(codexHome(), "plugins", "cache", marketplaceName, PLUGIN_NAME);
|
|
1014
1100
|
if (!existsSync(cacheRoot)) return [];
|
|
@@ -1032,6 +1118,9 @@ async function startBackendAndCheck({
|
|
|
1032
1118
|
skipOpenCodeAdapter = false,
|
|
1033
1119
|
opencodeAdapterRequired = !skipOpenCodeAdapter,
|
|
1034
1120
|
opencodeSkipReason,
|
|
1121
|
+
skipCodeBuddyAdapter = false,
|
|
1122
|
+
codebuddyAdapterRequired = !skipCodeBuddyAdapter,
|
|
1123
|
+
codebuddySkipReason,
|
|
1035
1124
|
} = {}) {
|
|
1036
1125
|
const adapterFlags = clientLifecycleFlags({ clientMode });
|
|
1037
1126
|
const startArgs = ["start", ...adapterFlags];
|
|
@@ -1052,6 +1141,7 @@ async function startBackendAndCheck({
|
|
|
1052
1141
|
codexAdapterRequired: !skipCodexAdapter,
|
|
1053
1142
|
claudeAdapterRequired,
|
|
1054
1143
|
opencodeAdapterRequired,
|
|
1144
|
+
codebuddyAdapterRequired,
|
|
1055
1145
|
}),
|
|
1056
1146
|
onEvent: (event) => {
|
|
1057
1147
|
if (event.type === "start" && event.attempt === 1) {
|
|
@@ -1082,6 +1172,8 @@ async function startBackendAndCheck({
|
|
|
1082
1172
|
claudeSkipReason,
|
|
1083
1173
|
skipOpenCodeAdapter,
|
|
1084
1174
|
opencodeSkipReason,
|
|
1175
|
+
skipCodeBuddyAdapter,
|
|
1176
|
+
codebuddySkipReason,
|
|
1085
1177
|
});
|
|
1086
1178
|
}
|
|
1087
1179
|
},
|
|
@@ -1104,6 +1196,8 @@ function printReconcileFailure(result, {
|
|
|
1104
1196
|
claudeSkipReason,
|
|
1105
1197
|
skipOpenCodeAdapter,
|
|
1106
1198
|
opencodeSkipReason,
|
|
1199
|
+
skipCodeBuddyAdapter,
|
|
1200
|
+
codebuddySkipReason,
|
|
1107
1201
|
}) {
|
|
1108
1202
|
if (result.reason === "hook-runtime-activation-failed") {
|
|
1109
1203
|
logRed("Client Hook runtime activation failed; automatic lifecycle recovery was skipped.");
|
|
@@ -1121,6 +1215,7 @@ function printReconcileFailure(result, {
|
|
|
1121
1215
|
codexSkipReason,
|
|
1122
1216
|
claudeSkipReason,
|
|
1123
1217
|
opencodeSkipReason,
|
|
1218
|
+
codebuddySkipReason,
|
|
1124
1219
|
});
|
|
1125
1220
|
}
|
|
1126
1221
|
}
|
|
@@ -1157,10 +1252,10 @@ function clientLifecycleFlags({ clientMode = "all" } = {}) {
|
|
|
1157
1252
|
}
|
|
1158
1253
|
|
|
1159
1254
|
function clientModeFor(clients, { includeDsh = false } = {}) {
|
|
1160
|
-
const selected = ["codex", "claude", "dsh", "opencode"].filter((client) => (
|
|
1255
|
+
const selected = ["codex", "claude", "dsh", "opencode", "codebuddy"].filter((client) => (
|
|
1161
1256
|
client === "dsh" ? includeDsh : clients.includes(client)
|
|
1162
1257
|
));
|
|
1163
|
-
if (selected.length ===
|
|
1258
|
+
if (selected.length === 5) return "all";
|
|
1164
1259
|
return selected.length > 0 ? selected.join(",") : "none";
|
|
1165
1260
|
}
|
|
1166
1261
|
|
|
@@ -1177,26 +1272,29 @@ function clientSelectionMessage(clients, { dshSelected = false } = {}) {
|
|
|
1177
1272
|
clients.includes("claude") ? "Claude Code" : undefined,
|
|
1178
1273
|
"DeepSeek Harness",
|
|
1179
1274
|
clients.includes("opencode") ? "OpenCode" : undefined,
|
|
1275
|
+
clients.includes("codebuddy") ? "CodeBuddy/WorkBuddy" : undefined,
|
|
1180
1276
|
].filter(Boolean);
|
|
1181
1277
|
return `Configuring MemoraX Code for ${joinedLabels(labels)}.`;
|
|
1182
1278
|
}
|
|
1183
1279
|
const hasCodex = clients.includes("codex");
|
|
1184
1280
|
const hasClaude = clients.includes("claude");
|
|
1185
1281
|
const hasOpenCode = clients.includes("opencode");
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1282
|
+
const hasCodeBuddy = clients.includes("codebuddy");
|
|
1283
|
+
const labels = [
|
|
1284
|
+
hasCodex ? "Codex" : undefined,
|
|
1285
|
+
hasClaude ? "Claude Code" : undefined,
|
|
1286
|
+
hasOpenCode ? "OpenCode" : undefined,
|
|
1287
|
+
hasCodeBuddy ? "CodeBuddy/WorkBuddy" : undefined,
|
|
1288
|
+
].filter(Boolean);
|
|
1289
|
+
if (labels.length > 0) return `Configuring MemoraX Code for ${joinedLabels(labels)}.`;
|
|
1193
1290
|
return "Skipping client adapter setup for this setup.";
|
|
1194
1291
|
}
|
|
1195
1292
|
|
|
1196
1293
|
function clientLabel(client) {
|
|
1197
1294
|
if (client === "codex") return "Codex";
|
|
1198
1295
|
if (client === "claude") return "Claude Code";
|
|
1199
|
-
return "OpenCode";
|
|
1296
|
+
if (client === "opencode") return "OpenCode";
|
|
1297
|
+
return "CodeBuddy/WorkBuddy";
|
|
1200
1298
|
}
|
|
1201
1299
|
|
|
1202
1300
|
function detectedClientMessage(clients, dshProfiles = []) {
|
|
@@ -1354,11 +1452,13 @@ function printNextSteps({
|
|
|
1354
1452
|
claudeAdapterEnabled = true,
|
|
1355
1453
|
dshAdapterEnabled = false,
|
|
1356
1454
|
opencodeAdapterEnabled = true,
|
|
1455
|
+
codebuddyAdapterEnabled = true,
|
|
1357
1456
|
} = {}) {
|
|
1358
1457
|
const clientText = enabledClientText({
|
|
1359
1458
|
codexAdapterEnabled,
|
|
1360
1459
|
claudeAdapterEnabled,
|
|
1361
1460
|
opencodeAdapterEnabled,
|
|
1461
|
+
codebuddyAdapterEnabled,
|
|
1362
1462
|
});
|
|
1363
1463
|
if (clientText && existingSetup) {
|
|
1364
1464
|
logGreen(`${bold("The new Hook runtime is active")}; existing sessions with the stable shell select it on their next user prompt.`);
|
|
@@ -1378,6 +1478,7 @@ function printNextSteps({
|
|
|
1378
1478
|
codexAdapterEnabled,
|
|
1379
1479
|
claudeAdapterEnabled,
|
|
1380
1480
|
opencodeAdapterEnabled,
|
|
1481
|
+
codebuddyAdapterEnabled,
|
|
1381
1482
|
});
|
|
1382
1483
|
if (clientText || !dshAdapterEnabled) {
|
|
1383
1484
|
log(`If MemoraX Code is not active ${existingSetup ? "on the next prompt" : "in new sessions"}, run ${statusCommands}.`);
|
|
@@ -1391,11 +1492,13 @@ function enabledClientText({
|
|
|
1391
1492
|
codexAdapterEnabled = true,
|
|
1392
1493
|
claudeAdapterEnabled = true,
|
|
1393
1494
|
opencodeAdapterEnabled = true,
|
|
1495
|
+
codebuddyAdapterEnabled = true,
|
|
1394
1496
|
} = {}) {
|
|
1395
1497
|
const labels = [
|
|
1396
1498
|
codexAdapterEnabled ? "Codex" : undefined,
|
|
1397
1499
|
claudeAdapterEnabled ? "Claude Code" : undefined,
|
|
1398
1500
|
opencodeAdapterEnabled ? "OpenCode" : undefined,
|
|
1501
|
+
codebuddyAdapterEnabled ? "CodeBuddy/WorkBuddy" : undefined,
|
|
1399
1502
|
].filter(Boolean);
|
|
1400
1503
|
if (labels.length < 2) return labels[0] ?? "";
|
|
1401
1504
|
if (labels.length === 2) return `${labels[0]} or ${labels[1]}`;
|
|
@@ -1406,11 +1509,13 @@ function statusCommandText({
|
|
|
1406
1509
|
codexAdapterEnabled = true,
|
|
1407
1510
|
claudeAdapterEnabled = true,
|
|
1408
1511
|
opencodeAdapterEnabled = true,
|
|
1512
|
+
codebuddyAdapterEnabled = true,
|
|
1409
1513
|
} = {}) {
|
|
1410
1514
|
const commands = ["`memorax-code status`"];
|
|
1411
1515
|
if (codexAdapterEnabled) commands.push("`memorax-code-codex status`");
|
|
1412
1516
|
if (claudeAdapterEnabled) commands.push("`memorax-code-claude status`");
|
|
1413
1517
|
if (opencodeAdapterEnabled) commands.push("`memorax-code-opencode status`");
|
|
1518
|
+
if (codebuddyAdapterEnabled) commands.push("`memorax-code-codebuddy status`");
|
|
1414
1519
|
if (commands.length === 1) return commands[0];
|
|
1415
1520
|
if (commands.length === 2) return `${commands[0]} and ${commands[1]}`;
|
|
1416
1521
|
return `${commands.slice(0, -1).join(", ")}, and ${commands.at(-1)}`;
|
|
@@ -1490,17 +1595,19 @@ function readMemoraxInstallStatus() {
|
|
|
1490
1595
|
}
|
|
1491
1596
|
}
|
|
1492
1597
|
|
|
1493
|
-
function printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason } = {}) {
|
|
1598
|
+
function printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason, codebuddySkipReason } = {}) {
|
|
1494
1599
|
logRed("MemoraX Code is not enabled for new client sessions.");
|
|
1495
|
-
logRed("Check `memorax-code status`,
|
|
1496
|
-
logRed("If Codex, Claude Code, OpenCode, or DeepSeek Harness is open, restart or refresh it after fixing the reported status.");
|
|
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.");
|
|
1497
1602
|
if (codexSkipReason) printCodexSkippedDiagnostics(codexSkipReason);
|
|
1498
1603
|
if (claudeSkipReason) printClaudeSkippedDiagnostics(claudeSkipReason);
|
|
1499
1604
|
if (opencodeSkipReason) printOpenCodeSkippedDiagnostics(opencodeSkipReason);
|
|
1605
|
+
if (codebuddySkipReason) printCodeBuddySkippedDiagnostics(codebuddySkipReason);
|
|
1500
1606
|
printCommonCommands({
|
|
1501
1607
|
codexAdapterEnabled: !codexSkipReason,
|
|
1502
1608
|
claudeAdapterEnabled: !claudeSkipReason,
|
|
1503
1609
|
opencodeAdapterEnabled: !opencodeSkipReason,
|
|
1610
|
+
codebuddyAdapterEnabled: !codebuddySkipReason,
|
|
1504
1611
|
});
|
|
1505
1612
|
}
|
|
1506
1613
|
|
|
@@ -1521,6 +1628,11 @@ function printOpenCodeSkippedDiagnostics() {
|
|
|
1521
1628
|
log("Run `memorax-code start --clients opencode` after installing OpenCode, then restart or refresh OpenCode.");
|
|
1522
1629
|
}
|
|
1523
1630
|
|
|
1631
|
+
function printCodeBuddySkippedDiagnostics() {
|
|
1632
|
+
logRed("CodeBuddy/WorkBuddy adapter setup was skipped for this setup, so MemoraX Code left the CodeBuddy integration unchanged.");
|
|
1633
|
+
log("Run `memorax-code start --clients codebuddy` after installing CodeBuddy/WorkBuddy, then restart or refresh it.");
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1524
1636
|
function printFailureSuggestions() {
|
|
1525
1637
|
logRed("Suggested recovery: run `memorax-code stop`, then `memorax-code start`, then `memorax-code status`.");
|
|
1526
1638
|
logRed("If the Backend port is busy, stop the process using 127.0.0.1:8787 and retry `memorax-code start`.");
|
|
@@ -1550,6 +1662,7 @@ function printCommonCommands({
|
|
|
1550
1662
|
codexAdapterEnabled = true,
|
|
1551
1663
|
claudeAdapterEnabled = true,
|
|
1552
1664
|
opencodeAdapterEnabled = true,
|
|
1665
|
+
codebuddyAdapterEnabled = true,
|
|
1553
1666
|
} = {}) {
|
|
1554
1667
|
log("Common commands:");
|
|
1555
1668
|
log("- `memorax-code status`: check the local backend and adapter state.");
|
|
@@ -1559,12 +1672,14 @@ function printCommonCommands({
|
|
|
1559
1672
|
if (codexAdapterEnabled) log("- `memorax-code-codex sessions`: verify recent native Codex session registration.");
|
|
1560
1673
|
if (claudeAdapterEnabled) log("- `memorax-code-claude sessions`: verify recent native Claude Code session registration.");
|
|
1561
1674
|
if (opencodeAdapterEnabled) log("- `memorax-code-opencode doctor`: verify the managed OpenCode plugin, runtime evidence, and Backend health.");
|
|
1675
|
+
if (codebuddyAdapterEnabled) log("- `memorax-code-codebuddy status`: verify the managed CodeBuddy/WorkBuddy plugin and Hook integration.");
|
|
1562
1676
|
}
|
|
1563
1677
|
|
|
1564
1678
|
function memoraxCodeEnabled(statusResult, {
|
|
1565
1679
|
codexAdapterRequired = true,
|
|
1566
1680
|
claudeAdapterRequired = true,
|
|
1567
1681
|
opencodeAdapterRequired = true,
|
|
1682
|
+
codebuddyAdapterRequired = true,
|
|
1568
1683
|
} = {}) {
|
|
1569
1684
|
const output = `${statusResult.stdout ?? ""}\n${statusResult.stderr ?? ""}`;
|
|
1570
1685
|
const normalized = stripAnsi(output);
|
|
@@ -1576,11 +1691,13 @@ function memoraxCodeEnabled(statusResult, {
|
|
|
1576
1691
|
const codexAdapterOk = /Codex adapter:\s*ok\b/im.test(normalized);
|
|
1577
1692
|
const claudeAdapterOk = /Claude adapter:\s*ok\b/im.test(normalized);
|
|
1578
1693
|
const opencodeAdapterOk = /OpenCode adapter:\s*ok\b/im.test(normalized);
|
|
1694
|
+
const codebuddyAdapterOk = /CodeBuddy adapter:\s*ok\b/im.test(normalized);
|
|
1579
1695
|
return backendOk
|
|
1580
1696
|
&& serviceOk
|
|
1581
1697
|
&& (!codexAdapterRequired || codexAdapterOk)
|
|
1582
1698
|
&& (!claudeAdapterRequired || claudeAdapterOk)
|
|
1583
|
-
&& (!opencodeAdapterRequired || opencodeAdapterOk)
|
|
1699
|
+
&& (!opencodeAdapterRequired || opencodeAdapterOk)
|
|
1700
|
+
&& (!codebuddyAdapterRequired || codebuddyAdapterOk);
|
|
1584
1701
|
}
|
|
1585
1702
|
|
|
1586
1703
|
function log(message) {
|