memax-cli 0.1.0-alpha.5 → 0.1.0-alpha.50
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/assets/skills/memax-memory/SKILL.md +173 -0
- package/dist/commands/agent-sessions.d.ts +62 -0
- package/dist/commands/agent-sessions.d.ts.map +1 -0
- package/dist/commands/agent-sessions.js +1447 -0
- package/dist/commands/agent-sessions.js.map +1 -0
- package/dist/commands/agent-sessions.test.d.ts +2 -0
- package/dist/commands/agent-sessions.test.d.ts.map +1 -0
- package/dist/commands/agent-sessions.test.js +255 -0
- package/dist/commands/agent-sessions.test.js.map +1 -0
- package/dist/commands/agents.d.ts +3 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +36 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/ask.d.ts +15 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +483 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +99 -8
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/capture.d.ts +19 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +69 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +13 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/delete.d.ts +3 -1
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +30 -5
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/dreams.d.ts +22 -0
- package/dist/commands/dreams.d.ts.map +1 -0
- package/dist/commands/dreams.js +235 -0
- package/dist/commands/dreams.js.map +1 -0
- package/dist/commands/dreams.test.d.ts +2 -0
- package/dist/commands/dreams.test.d.ts.map +1 -0
- package/dist/commands/dreams.test.js +39 -0
- package/dist/commands/dreams.test.js.map +1 -0
- package/dist/commands/hook.d.ts +2 -0
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +25 -103
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/hub.d.ts +37 -0
- package/dist/commands/hub.d.ts.map +1 -0
- package/dist/commands/hub.js +347 -0
- package/dist/commands/hub.js.map +1 -0
- package/dist/commands/hub.test.d.ts +2 -0
- package/dist/commands/hub.test.d.ts.map +1 -0
- package/dist/commands/hub.test.js +62 -0
- package/dist/commands/hub.test.js.map +1 -0
- package/dist/commands/list.d.ts +9 -2
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +118 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/list.test.d.ts +2 -0
- package/dist/commands/list.test.d.ts.map +1 -0
- package/dist/commands/list.test.js +20 -0
- package/dist/commands/list.test.js.map +1 -0
- package/dist/commands/login.d.ts +7 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +85 -22
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +427 -60
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/push.d.ts +7 -2
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +80 -12
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/recall.d.ts +11 -1
- package/dist/commands/recall.d.ts.map +1 -1
- package/dist/commands/recall.js +228 -41
- 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 +31 -0
- package/dist/commands/recall.test.js.map +1 -0
- package/dist/commands/setup-hooks.d.ts +13 -0
- package/dist/commands/setup-hooks.d.ts.map +1 -0
- package/dist/commands/setup-hooks.js +193 -0
- package/dist/commands/setup-hooks.js.map +1 -0
- package/dist/commands/setup-instructions.d.ts +21 -0
- package/dist/commands/setup-instructions.d.ts.map +1 -0
- package/dist/commands/setup-instructions.js +172 -0
- package/dist/commands/setup-instructions.js.map +1 -0
- package/dist/commands/setup-mcp.d.ts +40 -0
- package/dist/commands/setup-mcp.d.ts.map +1 -0
- package/dist/commands/setup-mcp.js +414 -0
- package/dist/commands/setup-mcp.js.map +1 -0
- package/dist/commands/setup-types.d.ts +33 -0
- package/dist/commands/setup-types.d.ts.map +1 -0
- package/dist/commands/setup-types.js +60 -0
- package/dist/commands/setup-types.js.map +1 -0
- package/dist/commands/setup.d.ts +13 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +289 -313
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/show.d.ts +5 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +36 -14
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/sync.d.ts +47 -3
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +1351 -135
- 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/commands/topic.d.ts +32 -0
- package/dist/commands/topic.d.ts.map +1 -0
- package/dist/commands/topic.js +265 -0
- package/dist/commands/topic.js.map +1 -0
- package/dist/commands/topic.test.d.ts +2 -0
- package/dist/commands/topic.test.d.ts.map +1 -0
- package/dist/commands/topic.test.js +114 -0
- package/dist/commands/topic.test.js.map +1 -0
- package/dist/index.js +35 -125
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +10 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +104 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/client.test.d.ts +2 -0
- package/dist/lib/client.test.d.ts.map +1 -0
- package/dist/lib/client.test.js +44 -0
- package/dist/lib/client.test.js.map +1 -0
- package/dist/lib/config.d.ts +43 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +72 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/credentials.d.ts +3 -0
- package/dist/lib/credentials.d.ts.map +1 -1
- package/dist/lib/credentials.js +24 -2
- package/dist/lib/credentials.js.map +1 -1
- package/dist/lib/hubs.d.ts +7 -0
- package/dist/lib/hubs.d.ts.map +1 -0
- package/dist/lib/hubs.js +33 -0
- package/dist/lib/hubs.js.map +1 -0
- package/dist/lib/hubs.test.d.ts +2 -0
- package/dist/lib/hubs.test.d.ts.map +1 -0
- package/dist/lib/hubs.test.js +58 -0
- package/dist/lib/hubs.test.js.map +1 -0
- package/dist/lib/project-context.d.ts +56 -0
- package/dist/lib/project-context.d.ts.map +1 -0
- package/dist/lib/project-context.js +225 -0
- package/dist/lib/project-context.js.map +1 -0
- 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/dist/lib/prompt.d.ts +7 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +41 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/trash.d.ts +6 -0
- package/dist/lib/trash.d.ts.map +1 -0
- package/dist/lib/trash.js +28 -0
- package/dist/lib/trash.js.map +1 -0
- package/package.json +17 -13
- package/.vscode/mcp.json +0 -8
- package/dist/lib/api.d.ts +0 -4
- package/dist/lib/api.d.ts.map +0 -1
- package/dist/lib/api.js +0 -95
- package/dist/lib/api.js.map +0 -1
- package/src/commands/auth.ts +0 -92
- package/src/commands/config.ts +0 -27
- package/src/commands/delete.ts +0 -20
- package/src/commands/hook.ts +0 -243
- package/src/commands/list.ts +0 -38
- package/src/commands/login.ts +0 -162
- package/src/commands/mcp.ts +0 -357
- package/src/commands/push.ts +0 -82
- package/src/commands/recall.ts +0 -163
- package/src/commands/setup.ts +0 -682
- package/src/commands/show.ts +0 -35
- package/src/commands/sync.ts +0 -403
- package/src/index.ts +0 -192
- package/src/lib/api.ts +0 -110
- package/src/lib/config.ts +0 -61
- package/src/lib/credentials.ts +0 -42
- package/tsconfig.json +0 -9
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { deriveInviteURL, extractInviteToken, inviteDisplayID, resolveInviteReference, } from "./hub.js";
|
|
3
|
+
describe("inviteDisplayID", () => {
|
|
4
|
+
it("shortens invite IDs by default", () => {
|
|
5
|
+
expect(inviteDisplayID("12345678-1234-1234-1234-123456789abc")).toBe("12345678");
|
|
6
|
+
});
|
|
7
|
+
it("shows full invite IDs in verbose mode", () => {
|
|
8
|
+
expect(inviteDisplayID("12345678-1234-1234-1234-123456789abc", true)).toBe("12345678-1234-1234-1234-123456789abc");
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
describe("deriveInviteURL", () => {
|
|
12
|
+
it("maps localhost API to local web app", () => {
|
|
13
|
+
expect(deriveInviteURL("tok", "http://localhost:8080")).toBe("http://localhost:3000/invite/tok");
|
|
14
|
+
});
|
|
15
|
+
it("strips api prefix for production", () => {
|
|
16
|
+
expect(deriveInviteURL("tok", "https://api.memax.app")).toBe("https://memax.app/invite/tok");
|
|
17
|
+
});
|
|
18
|
+
it("maps staging-api to staging-app", () => {
|
|
19
|
+
expect(deriveInviteURL("tok", "https://staging-api.memaxlabs.com")).toBe("https://staging-app.memaxlabs.com/invite/tok");
|
|
20
|
+
});
|
|
21
|
+
it("maps api- prefix to app- prefix", () => {
|
|
22
|
+
expect(deriveInviteURL("tok", "https://api-staging.memaxlabs.com")).toBe("https://app-staging.memaxlabs.com/invite/tok");
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("extractInviteToken", () => {
|
|
26
|
+
it("returns raw token unchanged", () => {
|
|
27
|
+
expect(extractInviteToken("abc123")).toBe("abc123");
|
|
28
|
+
});
|
|
29
|
+
it("extracts token from invite URL", () => {
|
|
30
|
+
expect(extractInviteToken("https://memax.app/invite/abc123")).toBe("abc123");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("resolveInviteReference", () => {
|
|
34
|
+
const invites = [
|
|
35
|
+
{
|
|
36
|
+
id: "12345678-1234-1234-1234-123456789abc",
|
|
37
|
+
hub_id: "h1",
|
|
38
|
+
token: "tok1",
|
|
39
|
+
invited_by: "u1",
|
|
40
|
+
role: "contributor",
|
|
41
|
+
expires_at: "",
|
|
42
|
+
created_at: "",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "abcdef12-1234-1234-1234-123456789abc",
|
|
46
|
+
hub_id: "h1",
|
|
47
|
+
token: "tok2",
|
|
48
|
+
invited_by: "u1",
|
|
49
|
+
role: "viewer",
|
|
50
|
+
expires_at: "",
|
|
51
|
+
created_at: "",
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
it("resolves exact invite IDs", () => {
|
|
55
|
+
expect(resolveInviteReference(invites, "12345678-1234-1234-1234-123456789abc")
|
|
56
|
+
.id).toBe("12345678-1234-1234-1234-123456789abc");
|
|
57
|
+
});
|
|
58
|
+
it("resolves unique invite ID prefixes", () => {
|
|
59
|
+
expect(resolveInviteReference(invites, "abcdef12").id).toBe("abcdef12-1234-1234-1234-123456789abc");
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=hub.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.test.js","sourceRoot":"","sources":["../../src/commands/hub.test.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/list.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
1
2
|
interface ListOptions {
|
|
2
|
-
|
|
3
|
-
state?: string;
|
|
3
|
+
sort?: string;
|
|
4
4
|
limit?: string;
|
|
5
|
+
all?: boolean;
|
|
6
|
+
hub?: string;
|
|
7
|
+
cursor?: string;
|
|
8
|
+
format?: string;
|
|
9
|
+
topicId?: string;
|
|
5
10
|
}
|
|
11
|
+
export declare function buildNextPageCommand(options: ListOptions, nextCursor: string): string;
|
|
6
12
|
export declare function listCommand(options: ListOptions): Promise<void>;
|
|
13
|
+
export declare function registerListCommand(program: Command): void;
|
|
7
14
|
export {};
|
|
8
15
|
//# sourceMappingURL=list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,CAUR;AAiCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FrE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAY1D"}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,18 +1,114 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
3
|
+
import { getActiveHubID } from "../lib/config.js";
|
|
4
|
+
import { resolveHubID } from "../lib/hubs.js";
|
|
5
|
+
import { buildTopicPathMap, resolveTopicReference } from "./topic.js";
|
|
6
|
+
function parseLimit(raw) {
|
|
7
|
+
if (!raw)
|
|
8
|
+
return 20;
|
|
9
|
+
const limit = Number.parseInt(raw, 10);
|
|
10
|
+
if (!Number.isFinite(limit) || limit <= 0) {
|
|
11
|
+
throw new Error(`Invalid --limit value: ${raw}`);
|
|
12
|
+
}
|
|
13
|
+
return limit;
|
|
14
|
+
}
|
|
15
|
+
export function buildNextPageCommand(options, nextCursor) {
|
|
16
|
+
const parts = ["memax", "list"];
|
|
17
|
+
if (options.sort && options.sort !== "newest")
|
|
18
|
+
parts.push("--sort", options.sort);
|
|
19
|
+
if (options.limit && options.limit !== "20")
|
|
20
|
+
parts.push("--limit", options.limit);
|
|
21
|
+
if (options.hub)
|
|
22
|
+
parts.push("--hub", options.hub);
|
|
23
|
+
if (options.topicId)
|
|
24
|
+
parts.push("--topic-id", options.topicId);
|
|
25
|
+
parts.push("--cursor", `'${nextCursor}'`);
|
|
26
|
+
return parts.join(" ");
|
|
27
|
+
}
|
|
28
|
+
function printTextList(memories, total, topicPaths) {
|
|
29
|
+
console.log(chalk.blue(`${memories.length} memor${memories.length > 1 ? "ies" : "y"}`), chalk.gray(`(${total} total)`));
|
|
30
|
+
console.log();
|
|
31
|
+
for (const memory of memories) {
|
|
32
|
+
console.log(chalk.bold(memory.title), chalk.gray(`[${memory.kind} · ${memory.stability}]`), chalk.gray(`· ${memory.source}`));
|
|
33
|
+
const topicPath = memory.topic_id
|
|
34
|
+
? topicPaths.get(memory.topic_id)
|
|
35
|
+
: undefined;
|
|
36
|
+
if (topicPath) {
|
|
37
|
+
console.log(chalk.gray(` topic: ${topicPath}`));
|
|
38
|
+
}
|
|
39
|
+
console.log(chalk.gray(` id: ${memory.id}`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function printJSON(result) {
|
|
43
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
44
|
+
}
|
|
3
45
|
export async function listCommand(options) {
|
|
4
46
|
try {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
47
|
+
const limit = parseLimit(options.limit);
|
|
48
|
+
const sort = (options.sort ?? "newest");
|
|
49
|
+
const format = options.format ?? "text";
|
|
50
|
+
if (format !== "text" && format !== "json") {
|
|
51
|
+
throw new Error(`Unsupported --format value: ${format}`);
|
|
52
|
+
}
|
|
53
|
+
const hubId = options.hub
|
|
54
|
+
? await resolveHubID(options.hub)
|
|
55
|
+
: getActiveHubID() || undefined;
|
|
56
|
+
if (options.hub && !hubId) {
|
|
57
|
+
throw new Error("Hub not found or not accessible. Run `memax hub list` to see available hubs.");
|
|
58
|
+
}
|
|
59
|
+
const client = getClient();
|
|
60
|
+
let topicId = options.topicId;
|
|
61
|
+
if (topicId) {
|
|
62
|
+
if (!hubId) {
|
|
63
|
+
throw new Error("Topic lookup requires a hub. Set an active hub or pass --hub.");
|
|
64
|
+
}
|
|
65
|
+
const topics = await client.topics.list(hubId);
|
|
66
|
+
topicId = resolveTopicReference(topics.topics, topicId);
|
|
67
|
+
}
|
|
68
|
+
const memories = [];
|
|
69
|
+
let cursor = options.cursor ?? "";
|
|
70
|
+
let nextCursor = "";
|
|
71
|
+
let total = 0;
|
|
72
|
+
do {
|
|
73
|
+
const res = await client.memories.list({
|
|
74
|
+
limit,
|
|
75
|
+
sort,
|
|
76
|
+
cursor: cursor || undefined,
|
|
77
|
+
hubId,
|
|
78
|
+
topicId,
|
|
79
|
+
});
|
|
80
|
+
memories.push(...(res.memories ?? []));
|
|
81
|
+
nextCursor = res.next_cursor;
|
|
82
|
+
total = res.total;
|
|
83
|
+
cursor = nextCursor;
|
|
84
|
+
if (!options.all)
|
|
85
|
+
break;
|
|
86
|
+
} while (cursor);
|
|
87
|
+
const result = {
|
|
88
|
+
memories,
|
|
89
|
+
next_cursor: options.all ? "" : nextCursor,
|
|
90
|
+
has_more: options.all ? false : nextCursor !== "",
|
|
91
|
+
total,
|
|
92
|
+
};
|
|
93
|
+
const topicPaths = hubId && memories.some((memory) => !!memory.topic_id)
|
|
94
|
+
? buildTopicPathMap((await client.topics.list(hubId)).topics)
|
|
95
|
+
: new Map();
|
|
96
|
+
if (format === "json") {
|
|
97
|
+
printJSON(result);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (memories.length === 0) {
|
|
101
|
+
console.log(chalk.yellow("No memories yet. Push your first one:"));
|
|
8
102
|
console.log(chalk.gray(" memax push --file ./README.md"));
|
|
9
103
|
return;
|
|
10
104
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
console.log(chalk.
|
|
15
|
-
console.log(chalk.gray(`
|
|
105
|
+
printTextList(memories, total, topicPaths);
|
|
106
|
+
if (result.has_more) {
|
|
107
|
+
console.log();
|
|
108
|
+
console.log(chalk.gray(` Showing ${memories.length} of ${total}.`));
|
|
109
|
+
console.log(chalk.gray(` Next cursor: ${result.next_cursor}`));
|
|
110
|
+
console.log(chalk.gray(` Next page: ${buildNextPageCommand(options, result.next_cursor)}`));
|
|
111
|
+
console.log(chalk.gray(" Use --all to fetch every page."));
|
|
16
112
|
}
|
|
17
113
|
}
|
|
18
114
|
catch (err) {
|
|
@@ -20,4 +116,17 @@ export async function listCommand(options) {
|
|
|
20
116
|
process.exit(1);
|
|
21
117
|
}
|
|
22
118
|
}
|
|
119
|
+
export function registerListCommand(program) {
|
|
120
|
+
program
|
|
121
|
+
.command("list")
|
|
122
|
+
.description("List your memories")
|
|
123
|
+
.option("-s, --sort <sort>", "Sort by: newest, relevant", "newest")
|
|
124
|
+
.option("-l, --limit <n>", "Max results per page", "20")
|
|
125
|
+
.option("--cursor <cursor>", "Continue from a pagination cursor")
|
|
126
|
+
.option("--hub <slug>", "List memories from a specific hub only")
|
|
127
|
+
.option("--topic-id <id>", "Restrict results to memories in this topic")
|
|
128
|
+
.option("--format <format>", "Output format: text, json", "text")
|
|
129
|
+
.option("--all", "Fetch all pages (not just the first)")
|
|
130
|
+
.action(listCommand);
|
|
131
|
+
}
|
|
23
132
|
//# sourceMappingURL=list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.test.d.ts","sourceRoot":"","sources":["../../src/commands/list.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { buildNextPageCommand } from "./list.js";
|
|
3
|
+
describe("buildNextPageCommand", () => {
|
|
4
|
+
it("carries relevant options into the next-page command", () => {
|
|
5
|
+
const cmd = buildNextPageCommand({
|
|
6
|
+
sort: "relevant",
|
|
7
|
+
limit: "50",
|
|
8
|
+
hub: "team-hub",
|
|
9
|
+
}, "12|2026-04-08T10:00:00Z");
|
|
10
|
+
expect(cmd).toBe("memax list --sort relevant --limit 50 --hub team-hub --cursor '12|2026-04-08T10:00:00Z'");
|
|
11
|
+
});
|
|
12
|
+
it("preserves --topic-id across pages", () => {
|
|
13
|
+
const cmd = buildNextPageCommand({
|
|
14
|
+
hub: "team-hub",
|
|
15
|
+
topicId: "01H9X0ABCDEF",
|
|
16
|
+
}, "12|2026-04-08T10:00:00Z");
|
|
17
|
+
expect(cmd).toBe("memax list --hub team-hub --topic-id 01H9X0ABCDEF --cursor '12|2026-04-08T10:00:00Z'");
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=list.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.test.js","sourceRoot":"","sources":["../../src/commands/list.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,oBAAoB,CAC9B;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,IAAI;YACX,GAAG,EAAE,UAAU;SAChB,EACD,yBAAyB,CAC1B,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CACd,yFAAyF,CAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,GAAG,oBAAoB,CAC9B;YACE,GAAG,EAAE,UAAU;YACf,OAAO,EAAE,cAAc;SACxB,EACD,yBAAyB,CAC1B,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CACd,sFAAsF,CACvF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
interface LoginOptions {
|
|
3
|
+
provider?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function loginCommand(options?: LoginOptions): Promise<void>;
|
|
2
6
|
export declare function logoutCommand(): Promise<void>;
|
|
3
7
|
export declare function whoamiCommand(): Promise<void>;
|
|
8
|
+
export declare function registerLoginCommands(program: Command): void;
|
|
9
|
+
export {};
|
|
4
10
|
//# sourceMappingURL=login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkI5E;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAInD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAgDnD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiB5D"}
|
package/dist/commands/login.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { createServer } from "node:http";
|
|
2
|
-
import {
|
|
2
|
+
import { getActiveHubID, setActiveHubID } from "../lib/config.js";
|
|
3
|
+
import { getClient, getPublicClient, resetClient } from "../lib/client.js";
|
|
3
4
|
import { saveCredentials } from "../lib/credentials.js";
|
|
4
|
-
export async function loginCommand() {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
export async function loginCommand(options = {}) {
|
|
6
|
+
let provider;
|
|
7
|
+
try {
|
|
8
|
+
provider = normalizeProvider(options.provider);
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
console.error(` Login failed: ${err.message}\n`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
7
14
|
// Start a temporary local server to receive the OAuth callback
|
|
8
15
|
const port = await findFreePort();
|
|
9
16
|
const callbackUrl = `http://localhost:${port}/callback`;
|
|
@@ -15,13 +22,8 @@ export async function loginCommand() {
|
|
|
15
22
|
if (code) {
|
|
16
23
|
// Exchange the one-time code for tokens via POST
|
|
17
24
|
try {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
headers: { "Content-Type": "application/json" },
|
|
21
|
-
body: JSON.stringify({ code }),
|
|
22
|
-
});
|
|
23
|
-
const json = (await exchangeRes.json());
|
|
24
|
-
if (json.data) {
|
|
25
|
+
const tokens = await getPublicClient().auth.exchangeCode(code);
|
|
26
|
+
if (tokens.access_token) {
|
|
25
27
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
26
28
|
res.end(`
|
|
27
29
|
<html><body style="font-family: system-ui; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0;">
|
|
@@ -31,12 +33,12 @@ export async function loginCommand() {
|
|
|
31
33
|
</div>
|
|
32
34
|
</body></html>
|
|
33
35
|
`);
|
|
34
|
-
resolve(
|
|
36
|
+
resolve(tokens);
|
|
35
37
|
}
|
|
36
38
|
else {
|
|
37
39
|
res.writeHead(400, { "Content-Type": "text/html" });
|
|
38
|
-
res.end(
|
|
39
|
-
reject(new Error(
|
|
40
|
+
res.end("<html><body><h2>Login failed</h2><p>Token exchange failed.</p></body></html>");
|
|
41
|
+
reject(new Error("Token exchange failed."));
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
catch (err) {
|
|
@@ -58,15 +60,18 @@ export async function loginCommand() {
|
|
|
58
60
|
}
|
|
59
61
|
});
|
|
60
62
|
server.listen(port);
|
|
61
|
-
// Timeout after 2 minutes
|
|
62
|
-
setTimeout(() => {
|
|
63
|
+
// Timeout after 2 minutes — use unref() so it doesn't keep the process alive
|
|
64
|
+
const timeout = setTimeout(() => {
|
|
63
65
|
server.close();
|
|
66
|
+
server.closeAllConnections();
|
|
64
67
|
reject(new Error("Login timed out — no callback received within 2 minutes."));
|
|
65
68
|
}, 120_000);
|
|
69
|
+
timeout.unref();
|
|
66
70
|
});
|
|
67
|
-
// Build the
|
|
68
|
-
const authUrl =
|
|
69
|
-
|
|
71
|
+
// Build the OAuth URL with our local callback as the redirect
|
|
72
|
+
const authUrl = getPublicClient().auth.providerLoginURL(provider, callbackUrl);
|
|
73
|
+
const providerLabel = provider === "google" ? "Google" : "GitHub";
|
|
74
|
+
console.log(`\n Opening browser for ${providerLabel} login...\n`);
|
|
70
75
|
console.log(` If the browser doesn't open, visit:\n ${authUrl}\n`);
|
|
71
76
|
// Try to open the browser
|
|
72
77
|
try {
|
|
@@ -88,6 +93,18 @@ export async function loginCommand() {
|
|
|
88
93
|
refresh_token: tokens.refresh_token,
|
|
89
94
|
expires_at: Date.now() + tokens.expires_in * 1000,
|
|
90
95
|
});
|
|
96
|
+
resetClient();
|
|
97
|
+
// Auto-set personal hub so commands work without `memax hub switch`
|
|
98
|
+
try {
|
|
99
|
+
const hubs = await getClient().hubs.list();
|
|
100
|
+
const personal = hubs.find((h) => h.hub.hub_type === "personal");
|
|
101
|
+
if (personal) {
|
|
102
|
+
setActiveHubID(personal.hub.id);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Non-fatal — user can manually run `memax hub switch personal`
|
|
107
|
+
}
|
|
91
108
|
console.log(" Logged in successfully. Credentials saved to ~/.memax/credentials.json\n");
|
|
92
109
|
}
|
|
93
110
|
catch (err) {
|
|
@@ -102,20 +119,66 @@ export async function logoutCommand() {
|
|
|
102
119
|
}
|
|
103
120
|
export async function whoamiCommand() {
|
|
104
121
|
const { loadCredentials } = await import("../lib/credentials.js");
|
|
105
|
-
const {
|
|
122
|
+
const { getClient } = await import("../lib/client.js");
|
|
123
|
+
const chalk = (await import("chalk")).default;
|
|
106
124
|
const creds = loadCredentials();
|
|
107
125
|
if (!creds?.access_token) {
|
|
108
126
|
console.log(" Not logged in. Run: memax login\n");
|
|
109
127
|
return;
|
|
110
128
|
}
|
|
111
129
|
try {
|
|
112
|
-
const
|
|
113
|
-
|
|
130
|
+
const me = await getClient().auth.me();
|
|
131
|
+
const u = me.user;
|
|
132
|
+
console.log();
|
|
133
|
+
console.log(` ${chalk.bold(u.display_name || u.name)} ${chalk.dim(`(${u.email})`)}`);
|
|
134
|
+
console.log(` Plan: ${chalk.cyan(u.personal_plan_id || u.plan)}`);
|
|
135
|
+
// Active read hub (client-local)
|
|
136
|
+
const activeHubID = getActiveHubID();
|
|
137
|
+
if (me.hubs && me.hubs.length > 0 && activeHubID) {
|
|
138
|
+
const active = me.hubs.find((h) => h.hub.id === activeHubID);
|
|
139
|
+
if (active) {
|
|
140
|
+
const typeTag = active.hub.hub_type === "personal" ? "" : chalk.dim(" (team)");
|
|
141
|
+
console.log(` Read hub: ${active.hub.name}${typeTag}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Usage this period
|
|
145
|
+
if (me.usage &&
|
|
146
|
+
(me.usage.push_count > 0 ||
|
|
147
|
+
me.usage.recall_count > 0 ||
|
|
148
|
+
me.usage.ask_count > 0)) {
|
|
149
|
+
console.log(` Usage: ${me.usage.push_count} pushes, ${me.usage.recall_count} recalls, ${me.usage.ask_count} asks`);
|
|
150
|
+
}
|
|
151
|
+
console.log();
|
|
114
152
|
}
|
|
115
153
|
catch {
|
|
116
154
|
console.log(" Session expired or invalid. Run: memax login\n");
|
|
117
155
|
}
|
|
118
156
|
}
|
|
157
|
+
export function registerLoginCommands(program) {
|
|
158
|
+
program
|
|
159
|
+
.command("login")
|
|
160
|
+
.description("Log in to Memax")
|
|
161
|
+
.option("--provider <name>", "OAuth provider to use: github or google (default: github)")
|
|
162
|
+
.action(loginCommand);
|
|
163
|
+
program
|
|
164
|
+
.command("logout")
|
|
165
|
+
.description("Clear saved credentials")
|
|
166
|
+
.action(logoutCommand);
|
|
167
|
+
program
|
|
168
|
+
.command("whoami")
|
|
169
|
+
.description("Show current user")
|
|
170
|
+
.action(whoamiCommand);
|
|
171
|
+
}
|
|
172
|
+
function normalizeProvider(value) {
|
|
173
|
+
if (!value) {
|
|
174
|
+
return "github";
|
|
175
|
+
}
|
|
176
|
+
const normalized = value.trim().toLowerCase();
|
|
177
|
+
if (normalized === "github" || normalized === "google") {
|
|
178
|
+
return normalized;
|
|
179
|
+
}
|
|
180
|
+
throw new Error("Unsupported login provider. Use: github or google.");
|
|
181
|
+
}
|
|
119
182
|
async function findFreePort() {
|
|
120
183
|
return new Promise((resolve) => {
|
|
121
184
|
const server = createServer();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAytBpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUzD"}
|