memax-cli 0.1.0-alpha.26 → 0.1.0-alpha.28
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/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +8 -2
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/recall.d.ts +5 -0
- package/dist/commands/recall.d.ts.map +1 -1
- package/dist/commands/recall.js +89 -6
- package/dist/commands/recall.js.map +1 -1
- package/dist/commands/recall.test.d.ts +2 -0
- package/dist/commands/recall.test.d.ts.map +1 -0
- package/dist/commands/recall.test.js +23 -0
- package/dist/commands/recall.test.js.map +1 -0
- package/dist/commands/setup-mcp.d.ts.map +1 -1
- package/dist/commands/setup-mcp.js +3 -3
- package/dist/commands/setup-mcp.js.map +1 -1
- package/dist/commands/sync.d.ts +26 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +508 -79
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/sync.test.d.ts +2 -0
- package/dist/commands/sync.test.d.ts.map +1 -0
- package/dist/commands/sync.test.js +130 -0
- package/dist/commands/sync.test.js.map +1 -0
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +33 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +63 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/project-context.d.ts +14 -4
- package/dist/lib/project-context.d.ts.map +1 -1
- package/dist/lib/project-context.js +98 -54
- package/dist/lib/project-context.js.map +1 -1
- package/dist/lib/project-context.test.d.ts +2 -0
- package/dist/lib/project-context.test.d.ts.map +1 -0
- package/dist/lib/project-context.test.js +75 -0
- package/dist/lib/project-context.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -29,40 +29,105 @@ export function normalizeRepoUrl(url) {
|
|
|
29
29
|
s = s.toLowerCase().replace(/\\/g, "/");
|
|
30
30
|
return s;
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
function normalizeProjectID(projectID) {
|
|
33
|
+
let s = projectID.trim();
|
|
34
|
+
s = s.replace(/^project:/, "");
|
|
35
|
+
s = normalizeRepoUrl(s);
|
|
36
|
+
if (!s || /\s/.test(s)) {
|
|
37
|
+
throw new Error("invalid project_id");
|
|
38
|
+
}
|
|
39
|
+
return s;
|
|
40
|
+
}
|
|
41
|
+
function findNearestMemaxYml(startDir) {
|
|
42
|
+
let dir = startDir;
|
|
43
|
+
const root = "/";
|
|
44
|
+
while (true) {
|
|
45
|
+
const ymlPath = join(dir, ".memax.yml");
|
|
46
|
+
if (existsSync(ymlPath)) {
|
|
47
|
+
return ymlPath;
|
|
48
|
+
}
|
|
49
|
+
const parent = join(dir, "..");
|
|
50
|
+
if (parent === dir || dir === root)
|
|
51
|
+
break;
|
|
52
|
+
dir = parent;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
export function readMemaxYmlConfig(dir) {
|
|
41
57
|
const cwd = dir ?? process.cwd();
|
|
58
|
+
const ymlPath = findNearestMemaxYml(cwd);
|
|
59
|
+
if (!ymlPath) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
42
62
|
try {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
63
|
+
const content = readFileSync(ymlPath, "utf-8");
|
|
64
|
+
const hubMatch = content.match(/^hub:\s*(.+)$/m);
|
|
65
|
+
const projectMatch = content.match(/^project_id:\s*(.+)$/m);
|
|
66
|
+
const cfg = {};
|
|
67
|
+
if (hubMatch) {
|
|
68
|
+
cfg.hub = hubMatch[1].trim();
|
|
69
|
+
}
|
|
70
|
+
if (projectMatch) {
|
|
71
|
+
cfg.project_id = normalizeProjectID(projectMatch[1].trim());
|
|
72
|
+
}
|
|
73
|
+
if (!cfg.hub && !cfg.project_id) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
return cfg;
|
|
51
77
|
}
|
|
52
|
-
catch {
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function getGitOriginProjectID(cwd) {
|
|
53
83
|
try {
|
|
54
|
-
const
|
|
84
|
+
const repo = execSync("git remote get-url origin", {
|
|
55
85
|
cwd,
|
|
56
86
|
encoding: "utf-8",
|
|
57
87
|
timeout: 2000,
|
|
58
88
|
stdio: ["pipe", "pipe", "pipe"],
|
|
59
89
|
}).trim();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
if (repo) {
|
|
91
|
+
return normalizeRepoUrl(repo);
|
|
92
|
+
}
|
|
63
93
|
}
|
|
64
94
|
catch { }
|
|
65
|
-
return
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get a canonical project scope string for the given directory.
|
|
99
|
+
*
|
|
100
|
+
* Returns:
|
|
101
|
+
* "project:<project-id>" — .memax.yml project_id or git remote available
|
|
102
|
+
* "project" — no canonical cross-device project identity
|
|
103
|
+
*/
|
|
104
|
+
export function getProjectScope(dir) {
|
|
105
|
+
return resolveProjectScope(dir).scope;
|
|
106
|
+
}
|
|
107
|
+
export function resolveProjectScope(dir) {
|
|
108
|
+
const cwd = dir ?? process.cwd();
|
|
109
|
+
const memaxCfg = readMemaxYmlConfig(cwd);
|
|
110
|
+
const gitProjectID = getGitOriginProjectID(cwd);
|
|
111
|
+
if (memaxCfg?.project_id) {
|
|
112
|
+
const warning = gitProjectID && gitProjectID !== memaxCfg.project_id
|
|
113
|
+
? `.memax.yml project_id (${memaxCfg.project_id}) overrides git origin (${gitProjectID})`
|
|
114
|
+
: undefined;
|
|
115
|
+
return {
|
|
116
|
+
scope: `project:${memaxCfg.project_id}`,
|
|
117
|
+
source: "memax_yml",
|
|
118
|
+
warning,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (gitProjectID) {
|
|
122
|
+
return {
|
|
123
|
+
scope: `project:${gitProjectID}`,
|
|
124
|
+
source: "git_remote",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
scope: "project",
|
|
129
|
+
source: "fallback",
|
|
130
|
+
};
|
|
66
131
|
}
|
|
67
132
|
/**
|
|
68
133
|
* Resolve a Claude Code mangled project folder name to a normalized repo URL.
|
|
@@ -78,18 +143,11 @@ export function resolveClaudeProjectFolder(mangledName) {
|
|
|
78
143
|
const absolutePath = mangledName.replace(/-/g, "/");
|
|
79
144
|
if (!existsSync(absolutePath))
|
|
80
145
|
return null;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
encoding: "utf-8",
|
|
85
|
-
timeout: 2000,
|
|
86
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
87
|
-
}).trim();
|
|
88
|
-
if (repo)
|
|
89
|
-
return normalizeRepoUrl(repo);
|
|
146
|
+
const resolution = resolveProjectScope(absolutePath);
|
|
147
|
+
if (resolution.scope === "project") {
|
|
148
|
+
return null;
|
|
90
149
|
}
|
|
91
|
-
|
|
92
|
-
return null;
|
|
150
|
+
return resolution.scope.replace(/^project:/, "");
|
|
93
151
|
}
|
|
94
152
|
/**
|
|
95
153
|
* Normalize a file path for cross-platform consistency.
|
|
@@ -101,10 +159,12 @@ export function normalizeFilePath(p) {
|
|
|
101
159
|
return p.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
102
160
|
}
|
|
103
161
|
/** Detect git project context (repo URL, project name, branch). */
|
|
104
|
-
export function detectProjectContext() {
|
|
162
|
+
export function detectProjectContext(dir) {
|
|
163
|
+
const cwd = dir ?? process.cwd();
|
|
105
164
|
const ctx = {};
|
|
106
165
|
try {
|
|
107
166
|
const repo = execSync("git remote get-url origin", {
|
|
167
|
+
cwd,
|
|
108
168
|
encoding: "utf-8",
|
|
109
169
|
timeout: 2000,
|
|
110
170
|
}).trim();
|
|
@@ -114,6 +174,7 @@ export function detectProjectContext() {
|
|
|
114
174
|
catch { }
|
|
115
175
|
try {
|
|
116
176
|
const project = execSync("git rev-parse --show-toplevel", {
|
|
177
|
+
cwd,
|
|
117
178
|
encoding: "utf-8",
|
|
118
179
|
timeout: 2000,
|
|
119
180
|
}).trim();
|
|
@@ -123,6 +184,7 @@ export function detectProjectContext() {
|
|
|
123
184
|
catch { }
|
|
124
185
|
try {
|
|
125
186
|
const branch = execSync("git branch --show-current", {
|
|
187
|
+
cwd,
|
|
126
188
|
encoding: "utf-8",
|
|
127
189
|
timeout: 2000,
|
|
128
190
|
}).trim();
|
|
@@ -134,24 +196,6 @@ export function detectProjectContext() {
|
|
|
134
196
|
}
|
|
135
197
|
/** Walk up from cwd looking for .memax.yml with a hub field. */
|
|
136
198
|
export function readMemaxYmlHub() {
|
|
137
|
-
|
|
138
|
-
const root = "/";
|
|
139
|
-
while (true) {
|
|
140
|
-
const ymlPath = join(dir, ".memax.yml");
|
|
141
|
-
if (existsSync(ymlPath)) {
|
|
142
|
-
try {
|
|
143
|
-
const content = readFileSync(ymlPath, "utf-8");
|
|
144
|
-
const match = content.match(/^hub:\s*(.+)$/m);
|
|
145
|
-
if (match)
|
|
146
|
-
return match[1].trim();
|
|
147
|
-
}
|
|
148
|
-
catch { }
|
|
149
|
-
}
|
|
150
|
-
const parent = join(dir, "..");
|
|
151
|
-
if (parent === dir || dir === root)
|
|
152
|
-
break;
|
|
153
|
-
dir = parent;
|
|
154
|
-
}
|
|
155
|
-
return undefined;
|
|
199
|
+
return readMemaxYmlConfig()?.hub;
|
|
156
200
|
}
|
|
157
201
|
//# sourceMappingURL=project-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-context.js","sourceRoot":"","sources":["../../src/lib/project-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnB,4CAA4C;IAC5C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,kCAAkC,EAAE,EAAE,CAAC,CAAC;IACtD,kCAAkC;IAClC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC7B,uEAAuE;IACvE,uEAAuE;IACvE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC5C,qBAAqB;IACrB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC5B,mBAAmB;IACnB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1B,8BAA8B;IAC9B,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC;AACX,CAAC;
|
|
1
|
+
{"version":3,"file":"project-context.js","sourceRoot":"","sources":["../../src/lib/project-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.test.d.ts","sourceRoot":"","sources":["../../src/lib/project-context.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const { execSync, existsSync, readFileSync } = vi.hoisted(() => ({
|
|
3
|
+
execSync: vi.fn(),
|
|
4
|
+
existsSync: vi.fn(),
|
|
5
|
+
readFileSync: vi.fn(),
|
|
6
|
+
}));
|
|
7
|
+
vi.mock("node:child_process", () => ({
|
|
8
|
+
execSync,
|
|
9
|
+
}));
|
|
10
|
+
vi.mock("node:fs", async () => {
|
|
11
|
+
const actual = await vi.importActual("node:fs");
|
|
12
|
+
return {
|
|
13
|
+
...actual,
|
|
14
|
+
existsSync,
|
|
15
|
+
readFileSync,
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
import { getProjectScope, normalizeRepoUrl, readMemaxYmlConfig, readMemaxYmlHub, resolveProjectScope, } from "./project-context.js";
|
|
19
|
+
describe("normalizeRepoUrl", () => {
|
|
20
|
+
it("normalizes common git remote forms", () => {
|
|
21
|
+
expect(normalizeRepoUrl("https://github.com/MemaxLabs/memax.git")).toBe("github.com/memaxlabs/memax");
|
|
22
|
+
expect(normalizeRepoUrl("git@github.com:MemaxLabs/memax.git")).toBe("github.com/memaxlabs/memax");
|
|
23
|
+
expect(normalizeRepoUrl("ssh://git@github.com/MemaxLabs/memax")).toBe("github.com/memaxlabs/memax");
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe("getProjectScope", () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
execSync.mockReset();
|
|
29
|
+
existsSync.mockReset();
|
|
30
|
+
readFileSync.mockReset();
|
|
31
|
+
existsSync.mockReturnValue(false);
|
|
32
|
+
});
|
|
33
|
+
it("uses the normalized origin remote when present", () => {
|
|
34
|
+
execSync.mockReturnValueOnce("git@github.com:MemaxLabs/memax.git\n");
|
|
35
|
+
expect(getProjectScope("/workspaces/memax")).toBe("project:github.com/memaxlabs/memax");
|
|
36
|
+
});
|
|
37
|
+
it("returns generic project scope when there is no canonical remote", () => {
|
|
38
|
+
execSync.mockImplementation(() => {
|
|
39
|
+
throw new Error("no remote");
|
|
40
|
+
});
|
|
41
|
+
expect(getProjectScope("/workspaces/memax")).toBe("project");
|
|
42
|
+
});
|
|
43
|
+
it("uses .memax.yml project_id as an explicit override", () => {
|
|
44
|
+
existsSync.mockImplementation((path) => path.endsWith(".memax.yml"));
|
|
45
|
+
readFileSync.mockReturnValue("project_id: Acme.Internal/Payments-API\n");
|
|
46
|
+
expect(getProjectScope("/workspaces/memax")).toBe("project:acme.internal/payments-api");
|
|
47
|
+
});
|
|
48
|
+
it("reports when .memax.yml project_id overrides git origin", () => {
|
|
49
|
+
existsSync.mockImplementation((path) => path.endsWith(".memax.yml"));
|
|
50
|
+
readFileSync.mockReturnValue("project_id: github.com/acme/override\n");
|
|
51
|
+
execSync.mockReturnValueOnce("git@github.com:MemaxLabs/memax.git\n");
|
|
52
|
+
expect(resolveProjectScope("/workspaces/memax")).toEqual({
|
|
53
|
+
scope: "project:github.com/acme/override",
|
|
54
|
+
source: "memax_yml",
|
|
55
|
+
warning: ".memax.yml project_id (github.com/acme/override) overrides git origin (github.com/memaxlabs/memax)",
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("readMemaxYmlConfig", () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
existsSync.mockReset();
|
|
62
|
+
readFileSync.mockReset();
|
|
63
|
+
existsSync.mockReturnValue(false);
|
|
64
|
+
});
|
|
65
|
+
it("parses hub and project_id from .memax.yml", () => {
|
|
66
|
+
existsSync.mockImplementation((path) => path.endsWith(".memax.yml"));
|
|
67
|
+
readFileSync.mockReturnValue("hub: team-backend\nproject_id: github.com/MemaxLabs/memax\n");
|
|
68
|
+
expect(readMemaxYmlConfig("/workspaces/memax")).toEqual({
|
|
69
|
+
hub: "team-backend",
|
|
70
|
+
project_id: "github.com/memaxlabs/memax",
|
|
71
|
+
});
|
|
72
|
+
expect(readMemaxYmlHub()).toBe("team-backend");
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=project-context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-context.test.js","sourceRoot":"","sources":["../../src/lib/project-context.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memax-cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.28",
|
|
4
4
|
"description": "CLI for Memax — universal context & memory hub for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
17
17
|
"chalk": "^5.4.0",
|
|
18
18
|
"commander": "^13.0.0",
|
|
19
|
-
"memax-sdk": "^0.1.
|
|
19
|
+
"memax-sdk": "^0.1.3"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^25.5.0",
|