@memorax/memorax-code 0.1.8 → 0.1.10
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 +82 -22
- package/docs/troubleshooting.md +69 -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/clients/codex/rollout-turn.js +52 -2
- 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 +279 -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 +277 -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 +112 -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
|
@@ -8,7 +8,8 @@ import { createBackendServer } from "../app/backend-server.js";
|
|
|
8
8
|
import { backendDebug } from "../shared/debug-log.js";
|
|
9
9
|
import { prepareClientPluginRemovalCleanup } from "../lifecycle/client-plugin-removal.js";
|
|
10
10
|
import { resolveBackendInstallWatchdogConfig, startBackendInstallWatchdog, } from "../lifecycle/install-watchdog.js";
|
|
11
|
-
import {
|
|
11
|
+
import { startBackendAutomaticUpdateScheduler, } from "../lifecycle/automatic-update-scheduler.js";
|
|
12
|
+
import { activateCodexPlugin, inspectCodexPluginRegistration, installCodexPlugin, } from "../clients/codex/plugin-install.js";
|
|
12
13
|
import { inspectCodexPluginHooks, trustCodexPluginHooks } from "../clients/codex/plugin-hooks.js";
|
|
13
14
|
import { collectMemoraxCodeStatus, isAdapterReady, isOptionalUnavailableDshAdapter, isOptionalUnconfiguredClaudeAdapter, restartMemoraxCodeService, startMemoraxCodeService, stopMemoraxCodeService, uninstallMemoraxCodeService, } from "../lifecycle/orchestrator.js";
|
|
14
15
|
import { backendEnv } from "../config/backend-env.js";
|
|
@@ -29,9 +30,9 @@ export function runBackendCli(argv = process.argv) {
|
|
|
29
30
|
`Usage: ${usageName} [${commands}] [--backend-url URL] [--backend-token TOKEN] [--home DIR]`,
|
|
30
31
|
"[--host HOST] [--port PORT] [--rotate] [--show]",
|
|
31
32
|
"[--codex-command CMD]",
|
|
32
|
-
"[--codex-home DIR] [--claude-home DIR] [--dsh-home DIR] [--opencode-config-dir DIR]",
|
|
33
|
+
"[--codex-home DIR] [--claude-home DIR] [--dsh-home DIR] [--opencode-config-dir DIR] [--codebuddy-home DIR]",
|
|
33
34
|
"[--dsh-command CMD] [--dsh-adapter-root DIR] [--memorax-code-command CMD]",
|
|
34
|
-
"[--clients codex|claude|dsh|opencode|CLIENT,...|all|none]",
|
|
35
|
+
"[--clients codex|claude|dsh|opencode|codebuddy|CLIENT,...|all|none]",
|
|
35
36
|
"[--json]",
|
|
36
37
|
"[--marketplace-path FILE] [--plugin-source-path DIR] [--claude-command CMD] [--help]",
|
|
37
38
|
"[--yes]",
|
|
@@ -210,12 +211,14 @@ async function startRawBackendServer(state, host, port, argv) {
|
|
|
210
211
|
dshHome: argValue(argv, "--dsh-home"),
|
|
211
212
|
dshAdapterRoot: argValue(argv, "--dsh-adapter-root"),
|
|
212
213
|
openCodeConfigDir: argValue(argv, "--opencode-config-dir"),
|
|
214
|
+
codeBuddyHome: argValue(argv, "--codebuddy-home"),
|
|
213
215
|
codexCommand: argValue(argv, "--codex-command"),
|
|
214
216
|
claudeCommand: argValue(argv, "--claude-command"),
|
|
215
217
|
dshCommand: argValue(argv, "--dsh-command"),
|
|
216
218
|
})
|
|
217
219
|
: undefined;
|
|
218
220
|
const server = createBackendServer(state);
|
|
221
|
+
let automaticUpdateScheduler;
|
|
219
222
|
let installRemovalStarted = false;
|
|
220
223
|
const installWatchdog = startBackendInstallWatchdog(installWatchdogConfig, async (event) => {
|
|
221
224
|
if (installRemovalStarted)
|
|
@@ -245,7 +248,10 @@ async function startRawBackendServer(state, host, port, argv) {
|
|
|
245
248
|
});
|
|
246
249
|
});
|
|
247
250
|
installBackendShutdownControls(server, state);
|
|
248
|
-
server.once("close", () =>
|
|
251
|
+
server.once("close", () => {
|
|
252
|
+
automaticUpdateScheduler?.close();
|
|
253
|
+
installWatchdog?.close();
|
|
254
|
+
});
|
|
249
255
|
server.on("error", (error) => {
|
|
250
256
|
if (error.code === "EADDRINUSE") {
|
|
251
257
|
console.error(`memorax-code-backend failed to listen on http://${host}:${port}: address already in use`);
|
|
@@ -258,6 +264,15 @@ async function startRawBackendServer(state, host, port, argv) {
|
|
|
258
264
|
});
|
|
259
265
|
server.listen(port, host, () => {
|
|
260
266
|
console.log(`memorax-code-backend listening on http://${host}:${port}`);
|
|
267
|
+
if (backendEnv("INSTANCE_ID")) {
|
|
268
|
+
automaticUpdateScheduler = startBackendAutomaticUpdateScheduler({
|
|
269
|
+
env: process.env,
|
|
270
|
+
memoraxCodeHome: state.sessionHome,
|
|
271
|
+
packageRoot: process.env.MEMORAX_CODE_NPM_PACKAGE_ROOT,
|
|
272
|
+
packageVersion: process.env.MEMORAX_CODE_NPM_PACKAGE_VERSION,
|
|
273
|
+
debug: (message) => backendDebug("automatic_update.scheduler_failed", { message }),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
261
276
|
});
|
|
262
277
|
}
|
|
263
278
|
function installBackendShutdownControls(server, state) {
|
|
@@ -382,6 +397,13 @@ async function runCodexPluginCommand(argv) {
|
|
|
382
397
|
yes: argv.includes("--yes"),
|
|
383
398
|
});
|
|
384
399
|
}
|
|
400
|
+
if (subcommand === "registration") {
|
|
401
|
+
return await inspectCodexPluginRegistration({
|
|
402
|
+
codexHome: argValue(argv, "--codex-home"),
|
|
403
|
+
codexCommand: argValue(argv, "--codex-command"),
|
|
404
|
+
workspace: argValue(argv, "--workspace"),
|
|
405
|
+
});
|
|
406
|
+
}
|
|
385
407
|
if (subcommand === "hooks") {
|
|
386
408
|
return await inspectCodexPluginHooks({
|
|
387
409
|
codexHome: argValue(argv, "--codex-home"),
|
|
@@ -427,6 +449,15 @@ function printCodexPluginInstallResult(report) {
|
|
|
427
449
|
console.log("backend: not started");
|
|
428
450
|
return;
|
|
429
451
|
}
|
|
452
|
+
if (report.action === "codex-plugin-registration") {
|
|
453
|
+
console.log(`codex home: ${report.codexHome}`);
|
|
454
|
+
console.log(`registered: ${report.registered ? "yes" : "no"}`);
|
|
455
|
+
console.log(`enabled: ${report.enabled ? "yes" : "no"}`);
|
|
456
|
+
if (report.version)
|
|
457
|
+
console.log(`version: ${report.version}`);
|
|
458
|
+
console.log("backend: not started");
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
430
461
|
const install = report.action === "codex-plugin-activate" ? report.install : report;
|
|
431
462
|
console.log(`codex home: ${install.codexHome}`);
|
|
432
463
|
console.log(`plugin source: ${install.pluginSourcePath}`);
|
|
@@ -490,6 +521,8 @@ function printMemoraxCodeStatus(report) {
|
|
|
490
521
|
backendLog(`DSH adapter: ${dshAdapterStatusLine(report.dshAdapter)}`);
|
|
491
522
|
if (report.opencodeAdapter)
|
|
492
523
|
backendLog(`OpenCode adapter: ${adapterStatusLine(report.opencodeAdapter)}`);
|
|
524
|
+
if (report.codebuddyAdapter)
|
|
525
|
+
backendLog(`CodeBuddy adapter: ${adapterStatusLine(report.codebuddyAdapter)}`);
|
|
493
526
|
if (!suppressBackendGuidance()) {
|
|
494
527
|
for (const line of statusGuidance(report))
|
|
495
528
|
backendLog(line);
|
|
@@ -591,6 +624,8 @@ function printLifecycleResult(report) {
|
|
|
591
624
|
backendLog(`DSH adapter: ${dshAdapterStatusLine(report.dshAdapter)}`);
|
|
592
625
|
if (report.opencodeAdapter)
|
|
593
626
|
backendLog(`OpenCode adapter: ${adapterStatusLine(report.opencodeAdapter)}`);
|
|
627
|
+
if (report.codebuddyAdapter)
|
|
628
|
+
backendLog(`CodeBuddy adapter: ${adapterStatusLine(report.codebuddyAdapter)}`);
|
|
594
629
|
if (report.codexPlugin) {
|
|
595
630
|
const removed = report.codexPlugin.removedPaths.length;
|
|
596
631
|
const marketplace = report.codexPlugin.marketplaceChanged ? " marketplace=updated" : " marketplace=unchanged";
|
|
@@ -848,11 +883,13 @@ function adapterStatusLine(report) {
|
|
|
848
883
|
const enabled = isAdapterReady(report);
|
|
849
884
|
const skillStatus = report.codexSkills?.status
|
|
850
885
|
?? report.claudeSkills?.status
|
|
851
|
-
?? report.opencodeSkills?.status
|
|
886
|
+
?? report.opencodeSkills?.status
|
|
887
|
+
?? report.codebuddySkills?.status;
|
|
852
888
|
const skills = skillStatus ? ` skills=${skillStatus}` : "";
|
|
889
|
+
const hooks = report.codebuddyHooks?.status ? ` hook-runtime=${report.codebuddyHooks.status}` : "";
|
|
853
890
|
const changed = report.changed === true ? " changed" : "";
|
|
854
891
|
const integration = report.integration ?? report.state?.integration ?? "hooks";
|
|
855
|
-
return `${enabled ? "ok" : "not enabled"} integration=${integration}${skills}${changed}`;
|
|
892
|
+
return `${enabled ? "ok" : "not enabled"} integration=${integration}${skills}${hooks}${changed}`;
|
|
856
893
|
}
|
|
857
894
|
function selectedLifecycleClientNames(report) {
|
|
858
895
|
return [
|
|
@@ -10,6 +10,8 @@ export function readActiveManagedClients(memoraxCodeHome) {
|
|
|
10
10
|
return undefined;
|
|
11
11
|
if (value.opencode !== undefined && typeof value.opencode !== "boolean")
|
|
12
12
|
return undefined;
|
|
13
|
+
if (value.codebuddy !== undefined && typeof value.codebuddy !== "boolean")
|
|
14
|
+
return undefined;
|
|
13
15
|
if (value.dsh !== undefined && typeof value.dsh !== "boolean")
|
|
14
16
|
return undefined;
|
|
15
17
|
return {
|
|
@@ -19,6 +21,7 @@ export function readActiveManagedClients(memoraxCodeHome) {
|
|
|
19
21
|
// that the Backend was serving DSH.
|
|
20
22
|
dsh: value.dsh === true,
|
|
21
23
|
opencode: value.opencode === true,
|
|
24
|
+
...(value.codebuddy === true ? { codebuddy: true } : {}),
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
catch {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { AUTOMATIC_UPDATE_RETRY_INTERVAL_MS, readAutomaticUpdateState, } from "../../../memorax-code-adapter-common/src/automatic-update-state.mjs";
|
|
5
|
+
import { readSetupCompletionRecord, } from "../../../memorax-code-adapter-common/src/setup-completion.mjs";
|
|
6
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
7
|
+
export function startBackendAutomaticUpdateScheduler(options, runtime = {}) {
|
|
8
|
+
const env = options.env ?? process.env;
|
|
9
|
+
if (automaticUpdateDisabled(env.MEMORAX_CODE_AUTO_UPDATE))
|
|
10
|
+
return undefined;
|
|
11
|
+
const packageRoot = nonEmptyString(options.packageRoot);
|
|
12
|
+
const installedVersion = nonEmptyString(options.packageVersion);
|
|
13
|
+
if (!packageRoot || !installedVersion)
|
|
14
|
+
return undefined;
|
|
15
|
+
const memoraxCodeHome = resolve(options.memoraxCodeHome);
|
|
16
|
+
const memoraxCodeCommand = join(resolve(packageRoot), "bin", "memorax-code.mjs");
|
|
17
|
+
if (!(runtime.existsSync ?? existsSync)(memoraxCodeCommand))
|
|
18
|
+
return undefined;
|
|
19
|
+
const readCompletion = runtime.readSetupCompletionRecord ?? readSetupCompletionRecord;
|
|
20
|
+
const readUpdateState = runtime.readAutomaticUpdateState ?? readAutomaticUpdateState;
|
|
21
|
+
const spawnProcess = runtime.spawnProcess ?? spawn;
|
|
22
|
+
const now = runtime.now ?? Date.now;
|
|
23
|
+
const setTimer = runtime.setTimeout
|
|
24
|
+
?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
25
|
+
const clearTimer = runtime.clearTimeout
|
|
26
|
+
?? ((handle) => clearTimeout(handle));
|
|
27
|
+
let closed = false;
|
|
28
|
+
let childRunning = false;
|
|
29
|
+
let timer;
|
|
30
|
+
let suppressImmediate = env.MEMORAX_CODE_AUTOMATIC_UPDATE_PROCESS === "1";
|
|
31
|
+
const debug = (message) => options.debug?.(message);
|
|
32
|
+
const scheduleAfter = (delayMs) => {
|
|
33
|
+
if (closed)
|
|
34
|
+
return;
|
|
35
|
+
if (timer !== undefined)
|
|
36
|
+
clearTimer(timer);
|
|
37
|
+
timer = setTimer(() => {
|
|
38
|
+
timer = undefined;
|
|
39
|
+
reconcile();
|
|
40
|
+
}, Math.max(1, Math.min(MAX_TIMER_DELAY_MS, Math.trunc(delayMs))));
|
|
41
|
+
timer.unref?.();
|
|
42
|
+
};
|
|
43
|
+
const scheduleRetry = () => scheduleAfter(AUTOMATIC_UPDATE_RETRY_INTERVAL_MS);
|
|
44
|
+
const launch = () => {
|
|
45
|
+
let child;
|
|
46
|
+
try {
|
|
47
|
+
child = spawnProcess(process.execPath, [memoraxCodeCommand, "update", "--automatic", "--home", memoraxCodeHome], {
|
|
48
|
+
detached: true,
|
|
49
|
+
env: {
|
|
50
|
+
...env,
|
|
51
|
+
MEMORAX_CODE_AUTOMATIC_UPDATE_PROCESS: "1",
|
|
52
|
+
MEMORAX_CODE_HOME: memoraxCodeHome,
|
|
53
|
+
},
|
|
54
|
+
stdio: "ignore",
|
|
55
|
+
windowsHide: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
debug(`MemoraX Code automatic update could not start: ${errorMessage(error)}`);
|
|
60
|
+
scheduleRetry();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
childRunning = true;
|
|
64
|
+
let settled = false;
|
|
65
|
+
const finish = (successful) => {
|
|
66
|
+
if (settled)
|
|
67
|
+
return;
|
|
68
|
+
settled = true;
|
|
69
|
+
childRunning = false;
|
|
70
|
+
if (!closed)
|
|
71
|
+
reconcile(!successful);
|
|
72
|
+
};
|
|
73
|
+
child.once("error", (error) => {
|
|
74
|
+
debug(`MemoraX Code automatic update could not start: ${error.message}`);
|
|
75
|
+
finish(false);
|
|
76
|
+
});
|
|
77
|
+
child.once("close", (code, signal) => finish(signal === null && code === 0));
|
|
78
|
+
child.unref();
|
|
79
|
+
};
|
|
80
|
+
function reconcile(deferDue = false) {
|
|
81
|
+
if (closed || childRunning)
|
|
82
|
+
return;
|
|
83
|
+
const suppressDue = suppressImmediate;
|
|
84
|
+
suppressImmediate = false;
|
|
85
|
+
try {
|
|
86
|
+
const completion = readCompletion(memoraxCodeHome);
|
|
87
|
+
const state = readUpdateState(memoraxCodeHome);
|
|
88
|
+
const nowMs = Number(now());
|
|
89
|
+
if (!Number.isFinite(nowMs))
|
|
90
|
+
throw new TypeError("automatic update scheduler clock is invalid");
|
|
91
|
+
if (completion.status !== "valid") {
|
|
92
|
+
scheduleRetry();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (state.status === "valid" && state.record.installedVersion === installedVersion) {
|
|
96
|
+
const remainingMs = Date.parse(state.record.nextCheckAt) - nowMs;
|
|
97
|
+
if (remainingMs > 0) {
|
|
98
|
+
scheduleAfter(remainingMs);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
debug(`MemoraX Code automatic update scheduling failed: ${errorMessage(error)}`);
|
|
105
|
+
scheduleRetry();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (suppressDue || deferDue)
|
|
109
|
+
scheduleRetry();
|
|
110
|
+
else
|
|
111
|
+
launch();
|
|
112
|
+
}
|
|
113
|
+
reconcile();
|
|
114
|
+
return {
|
|
115
|
+
close() {
|
|
116
|
+
if (closed)
|
|
117
|
+
return;
|
|
118
|
+
closed = true;
|
|
119
|
+
if (timer !== undefined)
|
|
120
|
+
clearTimer(timer);
|
|
121
|
+
timer = undefined;
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function automaticUpdateDisabled(value) {
|
|
126
|
+
return ["0", "false", "no", "off", "disabled"].includes(String(value ?? "").trim().toLowerCase());
|
|
127
|
+
}
|
|
128
|
+
function nonEmptyString(value) {
|
|
129
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
130
|
+
}
|
|
131
|
+
function errorMessage(error) {
|
|
132
|
+
return error instanceof Error ? error.message : String(error);
|
|
133
|
+
}
|
|
@@ -8,6 +8,7 @@ export async function prepareClientPluginRemovalCleanup(options = {}) {
|
|
|
8
8
|
const claudePluginInstaller = await loadClaudePluginInstaller();
|
|
9
9
|
const dshProfileLifecycle = await loadDshProfileLifecycle();
|
|
10
10
|
const openCodePluginInstaller = await loadOpenCodePluginInstaller();
|
|
11
|
+
const codeBuddyPluginInstaller = await loadCodeBuddyPluginInstaller();
|
|
11
12
|
const home = resolveHome(options.homeDir);
|
|
12
13
|
const memoraxCodeHome = resolve(options.memoraxCodeHome ?? process.env.MEMORAX_CODE_HOME ?? join(home, ".memorax-code"));
|
|
13
14
|
const claudeState = await readJsonRecord(join(memoraxCodeHome, "adapters", "claude-code", "state.json"));
|
|
@@ -15,7 +16,7 @@ export async function prepareClientPluginRemovalCleanup(options = {}) {
|
|
|
15
16
|
return async () => {
|
|
16
17
|
try {
|
|
17
18
|
return await withBackendLifecycleLock({ home: memoraxCodeHome }, async () => {
|
|
18
|
-
const [codexPlugin, claudePlugin, dshPlugin, opencodePlugin] = await Promise.all([
|
|
19
|
+
const [codexPlugin, claudePlugin, dshPlugin, opencodePlugin, codebuddyPlugin] = await Promise.all([
|
|
19
20
|
cleanupCodexAfterBackendRemoval({
|
|
20
21
|
memoraxCodeHome,
|
|
21
22
|
homeDir: home,
|
|
@@ -45,14 +46,21 @@ export async function prepareClientPluginRemovalCleanup(options = {}) {
|
|
|
45
46
|
: {}),
|
|
46
47
|
}))
|
|
47
48
|
.catch((error) => removalFailure("opencode-plugin-remove", error)),
|
|
49
|
+
Promise.resolve()
|
|
50
|
+
.then(() => codeBuddyPluginInstaller.removeCodeBuddyPluginInstallation({
|
|
51
|
+
memoraxCodeHome,
|
|
52
|
+
...(options.codeBuddyHome ? { codeBuddyHome: options.codeBuddyHome } : {}),
|
|
53
|
+
}))
|
|
54
|
+
.catch((error) => removalFailure("codebuddy-plugin-remove", error)),
|
|
48
55
|
]);
|
|
49
56
|
return {
|
|
50
|
-
ok: codexPlugin.ok && claudePlugin.ok && dshPlugin.ok && opencodePlugin.ok,
|
|
57
|
+
ok: codexPlugin.ok && claudePlugin.ok && dshPlugin.ok && opencodePlugin.ok && codebuddyPlugin.ok,
|
|
51
58
|
action: "client-plugin-removal-cleanup",
|
|
52
59
|
codexPlugin,
|
|
53
60
|
claudePlugin,
|
|
54
61
|
dshPlugin,
|
|
55
62
|
opencodePlugin,
|
|
63
|
+
codebuddyPlugin,
|
|
56
64
|
};
|
|
57
65
|
});
|
|
58
66
|
}
|
|
@@ -65,6 +73,7 @@ export async function prepareClientPluginRemovalCleanup(options = {}) {
|
|
|
65
73
|
claudePlugin: failure,
|
|
66
74
|
dshPlugin: failure,
|
|
67
75
|
opencodePlugin: failure,
|
|
76
|
+
codebuddyPlugin: failure,
|
|
68
77
|
};
|
|
69
78
|
}
|
|
70
79
|
};
|
|
@@ -75,6 +84,9 @@ async function loadClaudePluginInstaller() {
|
|
|
75
84
|
async function loadOpenCodePluginInstaller() {
|
|
76
85
|
return await import(new URL("../../../memorax-code-opencode-adapter/src/plugin-install.mjs", import.meta.url).href);
|
|
77
86
|
}
|
|
87
|
+
async function loadCodeBuddyPluginInstaller() {
|
|
88
|
+
return await import(new URL("../../../memorax-code-codebuddy-adapter/src/config.mjs", import.meta.url).href);
|
|
89
|
+
}
|
|
78
90
|
async function loadDshProfileLifecycle() {
|
|
79
91
|
return await import(new URL("../../../memorax-code-dsh-adapter/src/profile-lifecycle.mjs", import.meta.url).href);
|
|
80
92
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { loadLifecycleMemoraxCodeConfig } from "../config/memorax-code.js";
|
|
2
|
-
const allClients = Object.freeze({ codex: true, claude: true, dsh: true, opencode: true });
|
|
2
|
+
const allClients = Object.freeze({ codex: true, claude: true, dsh: true, opencode: true, codebuddy: true });
|
|
3
3
|
export function resolveManagedClients(argv, config = {}) {
|
|
4
4
|
const explicit = argValue(argv, "--clients");
|
|
5
5
|
if (explicit !== undefined)
|
|
@@ -12,9 +12,10 @@ export function resolveManagedClients(argv, config = {}) {
|
|
|
12
12
|
// automatic local-Harness discovery enabled for existing installations.
|
|
13
13
|
dsh: config.clients.dsh !== false,
|
|
14
14
|
opencode: config.clients.opencode === true,
|
|
15
|
+
...(config.clients.codebuddy === true ? { codebuddy: true } : {}),
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return { codex: true, claude: true, dsh: true, opencode: true };
|
|
18
19
|
}
|
|
19
20
|
export function parseManagedClients(value) {
|
|
20
21
|
const normalized = value.trim().toLowerCase();
|
|
@@ -23,14 +24,15 @@ export function parseManagedClients(value) {
|
|
|
23
24
|
if (normalized === "none")
|
|
24
25
|
return { codex: false, claude: false, dsh: false, opencode: false };
|
|
25
26
|
const names = normalized.split(",").map((name) => name.trim()).filter(Boolean);
|
|
26
|
-
if (names.length === 0 || names.some((name) => (name !== "codex" && name !== "claude" && name !== "dsh" && name !== "opencode"))) {
|
|
27
|
-
throw new Error(`invalid --clients value: ${value}; expected a comma-separated subset of codex, claude, dsh, opencode, or all or none`);
|
|
27
|
+
if (names.length === 0 || names.some((name) => (name !== "codex" && name !== "claude" && name !== "dsh" && name !== "opencode" && name !== "codebuddy"))) {
|
|
28
|
+
throw new Error(`invalid --clients value: ${value}; expected a comma-separated subset of codex, claude, dsh, opencode, codebuddy, or all or none`);
|
|
28
29
|
}
|
|
29
30
|
return {
|
|
30
31
|
codex: names.includes("codex"),
|
|
31
32
|
claude: names.includes("claude"),
|
|
32
33
|
dsh: names.includes("dsh"),
|
|
33
34
|
opencode: names.includes("opencode"),
|
|
35
|
+
...(names.includes("codebuddy") ? { codebuddy: true } : {}),
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
38
|
export function loadManagedClientsConfig(memoraxCodeHome) {
|
|
@@ -17,6 +17,7 @@ import { codexAdapterLifecycle } from "../clients/codex/lifecycle.js";
|
|
|
17
17
|
import { claudeAdapterLifecycle } from "../clients/claude/lifecycle.js";
|
|
18
18
|
import { collectDshAdapterLifecycleStatus, withDshAdapterLifecycleLock, } from "../clients/dsh/lifecycle.js";
|
|
19
19
|
import { openCodeAdapterLifecycle } from "../clients/opencode/lifecycle.js";
|
|
20
|
+
import { codeBuddyAdapterLifecycle } from "../clients/codebuddy/lifecycle.js";
|
|
20
21
|
const PACKAGE_REPLACEMENT_ENV = "MEMORAX_CODE_PACKAGE_REPLACEMENT";
|
|
21
22
|
const DSH_OPTIONAL_ENV = "MEMORAX_CODE_DSH_ADAPTER_OPTIONAL";
|
|
22
23
|
const DSH_RECOVERY_ENV = "MEMORAX_CODE_DSH_ADAPTER_RECOVERY";
|
|
@@ -58,15 +59,20 @@ export async function collectMemoraxCodeStatus(backendUrl, backendToken, service
|
|
|
58
59
|
const opencodeAdapter = clients.opencode
|
|
59
60
|
? await openCodeAdapterLifecycle.status({ argv, serviceOptions, backendUrl })
|
|
60
61
|
: undefined;
|
|
62
|
+
const codebuddyAdapter = clients.codebuddy
|
|
63
|
+
? await codeBuddyAdapterLifecycle.status({ argv, serviceOptions, backendUrl })
|
|
64
|
+
: undefined;
|
|
61
65
|
const codexReady = codexAdapter ? isAdapterReady(codexAdapter) : true;
|
|
62
66
|
const claudeReady = claudeAdapter ? isAdapterReady(claudeAdapter) : true;
|
|
63
67
|
const dshReady = dshAdapter ? isAdapterReady(dshAdapter) : true;
|
|
64
68
|
const opencodeReady = opencodeAdapter ? isAdapterReady(opencodeAdapter) : true;
|
|
69
|
+
const codebuddyReady = codebuddyAdapter ? isAdapterReady(codebuddyAdapter) : true;
|
|
65
70
|
const optionalDshUnavailable = isOptionalUnavailableDshAdapter(dshAdapter);
|
|
66
71
|
return {
|
|
67
72
|
ok: backend.ok
|
|
68
73
|
&& codexReady
|
|
69
74
|
&& opencodeReady
|
|
75
|
+
&& codebuddyReady
|
|
70
76
|
&& (isOptionalUnconfiguredClaudeAdapter(claudeAdapter, codexAdapter) || claudeReady)
|
|
71
77
|
&& (optionalDshUnavailable || dshReady),
|
|
72
78
|
action: "status",
|
|
@@ -76,6 +82,7 @@ export async function collectMemoraxCodeStatus(backendUrl, backendToken, service
|
|
|
76
82
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
77
83
|
...(dshAdapter ? { dshAdapter } : {}),
|
|
78
84
|
...(opencodeAdapter ? { opencodeAdapter } : {}),
|
|
85
|
+
...(codebuddyAdapter ? { codebuddyAdapter } : {}),
|
|
79
86
|
};
|
|
80
87
|
}
|
|
81
88
|
export async function startMemoraxCodeService(serviceOptions, argv, commitReadyState) {
|
|
@@ -193,10 +200,14 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
193
200
|
const deselectedOpenCode = previousClients?.opencode && !clients.opencode
|
|
194
201
|
? await openCodeAdapterLifecycle.disable({ argv, serviceOptions })
|
|
195
202
|
: undefined;
|
|
203
|
+
const deselectedCodeBuddy = previousClients?.codebuddy && !clients.codebuddy
|
|
204
|
+
? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
|
|
205
|
+
: undefined;
|
|
196
206
|
if (deselectedCodex?.ok === false
|
|
197
207
|
|| deselectedClaude?.ok === false
|
|
198
208
|
|| deselectedDsh?.ok === false
|
|
199
|
-
|| deselectedOpenCode?.ok === false
|
|
209
|
+
|| deselectedOpenCode?.ok === false
|
|
210
|
+
|| deselectedCodeBuddy?.ok === false) {
|
|
200
211
|
const recovery = await recoverPreparationFailure("adapter_disable_failed");
|
|
201
212
|
return {
|
|
202
213
|
ok: false,
|
|
@@ -208,6 +219,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
208
219
|
? { dshAdapter: recovery.dshAdapter ?? deselectedDsh }
|
|
209
220
|
: {}),
|
|
210
221
|
...(deselectedOpenCode ? { opencodeAdapter: deselectedOpenCode } : {}),
|
|
222
|
+
...(deselectedCodeBuddy ? { codebuddyAdapter: deselectedCodeBuddy } : {}),
|
|
211
223
|
};
|
|
212
224
|
}
|
|
213
225
|
// The marker is a conservative cleanup scope, not a readiness signal. Persist
|
|
@@ -247,6 +259,9 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
247
259
|
const opencodeAdapter = clients.opencode
|
|
248
260
|
? await openCodeAdapterLifecycle.prepareEnable({ argv, serviceOptions, backendUrl })
|
|
249
261
|
: undefined;
|
|
262
|
+
const codebuddyAdapter = clients.codebuddy
|
|
263
|
+
? await codeBuddyAdapterLifecycle.prepareEnable({ argv, serviceOptions, backendUrl })
|
|
264
|
+
: undefined;
|
|
250
265
|
if (opencodeAdapter?.ok === false) {
|
|
251
266
|
const recovery = await recoverPreparationFailure("opencode_adapter_enable_failed");
|
|
252
267
|
return {
|
|
@@ -257,6 +272,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
257
272
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
258
273
|
...(recovery.dshAdapter ? { dshAdapter: recovery.dshAdapter } : {}),
|
|
259
274
|
opencodeAdapter,
|
|
275
|
+
...(codebuddyAdapter ? { codebuddyAdapter } : {}),
|
|
260
276
|
};
|
|
261
277
|
}
|
|
262
278
|
const preparedDshAdapter = markOptionalDshAdapter(quiescedDsh?.ok === false
|
|
@@ -274,6 +290,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
274
290
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
275
291
|
dshAdapter: recovery.dshAdapter ?? preparedDshAdapter,
|
|
276
292
|
...(opencodeAdapter ? { opencodeAdapter } : {}),
|
|
293
|
+
...(codebuddyAdapter ? { codebuddyAdapter } : {}),
|
|
277
294
|
};
|
|
278
295
|
}
|
|
279
296
|
const backend = await startBackendService(serviceOptions);
|
|
@@ -284,6 +301,9 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
284
301
|
const disabledOpenCode = opencodeAdapter
|
|
285
302
|
? await openCodeAdapterLifecycle.disable({ argv, serviceOptions })
|
|
286
303
|
: undefined;
|
|
304
|
+
const disabledCodeBuddy = codebuddyAdapter
|
|
305
|
+
? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
|
|
306
|
+
: undefined;
|
|
287
307
|
return {
|
|
288
308
|
ok: false,
|
|
289
309
|
action: "start",
|
|
@@ -292,6 +312,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
292
312
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
293
313
|
...(preparedDshAdapter ? { dshAdapter: preparedDshAdapter } : {}),
|
|
294
314
|
...(disabledOpenCode ? { opencodeAdapter: disabledOpenCode } : {}),
|
|
315
|
+
...(disabledCodeBuddy ? { codebuddyAdapter: disabledCodeBuddy } : {}),
|
|
295
316
|
};
|
|
296
317
|
}
|
|
297
318
|
const dshAdapter = markOptionalDshAdapter(preparedDshAdapter?.installed === true
|
|
@@ -308,6 +329,7 @@ async function executeMemoraxCodeStart(serviceOptions, argv, backendUrl, memorax
|
|
|
308
329
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
309
330
|
...(dshAdapter ? { dshAdapter } : {}),
|
|
310
331
|
...(opencodeAdapter ? { opencodeAdapter } : {}),
|
|
332
|
+
...(codebuddyAdapter ? { codebuddyAdapter } : {}),
|
|
311
333
|
};
|
|
312
334
|
}
|
|
313
335
|
function expectedBackendUrl(serviceOptions) {
|
|
@@ -350,13 +372,15 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
|
|
|
350
372
|
claude: activeClients.claude && !clients.claude,
|
|
351
373
|
dsh: activeClients.dsh && !clients.dsh,
|
|
352
374
|
opencode: activeClients.opencode && !clients.opencode,
|
|
375
|
+
codebuddy: activeClients.codebuddy && !clients.codebuddy,
|
|
353
376
|
}
|
|
354
377
|
: undefined;
|
|
355
378
|
const hasRemainingClients = remaining?.codex === true
|
|
356
379
|
|| remaining?.claude === true
|
|
357
380
|
|| remaining?.dsh === true
|
|
358
|
-
|| remaining?.opencode === true
|
|
359
|
-
|
|
381
|
+
|| remaining?.opencode === true
|
|
382
|
+
|| remaining?.codebuddy === true;
|
|
383
|
+
const backendOnlyStop = !clients.codex && !clients.claude && !clients.dsh && !clients.opencode && !clients.codebuddy;
|
|
360
384
|
const packageReplacement = isPackageReplacement();
|
|
361
385
|
const needsBackendStop = packageReplacement || backendOnlyStop || !hasRemainingClients;
|
|
362
386
|
const quiescedDsh = clients.dsh && dshLifecycle
|
|
@@ -405,10 +429,14 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
|
|
|
405
429
|
const opencodeAdapter = clients.opencode
|
|
406
430
|
? await openCodeAdapterLifecycle.disable({ argv, serviceOptions })
|
|
407
431
|
: undefined;
|
|
432
|
+
const codebuddyAdapter = clients.codebuddy
|
|
433
|
+
? await codeBuddyAdapterLifecycle.disable({ argv, serviceOptions })
|
|
434
|
+
: undefined;
|
|
408
435
|
const adaptersOk = codexAdapter?.ok !== false
|
|
409
436
|
&& claudeAdapter?.ok !== false
|
|
410
437
|
&& dshAdapter?.ok !== false
|
|
411
|
-
&& opencodeAdapter?.ok !== false
|
|
438
|
+
&& opencodeAdapter?.ok !== false
|
|
439
|
+
&& codebuddyAdapter?.ok !== false;
|
|
412
440
|
const backend = stoppedBackend
|
|
413
441
|
?? (adaptersOk
|
|
414
442
|
? preservedBackendResult(serviceOptions, "active_clients_remaining")
|
|
@@ -417,7 +445,8 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
|
|
|
417
445
|
&& codexAdapter?.ok !== false
|
|
418
446
|
&& claudeAdapter?.ok !== false
|
|
419
447
|
&& dshAdapter?.ok !== false
|
|
420
|
-
&& opencodeAdapter?.ok !== false
|
|
448
|
+
&& opencodeAdapter?.ok !== false
|
|
449
|
+
&& codebuddyAdapter?.ok !== false;
|
|
421
450
|
return {
|
|
422
451
|
report: {
|
|
423
452
|
ok,
|
|
@@ -427,6 +456,7 @@ async function executeMemoraxCodeStop(serviceOptions, argv, context, dshLifecycl
|
|
|
427
456
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
428
457
|
...(dshAdapter ? { dshAdapter } : {}),
|
|
429
458
|
...(opencodeAdapter ? { opencodeAdapter } : {}),
|
|
459
|
+
...(codebuddyAdapter ? { codebuddyAdapter } : {}),
|
|
430
460
|
},
|
|
431
461
|
remainingClients: packageReplacement
|
|
432
462
|
? activeClients
|
|
@@ -535,10 +565,14 @@ async function executeMemoraxCodeUninstall(serviceOptions, argv, context, dshLif
|
|
|
535
565
|
const opencodePlugin = clients.opencode
|
|
536
566
|
? await openCodeAdapterLifecycle.remove({ argv, serviceOptions })
|
|
537
567
|
: undefined;
|
|
568
|
+
const codebuddyPlugin = clients.codebuddy
|
|
569
|
+
? await codeBuddyAdapterLifecycle.remove({ argv, serviceOptions })
|
|
570
|
+
: undefined;
|
|
538
571
|
const pluginCleanupOk = codexPlugin?.ok !== false
|
|
539
572
|
&& claudePlugin?.ok !== false
|
|
540
573
|
&& dshPlugin?.ok !== false
|
|
541
|
-
&& opencodePlugin?.ok !== false
|
|
574
|
+
&& opencodePlugin?.ok !== false
|
|
575
|
+
&& codebuddyPlugin?.ok !== false;
|
|
542
576
|
const npmPackageRemoval = !pluginCleanupOk
|
|
543
577
|
? skippedNpmPackageRemoval("plugin_cleanup_failed")
|
|
544
578
|
: canRemoveSharedPackage
|
|
@@ -562,11 +596,13 @@ async function executeMemoraxCodeUninstall(serviceOptions, argv, context, dshLif
|
|
|
562
596
|
...(claudeAdapter ? { claudeAdapter } : {}),
|
|
563
597
|
...(dshAdapter ? { dshAdapter } : {}),
|
|
564
598
|
...(opencodeAdapter ? { opencodeAdapter } : {}),
|
|
599
|
+
...(codebuddyPlugin ? { codebuddyPlugin } : {}),
|
|
565
600
|
npmPackageRemoval,
|
|
566
601
|
removesPlugin: codexPlugin?.ok === true
|
|
567
602
|
|| claudePlugin?.ok === true
|
|
568
603
|
|| (dshPlugin?.ok === true && dshPlugin.skipped !== true)
|
|
569
|
-
|| opencodePlugin?.ok === true
|
|
604
|
+
|| opencodePlugin?.ok === true
|
|
605
|
+
|| codebuddyPlugin?.ok === true,
|
|
570
606
|
removesUserState: false,
|
|
571
607
|
};
|
|
572
608
|
}
|
|
@@ -691,7 +727,8 @@ function includesManagedClients(selection, required) {
|
|
|
691
727
|
return (!required.codex || selection.codex)
|
|
692
728
|
&& (!required.claude || selection.claude)
|
|
693
729
|
&& (!required.dsh || selection.dsh)
|
|
694
|
-
&& (!required.opencode || selection.opencode)
|
|
730
|
+
&& (!required.opencode || selection.opencode)
|
|
731
|
+
&& (!required.codebuddy || selection.codebuddy === true);
|
|
695
732
|
}
|
|
696
733
|
function isPackageReplacement() {
|
|
697
734
|
return truthyEnv(process.env[PACKAGE_REPLACEMENT_ENV]);
|
|
@@ -819,7 +856,9 @@ export function isAdapterReady(report) {
|
|
|
819
856
|
&& report.backendUrlMatches !== false
|
|
820
857
|
&& report.codexSkills?.ok !== false
|
|
821
858
|
&& report.claudeSkills?.ok !== false
|
|
822
|
-
&& report.opencodeSkills?.ok !== false
|
|
859
|
+
&& report.opencodeSkills?.ok !== false
|
|
860
|
+
&& report.codebuddyHooks?.ok !== false
|
|
861
|
+
&& report.codebuddySkills?.ok !== false;
|
|
823
862
|
}
|
|
824
863
|
export function isOptionalUnavailableDshAdapter(report) {
|
|
825
864
|
return Boolean(report?.optional === true && !isAdapterReady(report));
|
|
@@ -238,9 +238,9 @@ async function resolveMemoryCliRepositoryMemory(options) {
|
|
|
238
238
|
}
|
|
239
239
|
function memoryCliRepositoryFailure(action, failure, fields = {}) {
|
|
240
240
|
const userAction = failure.reason === "workspace_scope_mismatch"
|
|
241
|
-
? "Start a new Codex, Claude Code, DSH, or OpenCode session from the target repository or local workspace."
|
|
241
|
+
? "Start a new Codex, Claude Code, WorkBuddy, DSH, or OpenCode session from the target repository or local workspace."
|
|
242
242
|
: failure.reason === "workspace_scope_unavailable"
|
|
243
|
-
? "Start a new Codex, Claude Code, DSH, or OpenCode session from the target repository or local workspace. If the problem continues, make sure its .git metadata is readable and valid."
|
|
243
|
+
? "Start a new Codex, Claude Code, WorkBuddy, DSH, or OpenCode session from the target repository or local workspace. If the problem continues, make sure its .git metadata is readable and valid."
|
|
244
244
|
: undefined;
|
|
245
245
|
return {
|
|
246
246
|
ok: false,
|
|
@@ -336,6 +336,8 @@ function traceClientLabel(client) {
|
|
|
336
336
|
return "DSH";
|
|
337
337
|
if (client === "opencode")
|
|
338
338
|
return "OpenCode";
|
|
339
|
+
if (client === "codebuddy")
|
|
340
|
+
return "WorkBuddy";
|
|
339
341
|
return client === "codex" ? "Codex" : "coding agent";
|
|
340
342
|
}
|
|
341
343
|
function memoryAddContentOptions(args) {
|