memax-cli 0.1.0-alpha.9 → 0.1.0

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.
Files changed (197) hide show
  1. package/assets/skills/memax-memory/SKILL.md +173 -0
  2. package/dist/commands/agent-configs.d.ts +41 -0
  3. package/dist/commands/agent-configs.d.ts.map +1 -0
  4. package/dist/commands/agent-configs.js +1290 -0
  5. package/dist/commands/agent-configs.js.map +1 -0
  6. package/dist/commands/agent-configs.test.d.ts +2 -0
  7. package/dist/commands/agent-configs.test.d.ts.map +1 -0
  8. package/dist/commands/agent-configs.test.js +122 -0
  9. package/dist/commands/agent-configs.test.js.map +1 -0
  10. package/dist/commands/agent-sessions.d.ts +74 -0
  11. package/dist/commands/agent-sessions.d.ts.map +1 -0
  12. package/dist/commands/agent-sessions.js +1513 -0
  13. package/dist/commands/agent-sessions.js.map +1 -0
  14. package/dist/commands/agent-sessions.test.d.ts +2 -0
  15. package/dist/commands/agent-sessions.test.d.ts.map +1 -0
  16. package/dist/commands/agent-sessions.test.js +255 -0
  17. package/dist/commands/agent-sessions.test.js.map +1 -0
  18. package/dist/commands/agents.d.ts +3 -0
  19. package/dist/commands/agents.d.ts.map +1 -0
  20. package/dist/commands/agents.js +36 -0
  21. package/dist/commands/agents.js.map +1 -0
  22. package/dist/commands/ask.d.ts +15 -0
  23. package/dist/commands/ask.d.ts.map +1 -0
  24. package/dist/commands/ask.js +483 -0
  25. package/dist/commands/ask.js.map +1 -0
  26. package/dist/commands/auth.d.ts +7 -0
  27. package/dist/commands/auth.d.ts.map +1 -1
  28. package/dist/commands/auth.js +103 -8
  29. package/dist/commands/auth.js.map +1 -1
  30. package/dist/commands/capture.d.ts +19 -0
  31. package/dist/commands/capture.d.ts.map +1 -0
  32. package/dist/commands/capture.js +69 -0
  33. package/dist/commands/capture.js.map +1 -0
  34. package/dist/commands/config.d.ts +2 -0
  35. package/dist/commands/config.d.ts.map +1 -1
  36. package/dist/commands/config.js +13 -0
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/delete.d.ts +2 -0
  39. package/dist/commands/delete.d.ts.map +1 -1
  40. package/dist/commands/delete.js +15 -18
  41. package/dist/commands/delete.js.map +1 -1
  42. package/dist/commands/dreams.d.ts +22 -0
  43. package/dist/commands/dreams.d.ts.map +1 -0
  44. package/dist/commands/dreams.js +251 -0
  45. package/dist/commands/dreams.js.map +1 -0
  46. package/dist/commands/dreams.test.d.ts +2 -0
  47. package/dist/commands/dreams.test.d.ts.map +1 -0
  48. package/dist/commands/dreams.test.js +39 -0
  49. package/dist/commands/dreams.test.js.map +1 -0
  50. package/dist/commands/hook.d.ts +2 -0
  51. package/dist/commands/hook.d.ts.map +1 -1
  52. package/dist/commands/hook.js +25 -103
  53. package/dist/commands/hook.js.map +1 -1
  54. package/dist/commands/hub.d.ts +37 -0
  55. package/dist/commands/hub.d.ts.map +1 -0
  56. package/dist/commands/hub.js +347 -0
  57. package/dist/commands/hub.js.map +1 -0
  58. package/dist/commands/hub.test.d.ts +2 -0
  59. package/dist/commands/hub.test.d.ts.map +1 -0
  60. package/dist/commands/hub.test.js +62 -0
  61. package/dist/commands/hub.test.js.map +1 -0
  62. package/dist/commands/import.d.ts +13 -0
  63. package/dist/commands/import.d.ts.map +1 -0
  64. package/dist/commands/import.js +257 -0
  65. package/dist/commands/import.js.map +1 -0
  66. package/dist/commands/import.test.d.ts +2 -0
  67. package/dist/commands/import.test.d.ts.map +1 -0
  68. package/dist/commands/import.test.js +11 -0
  69. package/dist/commands/import.test.js.map +1 -0
  70. package/dist/commands/list.d.ts +9 -2
  71. package/dist/commands/list.d.ts.map +1 -1
  72. package/dist/commands/list.js +118 -9
  73. package/dist/commands/list.js.map +1 -1
  74. package/dist/commands/list.test.d.ts +2 -0
  75. package/dist/commands/list.test.d.ts.map +1 -0
  76. package/dist/commands/list.test.js +20 -0
  77. package/dist/commands/list.test.js.map +1 -0
  78. package/dist/commands/login.d.ts +7 -1
  79. package/dist/commands/login.d.ts.map +1 -1
  80. package/dist/commands/login.js +81 -20
  81. package/dist/commands/login.js.map +1 -1
  82. package/dist/commands/mcp.d.ts.map +1 -1
  83. package/dist/commands/mcp.js +386 -65
  84. package/dist/commands/mcp.js.map +1 -1
  85. package/dist/commands/push.d.ts +6 -1
  86. package/dist/commands/push.d.ts.map +1 -1
  87. package/dist/commands/push.js +42 -8
  88. package/dist/commands/push.js.map +1 -1
  89. package/dist/commands/recall.d.ts +11 -1
  90. package/dist/commands/recall.d.ts.map +1 -1
  91. package/dist/commands/recall.js +228 -41
  92. package/dist/commands/recall.js.map +1 -1
  93. package/dist/commands/recall.test.d.ts +2 -0
  94. package/dist/commands/recall.test.d.ts.map +1 -0
  95. package/dist/commands/recall.test.js +31 -0
  96. package/dist/commands/recall.test.js.map +1 -0
  97. package/dist/commands/setup-hooks.d.ts +13 -0
  98. package/dist/commands/setup-hooks.d.ts.map +1 -0
  99. package/dist/commands/setup-hooks.js +193 -0
  100. package/dist/commands/setup-hooks.js.map +1 -0
  101. package/dist/commands/setup-instructions.d.ts +21 -0
  102. package/dist/commands/setup-instructions.d.ts.map +1 -0
  103. package/dist/commands/setup-instructions.js +172 -0
  104. package/dist/commands/setup-instructions.js.map +1 -0
  105. package/dist/commands/setup-mcp.d.ts +40 -0
  106. package/dist/commands/setup-mcp.d.ts.map +1 -0
  107. package/dist/commands/setup-mcp.js +414 -0
  108. package/dist/commands/setup-mcp.js.map +1 -0
  109. package/dist/commands/setup-types.d.ts +33 -0
  110. package/dist/commands/setup-types.d.ts.map +1 -0
  111. package/dist/commands/setup-types.js +60 -0
  112. package/dist/commands/setup-types.js.map +1 -0
  113. package/dist/commands/setup.d.ts +10 -1
  114. package/dist/commands/setup.d.ts.map +1 -1
  115. package/dist/commands/setup.js +216 -534
  116. package/dist/commands/setup.js.map +1 -1
  117. package/dist/commands/show.d.ts +5 -1
  118. package/dist/commands/show.d.ts.map +1 -1
  119. package/dist/commands/show.js +36 -14
  120. package/dist/commands/show.js.map +1 -1
  121. package/dist/commands/topic.d.ts +32 -0
  122. package/dist/commands/topic.d.ts.map +1 -0
  123. package/dist/commands/topic.js +265 -0
  124. package/dist/commands/topic.js.map +1 -0
  125. package/dist/commands/topic.test.d.ts +2 -0
  126. package/dist/commands/topic.test.d.ts.map +1 -0
  127. package/dist/commands/topic.test.js +114 -0
  128. package/dist/commands/topic.test.js.map +1 -0
  129. package/dist/index.js +35 -144
  130. package/dist/index.js.map +1 -1
  131. package/dist/lib/client.d.ts +10 -0
  132. package/dist/lib/client.d.ts.map +1 -0
  133. package/dist/lib/client.js +104 -0
  134. package/dist/lib/client.js.map +1 -0
  135. package/dist/lib/client.test.d.ts +2 -0
  136. package/dist/lib/client.test.d.ts.map +1 -0
  137. package/dist/lib/client.test.js +44 -0
  138. package/dist/lib/client.test.js.map +1 -0
  139. package/dist/lib/config.d.ts +43 -0
  140. package/dist/lib/config.d.ts.map +1 -1
  141. package/dist/lib/config.js +72 -1
  142. package/dist/lib/config.js.map +1 -1
  143. package/dist/lib/credentials.d.ts +3 -0
  144. package/dist/lib/credentials.d.ts.map +1 -1
  145. package/dist/lib/credentials.js +24 -2
  146. package/dist/lib/credentials.js.map +1 -1
  147. package/dist/lib/hubs.d.ts +7 -0
  148. package/dist/lib/hubs.d.ts.map +1 -0
  149. package/dist/lib/hubs.js +33 -0
  150. package/dist/lib/hubs.js.map +1 -0
  151. package/dist/lib/hubs.test.d.ts +2 -0
  152. package/dist/lib/hubs.test.d.ts.map +1 -0
  153. package/dist/lib/hubs.test.js +58 -0
  154. package/dist/lib/hubs.test.js.map +1 -0
  155. package/dist/lib/project-context.d.ts +56 -0
  156. package/dist/lib/project-context.d.ts.map +1 -0
  157. package/dist/lib/project-context.js +225 -0
  158. package/dist/lib/project-context.js.map +1 -0
  159. package/dist/lib/project-context.test.d.ts +2 -0
  160. package/dist/lib/project-context.test.d.ts.map +1 -0
  161. package/dist/lib/project-context.test.js +75 -0
  162. package/dist/lib/project-context.test.js.map +1 -0
  163. package/dist/lib/prompt.d.ts +7 -0
  164. package/dist/lib/prompt.d.ts.map +1 -0
  165. package/dist/lib/prompt.js +41 -0
  166. package/dist/lib/prompt.js.map +1 -0
  167. package/dist/lib/trash.d.ts +6 -0
  168. package/dist/lib/trash.d.ts.map +1 -0
  169. package/dist/lib/trash.js +28 -0
  170. package/dist/lib/trash.js.map +1 -0
  171. package/package.json +17 -13
  172. package/.vscode/mcp.json +0 -8
  173. package/dist/commands/sync.d.ts +0 -12
  174. package/dist/commands/sync.d.ts.map +0 -1
  175. package/dist/commands/sync.js +0 -414
  176. package/dist/commands/sync.js.map +0 -1
  177. package/dist/lib/api.d.ts +0 -4
  178. package/dist/lib/api.d.ts.map +0 -1
  179. package/dist/lib/api.js +0 -95
  180. package/dist/lib/api.js.map +0 -1
  181. package/src/commands/auth.ts +0 -92
  182. package/src/commands/config.ts +0 -27
  183. package/src/commands/delete.ts +0 -58
  184. package/src/commands/hook.ts +0 -243
  185. package/src/commands/list.ts +0 -38
  186. package/src/commands/login.ts +0 -164
  187. package/src/commands/mcp.ts +0 -405
  188. package/src/commands/push.ts +0 -137
  189. package/src/commands/recall.ts +0 -163
  190. package/src/commands/setup.ts +0 -1077
  191. package/src/commands/show.ts +0 -35
  192. package/src/commands/sync.ts +0 -506
  193. package/src/index.ts +0 -213
  194. package/src/lib/api.ts +0 -110
  195. package/src/lib/config.ts +0 -61
  196. package/src/lib/credentials.ts +0 -42
  197. package/tsconfig.json +0 -9
@@ -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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"}
@@ -0,0 +1,7 @@
1
+ /** Ask a yes/no question. Returns true if user answers 'y'. */
2
+ export declare function confirm(message: string): Promise<boolean>;
3
+ /** Ask a question and return the trimmed answer. */
4
+ export declare function ask(message: string): Promise<string>;
5
+ /** Ask a yes/no question where Enter defaults to yes. */
6
+ export declare function confirmDefault(message: string): Promise<boolean>;
7
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/lib/prompt.ts"],"names":[],"mappings":"AAEA,+DAA+D;AAC/D,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWzD;AAED,oDAAoD;AACpD,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWpD;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWhE"}
@@ -0,0 +1,41 @@
1
+ import { createInterface } from "node:readline";
2
+ /** Ask a yes/no question. Returns true if user answers 'y'. */
3
+ export function confirm(message) {
4
+ return new Promise((resolve) => {
5
+ const rl = createInterface({
6
+ input: process.stdin,
7
+ output: process.stdout,
8
+ });
9
+ rl.question(message, (answer) => {
10
+ rl.close();
11
+ resolve(answer.trim().toLowerCase() === "y");
12
+ });
13
+ });
14
+ }
15
+ /** Ask a question and return the trimmed answer. */
16
+ export function ask(message) {
17
+ return new Promise((resolve) => {
18
+ const rl = createInterface({
19
+ input: process.stdin,
20
+ output: process.stdout,
21
+ });
22
+ rl.question(message, (answer) => {
23
+ rl.close();
24
+ resolve(answer.trim());
25
+ });
26
+ });
27
+ }
28
+ /** Ask a yes/no question where Enter defaults to yes. */
29
+ export function confirmDefault(message) {
30
+ return new Promise((resolve) => {
31
+ const rl = createInterface({
32
+ input: process.stdin,
33
+ output: process.stdout,
34
+ });
35
+ rl.question(message, (answer) => {
36
+ rl.close();
37
+ resolve(answer.trim().toLowerCase() !== "n");
38
+ });
39
+ });
40
+ }
41
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/lib/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAC9B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface TrashMoveResult {
2
+ moved: boolean;
3
+ trashPath?: string;
4
+ }
5
+ export declare function moveFileToTrash(sourcePath: string, kind: "agent-configs" | "agent-sessions"): TrashMoveResult;
6
+ //# sourceMappingURL=trash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trash.d.ts","sourceRoot":"","sources":["../../src/lib/trash.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,eAAe,GAAG,gBAAgB,GACvC,eAAe,CAiBjB"}
@@ -0,0 +1,28 @@
1
+ import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync, } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { getConfigDir } from "./config.js";
4
+ function makeTrashPath(kind, sourcePath) {
5
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
6
+ const normalized = sourcePath.replace(/^\/+/, "");
7
+ return join(getConfigDir(), "trash", kind, timestamp, normalized);
8
+ }
9
+ export function moveFileToTrash(sourcePath, kind) {
10
+ if (!existsSync(sourcePath)) {
11
+ return { moved: false };
12
+ }
13
+ const trashPath = makeTrashPath(kind, sourcePath);
14
+ mkdirSync(dirname(trashPath), { recursive: true });
15
+ try {
16
+ renameSync(sourcePath, trashPath);
17
+ }
18
+ catch (err) {
19
+ const error = err;
20
+ if (error.code !== "EXDEV") {
21
+ throw err;
22
+ }
23
+ copyFileSync(sourcePath, trashPath);
24
+ rmSync(sourcePath);
25
+ }
26
+ return { moved: true, trashPath };
27
+ }
28
+ //# sourceMappingURL=trash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trash.js","sourceRoot":"","sources":["../../src/lib/trash.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,UAAU,EACV,MAAM,GACP,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,SAAS,aAAa,CAAC,IAAY,EAAE,UAAkB;IACrD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,UAAkB,EAClB,IAAwC;IAExC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAA4B,CAAC;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACpC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memax-cli",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.1.0",
4
4
  "description": "CLI for Memax — universal context & memory hub for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,21 +12,13 @@
12
12
  "import": "./dist/index.js"
13
13
  }
14
14
  },
15
- "scripts": {
16
- "build": "tsc",
17
- "dev": "tsc --watch",
18
- "start": "node dist/index.js",
19
- "lint": "tsc --noEmit",
20
- "test": "vitest run --passWithNoTests",
21
- "clean": "rm -rf dist"
22
- },
23
15
  "dependencies": {
24
16
  "@modelcontextprotocol/sdk": "^1.12.1",
25
17
  "chalk": "^5.4.0",
26
- "commander": "^13.0.0"
18
+ "commander": "^13.0.0",
19
+ "memax-sdk": "^0.4.0"
27
20
  },
28
21
  "devDependencies": {
29
- "@memaxlabs/shared": "workspace:*",
30
22
  "@types/node": "^25.5.0",
31
23
  "typescript": "^5.8.0",
32
24
  "vitest": "^3.0.0"
@@ -40,5 +32,17 @@
40
32
  "claude-code",
41
33
  "agent"
42
34
  ],
43
- "license": "UNLICENSED"
44
- }
35
+ "files": [
36
+ "dist",
37
+ "assets"
38
+ ],
39
+ "license": "UNLICENSED",
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "start": "node dist/index.js",
44
+ "lint": "tsc --noEmit",
45
+ "test": "vitest run --passWithNoTests",
46
+ "clean": "rm -rf dist"
47
+ }
48
+ }
package/.vscode/mcp.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "servers": {
3
- "memax": {
4
- "command": "memax",
5
- "args": ["mcp", "serve"]
6
- }
7
- }
8
- }
@@ -1,12 +0,0 @@
1
- interface SyncOptions {
2
- boundary?: string;
3
- category?: string;
4
- watch?: boolean;
5
- ignore?: string;
6
- agentMemory?: boolean;
7
- yes?: boolean;
8
- }
9
- export declare function syncAgentMemoryCommand(): Promise<void>;
10
- export declare function syncCommand(directory: string | undefined, options: SyncOptions): Promise<void>;
11
- export {};
12
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAcA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAsCD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAwFf"}
@@ -1,414 +0,0 @@
1
- import chalk from "chalk";
2
- import { readFileSync, readdirSync, statSync, watch, existsSync, } from "node:fs";
3
- import { createInterface } from "node:readline";
4
- import { join, relative, extname, resolve, basename } from "node:path";
5
- import { homedir } from "node:os";
6
- import { apiPost } from "../lib/api.js";
7
- const DEFAULT_IGNORE = new Set([
8
- "node_modules",
9
- ".git",
10
- ".next",
11
- "dist",
12
- "__pycache__",
13
- ".env",
14
- ".env.local",
15
- ".DS_Store",
16
- ]);
17
- const SUPPORTED_EXTENSIONS = new Set([
18
- ".md",
19
- ".txt",
20
- ".ts",
21
- ".tsx",
22
- ".js",
23
- ".jsx",
24
- ".go",
25
- ".py",
26
- ".rs",
27
- ".yaml",
28
- ".yml",
29
- ".json",
30
- ".toml",
31
- ".sh",
32
- ".bash",
33
- ".zsh",
34
- ".css",
35
- ".html",
36
- ".sql",
37
- ".graphql",
38
- ".proto",
39
- ".dockerfile",
40
- ]);
41
- export async function syncAgentMemoryCommand() {
42
- await syncAgentMemory();
43
- }
44
- export async function syncCommand(directory, options) {
45
- if (options.agentMemory || directory === "agents") {
46
- await syncAgentMemory();
47
- return;
48
- }
49
- const dir = directory ?? ".";
50
- const customIgnore = options.ignore
51
- ? new Set(options.ignore.split(",").map((s) => s.trim()))
52
- : new Set();
53
- const ignoreSet = new Set([...DEFAULT_IGNORE, ...customIgnore]);
54
- console.log(chalk.blue("Scanning"), dir);
55
- const files = walkDir(dir, ignoreSet);
56
- if (files.length === 0) {
57
- console.log(chalk.yellow("No supported files found."));
58
- return;
59
- }
60
- console.log(chalk.gray(`Found ${files.length} files to sync`));
61
- // Confirm if many files (>10) unless -y is passed
62
- if (files.length > 10 && !options.yes) {
63
- console.log(chalk.yellow(`\n This will push ${files.length} files. Continue? (y/N) `));
64
- const confirmed = await confirmSync();
65
- if (!confirmed) {
66
- console.log(chalk.gray(" Cancelled.\n"));
67
- return;
68
- }
69
- }
70
- console.log();
71
- let pushed = 0;
72
- let errors = 0;
73
- for (const file of files) {
74
- const result = await pushFile(file, options);
75
- if (result === "pushed")
76
- pushed++;
77
- else if (result === "error")
78
- errors++;
79
- }
80
- console.log();
81
- console.log(chalk.blue(`Synced ${pushed} files`), errors > 0 ? chalk.red(`(${errors} errors)`) : "");
82
- if (options.watch) {
83
- const resolvedDir = resolve(dir);
84
- console.log(chalk.cyan(`\nWatching ${dir} for changes... (Ctrl+C to stop)`));
85
- let debounceTimer = null;
86
- const pendingChanges = new Set();
87
- watch(resolvedDir, { recursive: true }, (_eventType, filename) => {
88
- if (!filename)
89
- return;
90
- const fullPath = join(resolvedDir, filename);
91
- if (!isSupportedFile(filename) || isIgnored(filename, ignoreSet))
92
- return;
93
- pendingChanges.add(fullPath);
94
- if (debounceTimer)
95
- clearTimeout(debounceTimer);
96
- debounceTimer = setTimeout(async () => {
97
- for (const file of pendingChanges) {
98
- if (!existsSync(file)) {
99
- console.log(chalk.gray(" ~"), relative(process.cwd(), file), chalk.gray("[deleted, skipped]"));
100
- continue;
101
- }
102
- await pushFile(file, options);
103
- }
104
- pendingChanges.clear();
105
- }, 500);
106
- });
107
- }
108
- }
109
- async function pushFile(file, options) {
110
- try {
111
- const content = readFileSync(file, "utf-8");
112
- if (!content.trim())
113
- return "skipped";
114
- const relPath = relative(process.cwd(), file);
115
- const ext = extname(file);
116
- const contentType = ext === ".md"
117
- ? "markdown"
118
- : ext === ".json" || ext === ".yaml" || ext === ".yml"
119
- ? "structured"
120
- : "code";
121
- const note = await apiPost("/v1/notes", {
122
- content,
123
- title: relPath,
124
- category: options.category ?? guessCategory(relPath),
125
- source: "sync",
126
- source_path: relPath,
127
- content_type: contentType,
128
- });
129
- console.log(chalk.green(" +"), relPath, chalk.gray(`[${note.category}]`));
130
- return "pushed";
131
- }
132
- catch (err) {
133
- console.log(chalk.red(" x"), file, chalk.gray(err.message));
134
- return "error";
135
- }
136
- }
137
- function isSupportedFile(filename) {
138
- return SUPPORTED_EXTENSIONS.has(extname(filename));
139
- }
140
- function isIgnored(filename, ignoreSet) {
141
- const parts = filename.split(/[/\\]/);
142
- return parts.some((part) => ignoreSet.has(part) || part.startsWith("."));
143
- }
144
- function walkDir(dir, ignore) {
145
- const files = [];
146
- function walk(currentDir) {
147
- let entries;
148
- try {
149
- entries = readdirSync(currentDir);
150
- }
151
- catch {
152
- return;
153
- }
154
- for (const entry of entries) {
155
- if (ignore.has(entry) || entry.startsWith("."))
156
- continue;
157
- const fullPath = join(currentDir, entry);
158
- let stat;
159
- try {
160
- stat = statSync(fullPath);
161
- }
162
- catch {
163
- continue;
164
- }
165
- if (stat.isDirectory()) {
166
- walk(fullPath);
167
- }
168
- else if (stat.isFile() && SUPPORTED_EXTENSIONS.has(extname(entry))) {
169
- files.push(fullPath);
170
- }
171
- }
172
- }
173
- walk(dir);
174
- return files;
175
- }
176
- function guessCategory(path) {
177
- const lower = path.toLowerCase();
178
- if (lower.includes("adr") || lower.includes("decision"))
179
- return "decisions/adr";
180
- if (lower.includes("deploy") || lower.includes("ci"))
181
- return "process/deploy";
182
- if (lower.includes("architecture") || lower.includes("design"))
183
- return "core/architecture";
184
- if (lower.includes("readme") || lower.includes("docs"))
185
- return "reference/api";
186
- if (lower.includes("test"))
187
- return "reference/api";
188
- if (lower.includes("config") || lower.includes(".env"))
189
- return "reference/config";
190
- return "daily/note";
191
- }
192
- function discoverAgentMemoryFiles() {
193
- const home = homedir();
194
- const cwd = process.cwd();
195
- const locations = [];
196
- // Claude Code global memory
197
- const claudeMemory = join(home, ".claude", "MEMORY.md");
198
- locations.push({ label: "~/.claude/MEMORY.md", path: claudeMemory });
199
- // Claude Code per-project memories: ~/.claude/projects/*/memory/*.md
200
- const claudeProjectsDir = join(home, ".claude", "projects");
201
- if (existsSync(claudeProjectsDir)) {
202
- try {
203
- for (const project of readdirSync(claudeProjectsDir)) {
204
- const memoryDir = join(claudeProjectsDir, project, "memory");
205
- if (existsSync(memoryDir)) {
206
- try {
207
- for (const file of readdirSync(memoryDir)) {
208
- if (file.endsWith(".md")) {
209
- locations.push({
210
- label: `~/.claude/projects/${project}/memory/${file}`,
211
- path: join(memoryDir, file),
212
- });
213
- }
214
- }
215
- }
216
- catch {
217
- // Permission denied or other read error — skip
218
- }
219
- }
220
- }
221
- }
222
- catch {
223
- // Permission denied or other read error — skip
224
- }
225
- }
226
- // Cursor rules (project-level)
227
- locations.push({ label: "./.cursorrules", path: join(cwd, ".cursorrules") });
228
- // Cursor scoped rules: .cursor/rules/*.mdc
229
- const cursorRulesDir = join(cwd, ".cursor", "rules");
230
- if (existsSync(cursorRulesDir)) {
231
- try {
232
- for (const file of readdirSync(cursorRulesDir)) {
233
- if (file.endsWith(".mdc")) {
234
- locations.push({
235
- label: `./.cursor/rules/${file}`,
236
- path: join(cursorRulesDir, file),
237
- });
238
- }
239
- }
240
- }
241
- catch {
242
- // Skip on error
243
- }
244
- }
245
- // Codex instructions
246
- locations.push({
247
- label: "./.codex/instructions.md",
248
- path: join(cwd, ".codex", "instructions.md"),
249
- });
250
- locations.push({
251
- label: "~/.codex/AGENTS.md",
252
- path: join(home, ".codex", "AGENTS.md"),
253
- });
254
- // Gemini CLI
255
- locations.push({
256
- label: "~/.gemini/GEMINI.md",
257
- path: join(home, ".gemini", "GEMINI.md"),
258
- });
259
- locations.push({ label: "./GEMINI.md", path: join(cwd, "GEMINI.md") });
260
- // GitHub Copilot
261
- locations.push({
262
- label: "./.github/copilot-instructions.md",
263
- path: join(cwd, ".github", "copilot-instructions.md"),
264
- });
265
- // Windsurf
266
- locations.push({
267
- label: "./.windsurfrules",
268
- path: join(cwd, ".windsurfrules"),
269
- });
270
- const windsurfRulesDir = join(cwd, ".windsurf", "rules");
271
- if (existsSync(windsurfRulesDir)) {
272
- try {
273
- for (const file of readdirSync(windsurfRulesDir)) {
274
- if (file.endsWith(".md")) {
275
- locations.push({
276
- label: `./.windsurf/rules/${file}`,
277
- path: join(windsurfRulesDir, file),
278
- });
279
- }
280
- }
281
- }
282
- catch {
283
- // Skip on error
284
- }
285
- }
286
- // OpenClaw memory
287
- const openclawMemoryDir = join(home, ".openclaw", "memory");
288
- if (existsSync(openclawMemoryDir)) {
289
- try {
290
- for (const file of readdirSync(openclawMemoryDir)) {
291
- if (file.endsWith(".md") || file.endsWith(".json")) {
292
- locations.push({
293
- label: `~/.openclaw/memory/${file}`,
294
- path: join(openclawMemoryDir, file),
295
- });
296
- }
297
- }
298
- }
299
- catch {
300
- // Skip on error
301
- }
302
- }
303
- // OpenCode (anomalyco) context
304
- const opencodePath = join(cwd, ".opencode");
305
- if (existsSync(opencodePath)) {
306
- // Check for any markdown context files in .opencode/
307
- try {
308
- for (const file of readdirSync(opencodePath)) {
309
- if (file.endsWith(".md")) {
310
- locations.push({
311
- label: `./.opencode/${file}`,
312
- path: join(opencodePath, file),
313
- });
314
- }
315
- }
316
- }
317
- catch {
318
- // Skip on error
319
- }
320
- }
321
- // Generic agent config files in current directory
322
- locations.push({ label: "./AGENTS.md", path: join(cwd, "AGENTS.md") });
323
- locations.push({ label: "./CLAUDE.md", path: join(cwd, "CLAUDE.md") });
324
- return locations;
325
- }
326
- function formatFileSize(bytes) {
327
- if (bytes < 1024)
328
- return `${bytes} B`;
329
- return `${(bytes / 1024).toFixed(1)} KB`;
330
- }
331
- async function syncAgentMemory() {
332
- console.log(chalk.blue("Scanning for agent memory files..."));
333
- console.log();
334
- const locations = discoverAgentMemoryFiles();
335
- const found = [];
336
- const notFound = [];
337
- for (const loc of locations) {
338
- if (existsSync(loc.path)) {
339
- try {
340
- const stat = statSync(loc.path);
341
- if (stat.isFile() && stat.size > 0) {
342
- found.push({ label: loc.label, path: loc.path, size: stat.size });
343
- }
344
- else {
345
- notFound.push(loc.label);
346
- }
347
- }
348
- catch {
349
- notFound.push(loc.label);
350
- }
351
- }
352
- else {
353
- notFound.push(loc.label);
354
- }
355
- }
356
- if (found.length === 0) {
357
- console.log(chalk.yellow("No agent memory files found."));
358
- return;
359
- }
360
- console.log("Found:");
361
- for (const f of found) {
362
- console.log(chalk.green(" \u2713"), f.label, chalk.gray(`(${formatFileSize(f.size)})`));
363
- }
364
- for (const label of notFound) {
365
- console.log(chalk.gray(" \u2717"), chalk.gray(label), chalk.gray("(not found)"));
366
- }
367
- console.log();
368
- let synced = 0;
369
- let unchanged = 0;
370
- let errors = 0;
371
- for (const f of found) {
372
- try {
373
- const content = readFileSync(f.path, "utf-8");
374
- if (!content.trim())
375
- continue;
376
- const title = basename(f.path);
377
- await apiPost("/v1/notes", {
378
- content,
379
- title,
380
- source: "sync",
381
- source_path: f.path,
382
- content_type: "markdown",
383
- category: "",
384
- });
385
- synced++;
386
- }
387
- catch (err) {
388
- const msg = err.message;
389
- if (msg.includes("unchanged") ||
390
- msg.includes("duplicate") ||
391
- msg.includes("exists")) {
392
- unchanged++;
393
- }
394
- else {
395
- errors++;
396
- console.log(chalk.red(" Error syncing"), f.label, chalk.gray(msg));
397
- }
398
- }
399
- }
400
- console.log(chalk.blue(`Synced ${found.length} files to Memax`), chalk.gray(`(${synced} new, ${unchanged} unchanged${errors > 0 ? `, ${errors} errors` : ""})`));
401
- }
402
- function confirmSync() {
403
- return new Promise((resolve) => {
404
- const rl = createInterface({
405
- input: process.stdin,
406
- output: process.stdout,
407
- });
408
- rl.question(" ", (answer) => {
409
- rl.close();
410
- resolve(answer.trim().toLowerCase() === "y");
411
- });
412
- });
413
- }
414
- //# sourceMappingURL=sync.js.map