@memorax/memorax-code 0.1.4 → 0.1.6
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 +8 -19
- package/bin/memorax-code-npm-preinstall.mjs +28 -39
- package/bin/memorax-code-plugin-postinstall.mjs +23 -1537
- package/bin/memorax-code-setup.mjs +1615 -0
- package/bin/memorax-code.mjs +289 -5
- package/docs/configuration.md +66 -17
- package/docs/troubleshooting.md +105 -7
- package/lib/memorax-code-adapter-common/src/config-utils.d.mts +5 -1
- package/lib/memorax-code-adapter-common/src/config-utils.mjs +36 -3
- package/lib/memorax-code-adapter-common/src/credentials/linux-secret-service.mjs +110 -0
- package/lib/memorax-code-adapter-common/src/credentials/macos-keychain.mjs +224 -0
- package/lib/memorax-code-adapter-common/src/credentials/secure-command.mjs +340 -0
- package/lib/memorax-code-adapter-common/src/credentials/trial-credential-record.d.mts +82 -0
- package/lib/memorax-code-adapter-common/src/credentials/trial-credential-record.mjs +183 -0
- package/lib/memorax-code-adapter-common/src/credentials/trial-credential-store.d.mts +82 -0
- package/lib/memorax-code-adapter-common/src/credentials/trial-credential-store.mjs +271 -0
- package/lib/memorax-code-adapter-common/src/credentials/windows-dpapi.mjs +440 -0
- package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +7 -4
- package/lib/memorax-code-adapter-common/src/setup-completion.d.mts +81 -0
- package/lib/memorax-code-adapter-common/src/setup-completion.mjs +154 -0
- package/lib/memorax-code-backend/dist/clients/claude/memory-hook-runtime.js +21 -2
- package/lib/memorax-code-backend/dist/clients/codex/memory-hook-runtime.js +23 -3
- package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +19 -1
- package/lib/memorax-code-backend/dist/entrypoints/backend-cli.js +17 -16
- package/lib/memorax-code-backend/dist/lifecycle/backend/process.js +21 -0
- package/lib/memorax-code-backend/dist/lifecycle/orchestrator.js +81 -22
- package/lib/memorax-code-backend/dist/memorax-cli.js +3 -0
- package/lib/memorax-code-backend/dist/memory/automatic-retrieval.js +8 -2
- package/lib/memorax-code-backend/dist/memory/automatic-writeback.js +13 -1
- package/lib/memorax-code-backend/dist/memory/cli.js +10 -0
- package/lib/memorax-code-backend/dist/memory/quota-notice.js +208 -0
- package/lib/memorax-code-backend/dist/memory/service.js +11 -0
- package/lib/memorax-code-backend/dist/provider/memorax/adapter.js +4 -2
- package/lib/memorax-code-backend/dist/provider/memorax/http.js +10 -3
- package/lib/memorax-code-backend/dist/provider/memorax/quota.js +26 -0
- package/lib/memorax-code-backend/package.json +2 -2
- 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/memory-turn.mjs +5 -3
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +2 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +4 -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/memorax-code-adapter-common/src/config-utils.d.mts +5 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.mjs +36 -3
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/linux-secret-service.mjs +110 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/macos-keychain.mjs +224 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/secure-command.mjs +340 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/trial-credential-record.d.mts +82 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/trial-credential-record.mjs +183 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/trial-credential-store.d.mts +82 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/trial-credential-store.mjs +271 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/credentials/windows-dpapi.mjs +440 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +7 -4
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/setup-completion.d.mts +81 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/setup-completion.mjs +154 -0
- 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/memory-turn.mjs +5 -3
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +2 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +4 -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/runtime-hooks/memory-skill-reminder.mjs +2 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +2 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +4 -2
- package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +5 -2
- package/lib/memorax-code-dsh-adapter/package.json +1 -1
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +2 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +4 -2
- package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +158 -7
- package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +21 -0
- package/lib/memorax-code-opencode-adapter/package.json +1 -1
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +2 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +4 -2
- package/lib/memorax-code-opencode-adapter/src/plugin.mjs +20 -0
- package/lib/node-version.mjs +1 -1
- package/lib/package-transition.mjs +311 -0
- package/lib/resolve-codex-command.mjs +32 -6
- package/lib/setup-memory-preferences.mjs +113 -0
- package/lib/setup-reconcile.mjs +128 -0
- package/lib/trial-plugin-mark.mjs +171 -0
- package/lib/trial-provision-client.mjs +307 -0
- package/lib/trial-provision-flow.mjs +215 -0
- package/lib/trial-setup.mjs +53 -0
- package/package.json +2 -2
package/bin/memorax-code.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
2
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
import { stagePackagedClientHookRuntime } from "../lib/client-hook-runtime.mjs";
|
|
8
8
|
import { unsupportedNodeVersionMessage } from "../lib/node-version.mjs";
|
|
9
9
|
import { resolveNpmInvocation } from "../lib/npm-invocation.mjs";
|
|
@@ -37,6 +37,51 @@ Options:
|
|
|
37
37
|
-h, --help Show this help message`);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function printMainHelp() {
|
|
41
|
+
console.log(`Usage: memorax-code [command] [options]
|
|
42
|
+
|
|
43
|
+
Commands:
|
|
44
|
+
setup Run or repair the interactive setup
|
|
45
|
+
account Manage local MemoraX account information
|
|
46
|
+
start Reconcile selected integrations and start the Backend
|
|
47
|
+
status Show Backend and integration status
|
|
48
|
+
stop Stop the Backend and selected integrations
|
|
49
|
+
restart Restart the Backend and selected integrations
|
|
50
|
+
update Update the globally installed npm package
|
|
51
|
+
uninstall Remove managed integrations and the npm package
|
|
52
|
+
logs Show Backend logs
|
|
53
|
+
token Manage the local Backend token
|
|
54
|
+
|
|
55
|
+
Run \`memorax-code setup\` to complete first-time setup or repair an installation.
|
|
56
|
+
Run \`memorax-code\` with no command to show setup guidance or current status.
|
|
57
|
+
Run \`memorax-code <command> --help\` for command-specific options.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function printAccountHelp() {
|
|
61
|
+
console.log(`Usage: memorax-code account --show-mark-id [--home DIR]
|
|
62
|
+
|
|
63
|
+
Show the Mark ID for the ready local trial identity. Run this command directly
|
|
64
|
+
in your local terminal and keep its output private.
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
--show-mark-id Show the complete local trial Mark ID
|
|
68
|
+
--home DIR Read the specified MemoraX Code home
|
|
69
|
+
-h, --help Show this help message`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function printSetupHelp() {
|
|
73
|
+
console.log(`Usage: memorax-code setup [--existing-account | --reconfigure] [--home DIR]
|
|
74
|
+
|
|
75
|
+
Run interactive setup to configure or repair MemoraX Code. A complete existing
|
|
76
|
+
configuration is reused automatically.
|
|
77
|
+
|
|
78
|
+
Options:
|
|
79
|
+
--existing-account Configure an existing account instead of anonymous access
|
|
80
|
+
--reconfigure Re-detect memory preferences instead of reusing configuration
|
|
81
|
+
--home DIR Configure the specified MemoraX Code home
|
|
82
|
+
-h, --help Show this help message`);
|
|
83
|
+
}
|
|
84
|
+
|
|
40
85
|
function printCommand(command, args) {
|
|
41
86
|
console.log([command, ...args].join(" "));
|
|
42
87
|
}
|
|
@@ -48,6 +93,39 @@ function npmCommandCwd() {
|
|
|
48
93
|
return "/";
|
|
49
94
|
}
|
|
50
95
|
|
|
96
|
+
async function runAccountCommand(args) {
|
|
97
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
98
|
+
printAccountHelp();
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
let memoraxCodeHome;
|
|
102
|
+
try {
|
|
103
|
+
memoraxCodeHome = requestedMemoraxCodeHome(args);
|
|
104
|
+
assertAccountArgs(args);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error(`memorax-code account: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
printAccountHelp();
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const { loadReadyTrialSetupCredential } = await loadTrialSetupApi();
|
|
113
|
+
const credential = await loadReadyTrialSetupCredential({
|
|
114
|
+
memoraxCodeHome,
|
|
115
|
+
env: process.env,
|
|
116
|
+
});
|
|
117
|
+
if (!credential) {
|
|
118
|
+
console.error("memorax-code account: no ready local trial identity was found");
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
console.log(`Mark ID: ${credential.markId}`);
|
|
122
|
+
return 0;
|
|
123
|
+
} catch {
|
|
124
|
+
console.error("memorax-code account: unable to read the secure local trial identity");
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
51
129
|
async function runUpdateCommand(args) {
|
|
52
130
|
let dryRun = false;
|
|
53
131
|
let force = false;
|
|
@@ -98,7 +176,6 @@ async function runUpdateCommand(args) {
|
|
|
98
176
|
const channel = requestedChannel ?? (pkg.version.includes("-") ? "preview" : "latest");
|
|
99
177
|
const npmArgs = ["install", "-g", `${pkg.name}@${channel}`];
|
|
100
178
|
if (force) npmArgs.push("--force");
|
|
101
|
-
npmArgs.push("--foreground-scripts");
|
|
102
179
|
|
|
103
180
|
if (dryRun) {
|
|
104
181
|
printCommand("npm", npmArgs);
|
|
@@ -120,11 +197,10 @@ async function runUpdateCommand(args) {
|
|
|
120
197
|
env: {
|
|
121
198
|
...process.env,
|
|
122
199
|
PWD: cwd,
|
|
123
|
-
MEMORAX_CODE_NPM_POSTINSTALL_UPDATE: "1",
|
|
124
200
|
...(requestedHome ? { MEMORAX_CODE_HOME: requestedHome } : {}),
|
|
125
201
|
},
|
|
126
202
|
});
|
|
127
|
-
|
|
203
|
+
const npmExitCode = await new Promise((resolve) => {
|
|
128
204
|
child.on("error", (error) => {
|
|
129
205
|
console.error(`memorax-code update: failed to start npm: ${error.message}`);
|
|
130
206
|
resolve(1);
|
|
@@ -138,6 +214,196 @@ async function runUpdateCommand(args) {
|
|
|
138
214
|
}
|
|
139
215
|
});
|
|
140
216
|
});
|
|
217
|
+
if (npmExitCode !== 0) return npmExitCode;
|
|
218
|
+
|
|
219
|
+
const memoraxCodeHome = requestedHome ?? requestedMemoraxCodeHome([]);
|
|
220
|
+
if (!existsSync(join(memoraxCodeHome, "runtime", "backend", "backend.pid.json"))) {
|
|
221
|
+
console.error("memorax-code update: package updated; the managed Backend remains stopped; run `memorax-code setup` from a terminal to review client and Hook changes");
|
|
222
|
+
return 0;
|
|
223
|
+
}
|
|
224
|
+
if (!setupCanPrompt()) {
|
|
225
|
+
console.error("memorax-code update: package updated; run `memorax-code setup` from a terminal to review client and Hook changes");
|
|
226
|
+
return 0;
|
|
227
|
+
}
|
|
228
|
+
return await runSetupCommand(["--home", memoraxCodeHome], { updateMode: true });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function runSetupCommand(args, { updateMode = false } = {}) {
|
|
232
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
233
|
+
printSetupHelp();
|
|
234
|
+
return 0;
|
|
235
|
+
}
|
|
236
|
+
let memoraxCodeHome;
|
|
237
|
+
let setupMode;
|
|
238
|
+
try {
|
|
239
|
+
memoraxCodeHome = requestedMemoraxCodeHome(args);
|
|
240
|
+
setupMode = parseSetupMode(args);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error(`memorax-code setup: ${error instanceof Error ? error.message : String(error)}`);
|
|
243
|
+
printSetupHelp();
|
|
244
|
+
return 2;
|
|
245
|
+
}
|
|
246
|
+
if (!setupCanPrompt()) {
|
|
247
|
+
console.error("memorax-code setup: an interactive terminal is required");
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const { withSetupCompletionLock } = await loadSetupCompletionApi();
|
|
252
|
+
return await withSetupCompletionLock(memoraxCodeHome, async (completion) => {
|
|
253
|
+
if (updateMode && completion.status === "absent") {
|
|
254
|
+
if (hasReadyMemoraxConfiguration(memoraxCodeHome)) {
|
|
255
|
+
console.error("memorax-code update: existing configuration detected; completing the one-time setup migration");
|
|
256
|
+
return await spawnSetupProcess(memoraxCodeHome, { setupMode });
|
|
257
|
+
}
|
|
258
|
+
console.error("memorax-code update: package updated; setup has not been completed; run `memorax-code setup` from an interactive terminal");
|
|
259
|
+
return 0;
|
|
260
|
+
}
|
|
261
|
+
if (updateMode) {
|
|
262
|
+
console.error("memorax-code update: reviewing client and Hook changes in the foreground");
|
|
263
|
+
}
|
|
264
|
+
return await spawnSetupProcess(memoraxCodeHome, {
|
|
265
|
+
updateMode,
|
|
266
|
+
setupMode,
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error(`memorax-code setup: ${error instanceof Error ? error.message : String(error)}`);
|
|
271
|
+
return 1;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function routeDefaultCommand() {
|
|
276
|
+
const memoraxCodeHome = requestedMemoraxCodeHome([]);
|
|
277
|
+
try {
|
|
278
|
+
const { readSetupCompletionRecord, setupCompletionPath } = await loadSetupCompletionApi();
|
|
279
|
+
const state = readSetupCompletionRecord(memoraxCodeHome);
|
|
280
|
+
if (state.status === "absent") {
|
|
281
|
+
if (setupCanPrompt() && hasReadyMemoraxConfiguration(memoraxCodeHome)) {
|
|
282
|
+
console.error("memorax-code: existing configuration detected; completing the one-time setup migration");
|
|
283
|
+
return await runSetupCommand(["--home", memoraxCodeHome]);
|
|
284
|
+
}
|
|
285
|
+
console.error("memorax-code: setup has not been completed. Run `memorax-code setup` from an interactive terminal.");
|
|
286
|
+
return 1;
|
|
287
|
+
}
|
|
288
|
+
if (state.status !== "valid") {
|
|
289
|
+
const detail = state.status === "unsupported"
|
|
290
|
+
? `uses unsupported version ${state.version}`
|
|
291
|
+
: `is invalid (${state.reason})`;
|
|
292
|
+
console.error(`memorax-code: setup completion record ${detail}: ${setupCompletionPath(memoraxCodeHome)}`);
|
|
293
|
+
console.error("Inspect or repair this private record before running setup again.");
|
|
294
|
+
return 1;
|
|
295
|
+
}
|
|
296
|
+
process.argv.splice(2, 0, "status");
|
|
297
|
+
return undefined;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.error(`memorax-code: unable to inspect setup state: ${error instanceof Error ? error.message : String(error)}`);
|
|
300
|
+
return 1;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function assertAccountArgs(args) {
|
|
305
|
+
let showMarkId = false;
|
|
306
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
307
|
+
const arg = args[index];
|
|
308
|
+
if (arg === "--show-mark-id") {
|
|
309
|
+
showMarkId = true;
|
|
310
|
+
} else if (arg === "--home") {
|
|
311
|
+
const value = args[++index];
|
|
312
|
+
if (!value || value.startsWith("--")) throw new Error("--home requires a directory");
|
|
313
|
+
} else if (arg.startsWith("--home=")) {
|
|
314
|
+
if (!arg.slice("--home=".length).trim()) throw new Error("--home requires a directory");
|
|
315
|
+
} else {
|
|
316
|
+
throw new Error(`unknown option ${arg}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (!showMarkId) throw new Error("--show-mark-id is required");
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function parseSetupMode(args) {
|
|
323
|
+
let setupMode = "automatic";
|
|
324
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
325
|
+
const arg = args[index];
|
|
326
|
+
if (arg === "--existing-account" || arg === "--reconfigure") {
|
|
327
|
+
const requestedMode = arg === "--existing-account" ? "existing-account" : "reconfigure";
|
|
328
|
+
if (setupMode !== "automatic" && setupMode !== requestedMode) {
|
|
329
|
+
throw new Error("--existing-account and --reconfigure cannot be used together");
|
|
330
|
+
}
|
|
331
|
+
setupMode = requestedMode;
|
|
332
|
+
} else if (arg === "--home") {
|
|
333
|
+
const value = args[++index];
|
|
334
|
+
if (!value || value.startsWith("--")) throw new Error("--home requires a directory");
|
|
335
|
+
} else if (arg.startsWith("--home=")) {
|
|
336
|
+
if (!arg.slice("--home=".length).trim()) throw new Error("--home requires a directory");
|
|
337
|
+
} else {
|
|
338
|
+
throw new Error(`unknown option ${arg}`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return setupMode;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function setupCanPrompt() {
|
|
345
|
+
return truthyEnv(process.env.MEMORAX_CODE_SETUP_ASSUME_INTERACTIVE)
|
|
346
|
+
|| (process.stdin.isTTY === true && process.stderr.isTTY === true);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async function loadSetupCompletionApi() {
|
|
350
|
+
const modulePath = join(
|
|
351
|
+
packageRoot(),
|
|
352
|
+
"lib",
|
|
353
|
+
"memorax-code-adapter-common",
|
|
354
|
+
"src",
|
|
355
|
+
"setup-completion.mjs",
|
|
356
|
+
);
|
|
357
|
+
return await import(pathToFileURL(modulePath).href);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function loadTrialSetupApi() {
|
|
361
|
+
return await import(pathToFileURL(join(packageRoot(), "lib", "trial-setup.mjs")).href);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function hasReadyMemoraxConfiguration(memoraxCodeHome) {
|
|
365
|
+
const result = spawnSync(process.execPath, [
|
|
366
|
+
join(packageRoot(), "bin", "memorax-cli.mjs"),
|
|
367
|
+
"status",
|
|
368
|
+
"--json",
|
|
369
|
+
"--config-only",
|
|
370
|
+
], {
|
|
371
|
+
encoding: "utf8",
|
|
372
|
+
env: { ...process.env, MEMORAX_CODE_HOME: memoraxCodeHome },
|
|
373
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
374
|
+
timeout: 10_000,
|
|
375
|
+
windowsHide: true,
|
|
376
|
+
});
|
|
377
|
+
return !result.error && !result.signal && result.status === 0;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async function spawnSetupProcess(memoraxCodeHome, { updateMode = false, setupMode = "automatic" } = {}) {
|
|
381
|
+
const env = {
|
|
382
|
+
...process.env,
|
|
383
|
+
MEMORAX_CODE_HOME: memoraxCodeHome,
|
|
384
|
+
};
|
|
385
|
+
delete env.MEMORAX_CODE_SETUP_UPDATE;
|
|
386
|
+
delete env.MEMORAX_CODE_SETUP_MODE;
|
|
387
|
+
if (updateMode) env.MEMORAX_CODE_SETUP_UPDATE = "1";
|
|
388
|
+
if (setupMode !== "automatic") env.MEMORAX_CODE_SETUP_MODE = setupMode;
|
|
389
|
+
const child = spawn(process.execPath, [join(packageRoot(), "bin", "memorax-code-setup.mjs")], {
|
|
390
|
+
stdio: "inherit",
|
|
391
|
+
env,
|
|
392
|
+
});
|
|
393
|
+
return await new Promise((resolve) => {
|
|
394
|
+
child.on("error", (error) => {
|
|
395
|
+
console.error(`memorax-code setup: failed to start setup: ${error.message}`);
|
|
396
|
+
resolve(1);
|
|
397
|
+
});
|
|
398
|
+
child.on("close", (code, signal) => {
|
|
399
|
+
if (signal) {
|
|
400
|
+
console.error(`memorax-code setup: setup exited from signal ${signal}`);
|
|
401
|
+
resolve(1);
|
|
402
|
+
} else {
|
|
403
|
+
resolve(code ?? 1);
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
});
|
|
141
407
|
}
|
|
142
408
|
|
|
143
409
|
if (process.argv[2] === "update") {
|
|
@@ -150,6 +416,24 @@ if (process.argv[2] === "--version" || process.argv[2] === "-v") {
|
|
|
150
416
|
process.exit(0);
|
|
151
417
|
}
|
|
152
418
|
|
|
419
|
+
if (process.argv.length === 3 && (process.argv[2] === "--help" || process.argv[2] === "-h")) {
|
|
420
|
+
printMainHelp();
|
|
421
|
+
process.exit(0);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (process.argv[2] === "setup") {
|
|
425
|
+
process.exit(await runSetupCommand(process.argv.slice(3)));
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (process.argv[2] === "account") {
|
|
429
|
+
process.exit(await runAccountCommand(process.argv.slice(3)));
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (process.argv.length === 2) {
|
|
433
|
+
const exitCode = await routeDefaultCommand();
|
|
434
|
+
if (exitCode !== undefined) process.exit(exitCode);
|
|
435
|
+
}
|
|
436
|
+
|
|
153
437
|
if (shouldStageClientHookRuntime(process.argv.slice(2))
|
|
154
438
|
&& !truthyEnv(process.env.MEMORAX_CODE_DEFER_CLIENT_HOOK_RUNTIME_ACTIVATION)) {
|
|
155
439
|
try {
|
package/docs/configuration.md
CHANGED
|
@@ -19,7 +19,8 @@ explicit command/context value > environment variable > config.toml > code fallb
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Use `config.toml` for durable choices and environment variables for temporary
|
|
22
|
-
overrides
|
|
22
|
+
overrides. Both account-free and existing-account setup write the effective API
|
|
23
|
+
key to this private file so the connection can be reused. After editing the
|
|
23
24
|
file, run:
|
|
24
25
|
|
|
25
26
|
```sh
|
|
@@ -42,7 +43,7 @@ The generated template selects all four client integrations, disables automatic
|
|
|
42
43
|
retrieval, enables automatic writeback, sets the preferred language to Chinese
|
|
43
44
|
(`zh`), uses a five-turn skill reminder and the adaptive repository-update
|
|
44
45
|
policy, and enables content-bearing local traces for Codex, Claude Code, and
|
|
45
|
-
OpenCode.
|
|
46
|
+
OpenCode. Foreground setup may narrow `[clients]` to clients detected on the
|
|
46
47
|
host. The tables below list all fallbacks, including tuning fields omitted from
|
|
47
48
|
the generated file.
|
|
48
49
|
|
|
@@ -64,25 +65,65 @@ comma-separated subset:
|
|
|
64
65
|
--clients codex|claude|dsh|opencode|<comma-separated subset>|all|none
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
Foreground `memorax-code setup` refreshes `[clients]` from the clients
|
|
69
|
+
available at that time. OpenCode is available when its explicit, XDG, or
|
|
70
|
+
default configuration directory exists, or when `opencode` is on `PATH`.
|
|
70
71
|
DSH is available when at least one valid Profile exists under
|
|
71
72
|
`$DSH_HOME/profiles`; `DSH_HOME` defaults to `~/.dsh`. An explicit
|
|
72
73
|
`[clients].dsh = false` is preserved.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
selected
|
|
78
|
-
|
|
79
|
-
enables Codex, it requests initial Hook activation after the client-selection
|
|
80
|
-
prompt.
|
|
74
|
+
|
|
75
|
+
On later setup runs, enabled client intent is preserved. Each newly available
|
|
76
|
+
disabled client is offered for activation with a default of yes; declining
|
|
77
|
+
keeps it disabled. A selected client that is temporarily unavailable remains
|
|
78
|
+
selected instead of being permanently disabled. Direct npm installation does
|
|
79
|
+
not detect clients or modify `[clients]`.
|
|
81
80
|
|
|
82
81
|
Client selection controls managed client-integration lifecycle only. It does
|
|
83
82
|
not change Codex, Claude Code, DSH, or OpenCode provider settings.
|
|
84
83
|
`--clients none` runs the Backend without managing a client integration.
|
|
85
84
|
|
|
85
|
+
## Setup and package-transition state
|
|
86
|
+
|
|
87
|
+
npm installation and foreground setup are separate operations.
|
|
88
|
+
`npm install -g @memorax/memorax-code` installs or replaces package files
|
|
89
|
+
without reading terminal input. `memorax-code setup` owns client detection,
|
|
90
|
+
connection setup, configuration writes, Codex Hook activation or review, and
|
|
91
|
+
final readiness checks.
|
|
92
|
+
|
|
93
|
+
Default setup reuses a complete effective connection. Otherwise it detects the
|
|
94
|
+
logged-in operating-system username and maps the system language to `zh` or
|
|
95
|
+
`en`, asking only when a value cannot be detected safely. It then creates or
|
|
96
|
+
restores an account-free credential and writes its API key to `config.toml`.
|
|
97
|
+
`memorax-code setup --existing-account` bypasses automatic reuse and accepts
|
|
98
|
+
an existing connection's username and API key. `--reconfigure` bypasses reuse
|
|
99
|
+
and follows the account-free path again.
|
|
100
|
+
|
|
101
|
+
Successful setup writes a private versioned record at:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
$MEMORAX_CODE_HOME/runtime/setup/setup-completion.json
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The record controls only no-argument CLI routing. When it is valid, the command
|
|
108
|
+
shows status. When it is absent and an interactive terminal is available,
|
|
109
|
+
`memorax-code` validates and reuses a complete effective configuration, then
|
|
110
|
+
runs setup and reconciliation once to write the record. If the configuration
|
|
111
|
+
is incomplete or no interactive terminal is available, it points to
|
|
112
|
+
`memorax-code setup`. Invalid and unsupported records fail closed. A complete
|
|
113
|
+
product uninstall removes this marker while retaining `config.toml`; stop and
|
|
114
|
+
partial client uninstall preserve it.
|
|
115
|
+
|
|
116
|
+
Replacing a running managed Backend uses a separate private record:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
$MEMORAX_CODE_HOME/runtime/install/package-transition.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Preinstall records and retires the running installation. Postinstall restores
|
|
123
|
+
and verifies it before consuming the record. A fresh or already-stopped
|
|
124
|
+
installation has no transition and remains stopped. Do not edit either runtime
|
|
125
|
+
record by hand.
|
|
126
|
+
|
|
86
127
|
## DeepSeek Harness integration paths
|
|
87
128
|
|
|
88
129
|
DSH Profiles are discovered under:
|
|
@@ -145,7 +186,7 @@ MemoraX is the required remote-memory service:
|
|
|
145
186
|
```toml
|
|
146
187
|
[memorax]
|
|
147
188
|
endpoint = "https://platform.memorax.net"
|
|
148
|
-
user_id = "your-
|
|
189
|
+
user_id = "your-username"
|
|
149
190
|
api_key = "your-api-key"
|
|
150
191
|
# timeout_ms = 5000
|
|
151
192
|
# startup_timeout_ms = 3000
|
|
@@ -154,8 +195,8 @@ api_key = "your-api-key"
|
|
|
154
195
|
| Field | Environment override | Fallback |
|
|
155
196
|
| --- | --- | --- |
|
|
156
197
|
| `endpoint` | `MEMORAX_CODE_MEMORAX_ENDPOINT` | `https://platform.memorax.net` |
|
|
157
|
-
| `user_id` | `MEMORAX_CODE_MEMORAX_USER_ID` | required |
|
|
158
|
-
| `api_key` | `MEMORAX_CODE_MEMORAX_API_KEY` | required |
|
|
198
|
+
| `user_id` | `MEMORAX_CODE_MEMORAX_USER_ID` | required username |
|
|
199
|
+
| `api_key` | `MEMORAX_CODE_MEMORAX_API_KEY` | required; setup writes it |
|
|
159
200
|
| `timeout_ms` | `MEMORAX_CODE_MEMORAX_TIMEOUT_MS` | `5000` ms |
|
|
160
201
|
| `startup_timeout_ms` | `MEMORAX_CODE_MEMORAX_STARTUP_TIMEOUT_MS` | `3000` ms |
|
|
161
202
|
|
|
@@ -163,8 +204,14 @@ MemoraX requests send the API key and the query or content required by the
|
|
|
163
204
|
selected memory operation to the HTTPS endpoint. Override `endpoint` only with
|
|
164
205
|
a compatible MemoraX service you trust.
|
|
165
206
|
|
|
207
|
+
Quota reminders keep only a one-way connection fingerprint and the last
|
|
208
|
+
notified level for memory write and memory search under the private runtime
|
|
209
|
+
directory. They do not store a raw API key, Mark ID, or account-registration
|
|
210
|
+
state. The returned quota limit is used only to decide whether to include
|
|
211
|
+
conditional anonymous-account guidance.
|
|
212
|
+
|
|
166
213
|
`startup_timeout_ms` controls synchronous automatic retrieval and is capped at
|
|
167
|
-
10 seconds. `user_id` is
|
|
214
|
+
10 seconds. `user_id` is the configured username; MemoraX Code derives a
|
|
168
215
|
repository-scoped identity for Git workspaces and a folder-scoped identity for
|
|
169
216
|
non-Git workspaces. It never falls back to the unscoped base identity.
|
|
170
217
|
|
|
@@ -341,6 +388,8 @@ token. Persistent connection, token, and PID records live under
|
|
|
341
388
|
read or parsed; memory readers may also warn. Unsupported field types are
|
|
342
389
|
ignored.
|
|
343
390
|
- Targeted configuration updates preserve unrelated and unknown TOML content.
|
|
391
|
+
- Setup writes completion only after Backend, client, and effective MemoraX
|
|
392
|
+
readiness checks succeed.
|
|
344
393
|
- Invalid or unsupported Backend runtime records fail closed instead of
|
|
345
394
|
silently falling back to `127.0.0.1:8787`.
|
|
346
395
|
|
package/docs/troubleshooting.md
CHANGED
|
@@ -18,17 +18,83 @@ memory switches without printing secrets. Codex, Claude Code, and OpenCode
|
|
|
18
18
|
also provide client-specific `doctor` commands; DSH uses the shared lifecycle
|
|
19
19
|
status.
|
|
20
20
|
|
|
21
|
+
## Package installed, but setup did not start
|
|
22
|
+
|
|
23
|
+
This is expected after:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm install -g @memorax/memorax-code
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
npm installation is deliberately non-interactive. Start setup from a normal
|
|
30
|
+
terminal:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
memorax-code setup
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If a complete configuration was retained from an earlier installation,
|
|
37
|
+
default setup reuses it automatically. Use `memorax-code setup --reconfigure`
|
|
38
|
+
to replace it, or `memorax-code setup --existing-account` to enter an
|
|
39
|
+
existing MemoraX connection.
|
|
40
|
+
|
|
41
|
+
Setup requires terminal input and terminal-visible stderr. A pipe, background
|
|
42
|
+
process, or redirected stdin/stderr cannot complete setup; rerun it in a normal
|
|
43
|
+
interactive terminal.
|
|
44
|
+
|
|
45
|
+
## Setup does not complete
|
|
46
|
+
|
|
47
|
+
Setup writes
|
|
48
|
+
`$MEMORAX_CODE_HOME/runtime/setup/setup-completion.json` only after
|
|
49
|
+
configuration, client and Hook reconciliation, Backend start, and final
|
|
50
|
+
readiness checks succeed. Until then, running `memorax-code` with no command
|
|
51
|
+
points back to `memorax-code setup`.
|
|
52
|
+
|
|
53
|
+
If secure credential setup fails, confirm that the operating-system credential
|
|
54
|
+
backend is available to the same logged-in user and that the MemoraX service is
|
|
55
|
+
reachable. On Linux, confirm that `/usr/bin/secret-tool` is installed and the
|
|
56
|
+
session can reach an unlocked Secret Service. Minimal containers and detached
|
|
57
|
+
SSH sessions often do not provide one.
|
|
58
|
+
|
|
59
|
+
Malformed `config.toml` is preserved rather than overwritten. Repair or
|
|
60
|
+
restore the file, then rerun setup. Invalid setup-completion records also fail
|
|
61
|
+
closed; preserve a diagnostic copy and confirm no setup command is active
|
|
62
|
+
before moving an invalid record aside. An unsupported record version requires
|
|
63
|
+
a compatible MemoraX Code release.
|
|
64
|
+
|
|
65
|
+
## npm package transition fails
|
|
66
|
+
|
|
67
|
+
Replacing a running managed installation uses
|
|
68
|
+
`$MEMORAX_CODE_HOME/runtime/install/package-transition.json`. If preinstall
|
|
69
|
+
cannot retire the old Backend, installation stops before package replacement.
|
|
70
|
+
If postinstall cannot start or verify the new Backend, the retired transition
|
|
71
|
+
is retained for a bounded retry.
|
|
72
|
+
|
|
73
|
+
Do not delete the record while the old Backend or another lifecycle command may
|
|
74
|
+
still own state. After confirming process ownership, retry:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
memorax-code stop --clients none
|
|
78
|
+
npm install -g @memorax/memorax-code
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Fresh and already-stopped installations do not create a transition and remain
|
|
82
|
+
stopped.
|
|
83
|
+
|
|
21
84
|
## Installed, but memory is unavailable
|
|
22
85
|
|
|
23
86
|
The package and Backend can be healthy while MemoraX remains unconfigured. Run:
|
|
24
87
|
|
|
25
88
|
```sh
|
|
89
|
+
memorax-code setup
|
|
26
90
|
memorax-cli status
|
|
27
91
|
```
|
|
28
92
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
93
|
+
Default setup creates or restores an account-free connection. For an existing
|
|
94
|
+
account, run `memorax-code setup --existing-account`. A manually managed
|
|
95
|
+
connection may instead configure `endpoint`, `user_id`, and `api_key`
|
|
96
|
+
under `[memorax]`, or set their environment equivalents. The current default
|
|
97
|
+
endpoint is `https://platform.memorax.net`.
|
|
32
98
|
|
|
33
99
|
After changing persistent configuration:
|
|
34
100
|
|
|
@@ -42,6 +108,29 @@ search. Automatic writeback requires `[memory.writeback] enabled = true` and
|
|
|
42
108
|
must not be disabled by
|
|
43
109
|
`MEMORAX_CODE_MEMORAX_WRITEBACK_ENABLED=false`.
|
|
44
110
|
|
|
111
|
+
## Quota reminder and Mark ID
|
|
112
|
+
|
|
113
|
+
Memory write and memory search reminders are tracked independently. A reminder
|
|
114
|
+
is emitted when the corresponding remaining quota reaches 10% or less and
|
|
115
|
+
again at 0%; raw quota counts are not shown.
|
|
116
|
+
|
|
117
|
+
Automatic quota reminders are currently supported in Codex, Claude Code, and
|
|
118
|
+
OpenCode. DeepSeek Harness does not currently surface these reminders.
|
|
119
|
+
|
|
120
|
+
Routine reminders do not include a complete Mark ID. If this device uses an
|
|
121
|
+
unregistered anonymous identity and the MemoraX account page requires its Mark
|
|
122
|
+
ID, run this command yourself in a local terminal:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
memorax-code account --show-mark-id
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The command reads a ready local trial identity and prints only its Mark ID. Do
|
|
129
|
+
not ask an Agent to run it or paste the output into a conversation, screenshot,
|
|
130
|
+
or log. If no ready local trial identity exists, use `memorax-code setup`; a
|
|
131
|
+
connection copied from another computer does not include that computer's
|
|
132
|
+
device-local Mark ID.
|
|
133
|
+
|
|
45
134
|
## Backend does not start
|
|
46
135
|
|
|
47
136
|
```sh
|
|
@@ -91,9 +180,10 @@ memorax-code start --clients codex
|
|
|
91
180
|
memorax-code-codex doctor
|
|
92
181
|
```
|
|
93
182
|
|
|
94
|
-
Codex requires review for new or changed Hook command hashes. A declined
|
|
95
|
-
non-interactive update can leave Hooks untrusted even
|
|
96
|
-
|
|
183
|
+
Codex requires review for new or changed Hook command hashes. A declined,
|
|
184
|
+
non-interactive, or direct npm update can leave changed Hooks untrusted even
|
|
185
|
+
though package replacement succeeded. Run `memorax-code setup` for foreground
|
|
186
|
+
review; do not write trust entries directly. If the skill is missing, rerun
|
|
97
187
|
`memorax-code start --clients codex`, then restart or refresh Codex.
|
|
98
188
|
|
|
99
189
|
## Claude Code plugin or Hook is inactive
|
|
@@ -116,10 +206,18 @@ memorax-code start --clients dsh
|
|
|
116
206
|
memorax-code status --clients dsh
|
|
117
207
|
```
|
|
118
208
|
|
|
209
|
+
Automatic DSH discovery is optional: an unavailable DSH integration is
|
|
210
|
+
reported as degraded without blocking the Backend or another detected client.
|
|
211
|
+
The explicit commands above are strict and return a failure until DSH is ready.
|
|
212
|
+
|
|
119
213
|
MemoraX Code discovers existing Profiles under `$DSH_HOME/profiles`;
|
|
120
214
|
`DSH_HOME` defaults to `~/.dsh`. A `no_existing_profiles` result means DSH has
|
|
121
215
|
not created a valid Profile in that home. A `dsh_version_unavailable` result
|
|
122
|
-
means the selected
|
|
216
|
+
means neither the selected DSH command nor an existing Profile-linked DSH
|
|
217
|
+
runtime supplied a valid semantic version. A `dsh_profile_runtime_stale` result
|
|
218
|
+
means that Profile-linked package is invalid or its original package cache is
|
|
219
|
+
no longer available. Repair or relaunch DSH itself, then rerun the MemoraX Code
|
|
220
|
+
start command. MemoraX Code never invokes `npx` or installs or updates DSH. The
|
|
123
221
|
tested baseline is `0.1.0-rc.6`; another valid version is allowed but marked
|
|
124
222
|
untested. A `pnpm_not_found` result means DSH's native Profile plugin manager
|
|
125
223
|
could not find `pnpm` on `PATH`; install `pnpm`, then rerun the start command.
|
|
@@ -4,6 +4,10 @@ export type JsonFileLockOptions = Readonly<{
|
|
|
4
4
|
retryMs?: number;
|
|
5
5
|
}>;
|
|
6
6
|
|
|
7
|
+
export type AsyncJsonFileLockOptions = JsonFileLockOptions & Readonly<{
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}>;
|
|
10
|
+
|
|
7
11
|
export function readAdapterState(path: string): any;
|
|
8
12
|
export function readJsonFile(path: string): any;
|
|
9
13
|
export function readJsonValue(path: string): any;
|
|
@@ -23,5 +27,5 @@ export function withJsonFileLock<T>(
|
|
|
23
27
|
export function withJsonFileLockAsync<T>(
|
|
24
28
|
path: string,
|
|
25
29
|
operation: () => T | Promise<T>,
|
|
26
|
-
options?:
|
|
30
|
+
options?: AsyncJsonFileLockOptions,
|
|
27
31
|
): Promise<T>;
|