memax-cli 0.1.0-alpha.2 → 0.1.0-alpha.21
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 +154 -0
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +14 -7
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/capture.d.ts +17 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +60 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/delete.d.ts +1 -1
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +22 -5
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/hub.d.ts +4 -0
- package/dist/commands/hub.d.ts.map +1 -0
- package/dist/commands/hub.js +53 -0
- package/dist/commands/hub.js.map +1 -0
- package/dist/commands/list.d.ts +2 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +35 -8
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +32 -7
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +226 -26
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/push.d.ts +2 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +49 -11
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/recall.d.ts +1 -0
- package/dist/commands/recall.d.ts.map +1 -1
- package/dist/commands/recall.js +30 -27
- package/dist/commands/recall.js.map +1 -1
- package/dist/commands/setup-hooks.d.ts +12 -0
- package/dist/commands/setup-hooks.d.ts.map +1 -0
- package/dist/commands/setup-hooks.js +184 -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 +14 -0
- package/dist/commands/setup-mcp.d.ts.map +1 -0
- package/dist/commands/setup-mcp.js +276 -0
- package/dist/commands/setup-mcp.js.map +1 -0
- package/dist/commands/setup-types.d.ts +20 -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 +18 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +371 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +10 -13
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/sync.d.ts +7 -2
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +614 -107
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.js +85 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +6 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +69 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/project-context.d.ts +40 -0
- package/dist/lib/project-context.d.ts.map +1 -0
- package/dist/lib/project-context.js +157 -0
- package/dist/lib/project-context.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/package.json +17 -13
- 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 -159
- package/src/commands/mcp.ts +0 -282
- package/src/commands/push.ts +0 -82
- package/src/commands/recall.ts +0 -160
- package/src/commands/show.ts +0 -35
- package/src/commands/sync.ts +0 -403
- package/src/index.ts +0 -167
- 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,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memax-memory
|
|
3
|
+
description: Persistent memory layer using Memax. Gives Claude the ability to recall past context and store new learnings across sessions via the Memax MCP tools (memax_recall, memax_push, memax_get, memax_search, memax_forget). Use this skill at the START of every conversation to do a light context check, and throughout the session whenever the user references past decisions, project context, architecture, or conventions — or whenever Claude discovers something worth remembering for future sessions. Also trigger when the user explicitly asks to remember or forget something, or when working on a project where prior context would prevent redundant questions. If Memax MCP tools are available, this skill applies.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Memax Memory — Persistent Context for Claude
|
|
7
|
+
|
|
8
|
+
You have access to **Memax**, a persistent cloud knowledge hub shared across all your AI agents. It survives between sessions — anything you push now is available in every future conversation.
|
|
9
|
+
|
|
10
|
+
Your job is to use it proactively. Don't wait for the user to say "check Memax" or "remember this." Treat it like your own long-term memory.
|
|
11
|
+
|
|
12
|
+
## Tools
|
|
13
|
+
|
|
14
|
+
| Tool | Purpose |
|
|
15
|
+
| --------------- | ----------------------------------------------------- |
|
|
16
|
+
| `memax_recall` | Semantic search — find memories relevant to a query |
|
|
17
|
+
| `memax_push` | Save a new memory |
|
|
18
|
+
| `memax_get` | Read the full content of a specific memory by ID |
|
|
19
|
+
| `memax_search` | Browse/list memories by category |
|
|
20
|
+
| `memax_forget` | Delete a memory by ID |
|
|
21
|
+
| `memax_capture` | Extract and save key decisions from a session summary |
|
|
22
|
+
|
|
23
|
+
## When to recall (read)
|
|
24
|
+
|
|
25
|
+
### Every session — light check
|
|
26
|
+
|
|
27
|
+
At the very start of a conversation, before diving into the user's request, do a quick `memax_recall` with a query derived from the user's first message. This takes a second and often saves minutes of redundant back-and-forth.
|
|
28
|
+
|
|
29
|
+
**Example:** User says "Let's work on the auth flow." → `memax_recall("auth flow")` before responding.
|
|
30
|
+
|
|
31
|
+
If the first message is generic (e.g. "hey" or "what's up"), skip the recall — there's nothing meaningful to search for yet. Resume checking once the conversation has a topic.
|
|
32
|
+
|
|
33
|
+
### On cues — deeper recall
|
|
34
|
+
|
|
35
|
+
Go deeper when you notice:
|
|
36
|
+
|
|
37
|
+
- References to past decisions: "the approach we agreed on," "like last time," "what did we decide about..."
|
|
38
|
+
- Project names, codenames, or domain-specific terms you don't have full context for
|
|
39
|
+
- Architecture or convention questions: "how do we handle X," "what's our pattern for Y"
|
|
40
|
+
- The user correcting you on something that suggests prior context exists
|
|
41
|
+
|
|
42
|
+
For deeper recall, chain multiple calls: `memax_recall` to find relevant memories, then `memax_get` on specific IDs to read full details, or `memax_search` to browse a category.
|
|
43
|
+
|
|
44
|
+
### Don't over-recall
|
|
45
|
+
|
|
46
|
+
One or two recall calls at session start is plenty for most conversations. Don't recall on every single message — that's noisy and slow. Use judgment: if you already have the context you need, just work.
|
|
47
|
+
|
|
48
|
+
## When to push (write)
|
|
49
|
+
|
|
50
|
+
Push memories **proactively during the conversation** whenever something important surfaces. Don't hoard insights until the end — if you discover something worth remembering, push it now. Sessions can end abruptly (browser closed, timeout, context limit), and anything not pushed is lost.
|
|
51
|
+
|
|
52
|
+
### What to push
|
|
53
|
+
|
|
54
|
+
Things that would save time or prevent mistakes in a future session:
|
|
55
|
+
|
|
56
|
+
- **Architecture decisions** — "We chose X over Y because Z"
|
|
57
|
+
- **API conventions** — naming patterns, error handling approaches, auth schemes
|
|
58
|
+
- **Debugging solutions** — especially non-obvious ones that took effort to find
|
|
59
|
+
- **Deployment processes** — steps, gotchas, environment-specific details
|
|
60
|
+
- **Team/project preferences** — coding style, tool choices, workflow preferences
|
|
61
|
+
- **Infrastructure details** — server setup, service configurations, access patterns
|
|
62
|
+
- **Key decisions with rationale** — not just what, but why
|
|
63
|
+
|
|
64
|
+
### What NOT to push
|
|
65
|
+
|
|
66
|
+
- Ephemeral task details ("fix the typo on line 42")
|
|
67
|
+
- File contents — they belong in git, not memory
|
|
68
|
+
- Obvious things that any Claude session would already know
|
|
69
|
+
- Verbatim code blocks — summarize the approach instead
|
|
70
|
+
- Anything the user explicitly says is temporary or experimental
|
|
71
|
+
|
|
72
|
+
### How to write good memories
|
|
73
|
+
|
|
74
|
+
Write memories as if explaining to a future Claude session that has zero context about the current conversation. Be specific and self-contained.
|
|
75
|
+
|
|
76
|
+
**Good:**
|
|
77
|
+
|
|
78
|
+
> Memax uses JWT auth with RS256 signing. Tokens are issued by the API gateway and verified by each microservice independently. We chose RS256 over HS256 so services don't need a shared secret. Decision made 2025-01.
|
|
79
|
+
|
|
80
|
+
**Bad:**
|
|
81
|
+
|
|
82
|
+
> We're using JWT now.
|
|
83
|
+
|
|
84
|
+
Include the _why_ behind decisions — rationale is the most valuable thing to remember because it prevents future sessions from relitigating settled questions.
|
|
85
|
+
|
|
86
|
+
### Push cadence
|
|
87
|
+
|
|
88
|
+
- Push as soon as something important is decided or discovered — don't batch
|
|
89
|
+
- If a conversation is heavy on decisions (e.g., architecture planning), you might push 3-5 memories
|
|
90
|
+
- For a routine task, zero pushes is fine — not every session produces lasting knowledge
|
|
91
|
+
- When in doubt, push it. A slightly redundant memory is better than a lost insight. Memax handles merging and deduplication on the server side, so don't worry about conflicts or overlap with existing memories.
|
|
92
|
+
|
|
93
|
+
## Handling outdated information
|
|
94
|
+
|
|
95
|
+
If you recall a memory that looks outdated or contradicts what you're learning in the current session, just push the new information as a fresh memory. Don't bother deleting the old one — Memax's cloud layer handles conflict resolution and merging automatically.
|
|
96
|
+
|
|
97
|
+
The exception: if the user explicitly asks you to delete something ("forget that we use Redis" or "remove the old deployment notes"), use `memax_forget` to honor the request.
|
|
98
|
+
|
|
99
|
+
## Categories
|
|
100
|
+
|
|
101
|
+
Memax organizes memories into categories. Use them when pushing to keep things browsable:
|
|
102
|
+
|
|
103
|
+
| Category | What goes here | Example |
|
|
104
|
+
| ----------- | ------------------------------------------------------ | -------------------------------------------- |
|
|
105
|
+
| `core` | Fundamental architecture, tech stack, core patterns | "API uses stdlib net/http, not Gin" |
|
|
106
|
+
| `process` | Workflows, deployment steps, development practices | "Deploy to Fly.io requires fly.toml rename" |
|
|
107
|
+
| `decisions` | Key choices with rationale (ADR-style) | "Chose River over BullMQ because..." |
|
|
108
|
+
| `reference` | Useful lookup info, configurations, external resources | "Neon connection pooling limit: 100" |
|
|
109
|
+
| `daily` | Working notes, debugging sessions, ephemeral context | "Auth timeout was caused by Neon cold start" |
|
|
110
|
+
| `personal` | User preferences, coding style, workflow habits | "User prefers terse responses, no summaries" |
|
|
111
|
+
|
|
112
|
+
When pushing, set the category if you know it. If unsure, omit it — the server auto-classifies via LLM.
|
|
113
|
+
|
|
114
|
+
When searching, `memax_recall` does semantic search across all categories, so you don't need to filter by category when reading — just when writing.
|
|
115
|
+
|
|
116
|
+
## Behavior across environments
|
|
117
|
+
|
|
118
|
+
This skill works in both **Claude Code** and **Claude.ai**. The tools and behaviors are identical. The only difference is conversational style:
|
|
119
|
+
|
|
120
|
+
- In **Claude Code**, you're likely deep in a coding task — recall silently and weave context into your responses without narrating that you checked memory.
|
|
121
|
+
- In **Claude.ai**, conversations are more exploratory — it's fine to briefly mention what you found ("I see from past context that you're using pgvector for embeddings — want me to build on that?").
|
|
122
|
+
|
|
123
|
+
In both cases, push memories inline without ceremony. No need to announce "I'm saving this to Memax" unless the user would benefit from knowing (e.g., they asked you to remember something and you're confirming).
|
|
124
|
+
|
|
125
|
+
## Project context
|
|
126
|
+
|
|
127
|
+
When the Memax MCP server is connected, memories you push are automatically tagged with the current project context (git repo, project name, branch). This means:
|
|
128
|
+
|
|
129
|
+
- Memories pushed from Project A rank higher when recalled from Project A
|
|
130
|
+
- Cross-project knowledge still surfaces, just lower in the ranking
|
|
131
|
+
- You don't need to manually tag project context — it's handled by the transport layer
|
|
132
|
+
|
|
133
|
+
This is especially useful when the user works across multiple repos with different conventions (e.g., different package managers, different auth patterns). Your memories from each repo are contextually prioritized.
|
|
134
|
+
|
|
135
|
+
## At session end
|
|
136
|
+
|
|
137
|
+
If the conversation is ending (user says goodbye, context is running low, or the task is wrapping up) and you learned something significant during the session, push it before the session closes. Key candidates:
|
|
138
|
+
|
|
139
|
+
- Decisions made during this session
|
|
140
|
+
- Bugs found and their root causes
|
|
141
|
+
- Architectural changes or new patterns introduced
|
|
142
|
+
- User preferences you discovered (response style, tool choices, workflow)
|
|
143
|
+
|
|
144
|
+
Don't push a "session summary" — push the individual insights that would be useful standalone.
|
|
145
|
+
|
|
146
|
+
## Quick reference
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
Session start → memax_recall(topic from first message)
|
|
150
|
+
Cue detected → memax_recall(specific query) → memax_get(id) if needed
|
|
151
|
+
Important info → memax_push(clear, self-contained summary with rationale)
|
|
152
|
+
User says forget → memax_forget(id)
|
|
153
|
+
Outdated memory → Just push the new version, Memax handles merging
|
|
154
|
+
```
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAGA,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAiCrD;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhE"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
2
3
|
export async function createKeyCommand(name, opts) {
|
|
3
4
|
const expiresInDays = opts.expires ? parseInt(opts.expires, 10) : 0;
|
|
4
5
|
try {
|
|
5
|
-
const result = await
|
|
6
|
+
const result = await getClient().auth.createKey({
|
|
6
7
|
name,
|
|
7
|
-
|
|
8
|
+
hubId: opts.hub || undefined,
|
|
9
|
+
expiresInDays: expiresInDays || undefined,
|
|
8
10
|
});
|
|
9
11
|
console.log("\n API key created successfully.\n");
|
|
10
12
|
console.log(` Name: ${result.name}`);
|
|
11
13
|
console.log(` Key: ${result.key}`);
|
|
14
|
+
console.log(` Scope: ${result.hub_id ? chalk.cyan(result.scope) : chalk.dim("all hubs")}`);
|
|
12
15
|
if (result.expires_at) {
|
|
13
16
|
console.log(` Expires: ${new Date(result.expires_at).toLocaleDateString()}`);
|
|
14
17
|
}
|
|
15
18
|
else {
|
|
16
19
|
console.log(` Expires: never`);
|
|
17
20
|
}
|
|
18
|
-
console.log(
|
|
21
|
+
console.log(`\n ${chalk.yellow("Save this key now — it cannot be retrieved again.")}\n`);
|
|
19
22
|
console.log(" Usage:");
|
|
20
23
|
console.log(` export MEMAX_API_KEY=${result.key}\n`);
|
|
21
24
|
}
|
|
@@ -26,7 +29,7 @@ export async function createKeyCommand(name, opts) {
|
|
|
26
29
|
}
|
|
27
30
|
export async function listKeysCommand() {
|
|
28
31
|
try {
|
|
29
|
-
const keys = await
|
|
32
|
+
const keys = await getClient().auth.listKeys();
|
|
30
33
|
if (keys.length === 0) {
|
|
31
34
|
console.log("\n No API keys. Create one with: memax auth create-key <name>\n");
|
|
32
35
|
return;
|
|
@@ -39,7 +42,11 @@ export async function listKeysCommand() {
|
|
|
39
42
|
const lastUsed = key.last_used
|
|
40
43
|
? new Date(key.last_used).toLocaleDateString()
|
|
41
44
|
: "never";
|
|
42
|
-
|
|
45
|
+
const scope = key.hub_id
|
|
46
|
+
? chalk.cyan(`hub:${key.scope}`)
|
|
47
|
+
: chalk.dim("all hubs");
|
|
48
|
+
const agent = key.agent_name ? chalk.magenta(` [${key.agent_name}]`) : "";
|
|
49
|
+
console.log(` ${key.prefix}... ${key.name} ${scope}${agent}`);
|
|
43
50
|
console.log(` ID: ${key.id} Expires: ${expires} Last used: ${lastUsed}`);
|
|
44
51
|
}
|
|
45
52
|
console.log();
|
|
@@ -51,7 +58,7 @@ export async function listKeysCommand() {
|
|
|
51
58
|
}
|
|
52
59
|
export async function revokeKeyCommand(id) {
|
|
53
60
|
try {
|
|
54
|
-
await
|
|
61
|
+
await getClient().auth.revokeKey(id);
|
|
55
62
|
console.log("\n API key revoked.\n");
|
|
56
63
|
}
|
|
57
64
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface CaptureOptions {
|
|
2
|
+
summary?: string;
|
|
3
|
+
agent?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* capture-session reads a session transcript from stdin and pushes it
|
|
7
|
+
* to Memax for fact extraction. The extraction pipeline (Claude Haiku)
|
|
8
|
+
* pulls out key decisions, learnings, and context — each becomes a
|
|
9
|
+
* separate searchable memory.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* memax capture-session --agent claude-code (reads stdin)
|
|
13
|
+
* memax capture-session --summary "Implemented auth system with JWT"
|
|
14
|
+
*/
|
|
15
|
+
export declare function captureSessionCommand(options: CaptureOptions): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CA4Df"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
3
|
+
/**
|
|
4
|
+
* capture-session reads a session transcript from stdin and pushes it
|
|
5
|
+
* to Memax for fact extraction. The extraction pipeline (Claude Haiku)
|
|
6
|
+
* pulls out key decisions, learnings, and context — each becomes a
|
|
7
|
+
* separate searchable memory.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* memax capture-session --agent claude-code (reads stdin)
|
|
11
|
+
* memax capture-session --summary "Implemented auth system with JWT"
|
|
12
|
+
*/
|
|
13
|
+
export async function captureSessionCommand(options) {
|
|
14
|
+
let content = "";
|
|
15
|
+
// Read from stdin if available
|
|
16
|
+
if (!process.stdin.isTTY) {
|
|
17
|
+
const chunks = [];
|
|
18
|
+
for await (const chunk of process.stdin) {
|
|
19
|
+
chunks.push(chunk);
|
|
20
|
+
}
|
|
21
|
+
content = Buffer.concat(chunks).toString("utf-8").trim();
|
|
22
|
+
}
|
|
23
|
+
// If --summary provided, use that as the content (or append to stdin)
|
|
24
|
+
if (options.summary) {
|
|
25
|
+
if (content) {
|
|
26
|
+
content = `## Session Summary\n${options.summary}\n\n## Session Transcript\n${content}`;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
content = options.summary;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!content) {
|
|
33
|
+
console.error(chalk.red("No session data. Pipe transcript via stdin or use --summary:\n" +
|
|
34
|
+
" memax capture-session --summary 'Implemented JWT auth'\n" +
|
|
35
|
+
" cat transcript.md | memax capture-session --agent claude-code"));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Truncate very long transcripts (keep first + last sections)
|
|
39
|
+
if (content.length > 20000) {
|
|
40
|
+
const head = content.slice(0, 10000);
|
|
41
|
+
const tail = content.slice(-5000);
|
|
42
|
+
content = head + "\n\n[...transcript truncated...]\n\n" + tail;
|
|
43
|
+
}
|
|
44
|
+
const agent = options.agent ?? "unknown";
|
|
45
|
+
try {
|
|
46
|
+
const memory = await getClient().push(content, {
|
|
47
|
+
title: `Session capture (${agent}) — ${new Date().toLocaleDateString()}`,
|
|
48
|
+
contentType: "transcript",
|
|
49
|
+
source: `auto-capture/${agent}`,
|
|
50
|
+
category: "chat/agent",
|
|
51
|
+
});
|
|
52
|
+
console.log(chalk.green(" Session captured."), chalk.gray(`Facts will be extracted in the background.`));
|
|
53
|
+
console.log(chalk.gray(` id: ${memory.id} category: ${memory.category}\n`));
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
console.error(chalk.red(` Capture failed: ${err.message}\n`));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/commands/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAO7C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAuB;IAEvB,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,+BAA+B;IAC/B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,sEAAsE;IACtE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,uBAAuB,OAAO,CAAC,OAAO,8BAA8B,OAAO,EAAE,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,gEAAgE;YAC9D,4DAA4D;YAC5D,iEAAiE,CACpE,CACF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,8DAA8D;IAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,GAAG,IAAI,GAAG,sCAAsC,GAAG,IAAI,CAAC;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YAC7C,KAAK,EAAE,oBAAoB,KAAK,OAAO,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE;YACxE,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,gBAAgB,KAAK,EAAE;YAC/B,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAClC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CACzD,CAAC;QACF,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,EAAE,eAAe,MAAM,CAAC,QAAQ,IAAI,CAAC,CACjE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAsB,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CAiCf"}
|
package/dist/commands/delete.js
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
3
|
+
import { confirm } from "../lib/prompt.js";
|
|
3
4
|
export async function deleteCommand(id, options) {
|
|
4
5
|
if (!id) {
|
|
5
|
-
console.error(chalk.red("Provide a
|
|
6
|
+
console.error(chalk.red("Provide a memory ID: memax forget <id>"));
|
|
6
7
|
process.exit(1);
|
|
7
8
|
}
|
|
9
|
+
const client = getClient();
|
|
10
|
+
// Show what's being deleted and confirm
|
|
11
|
+
if (!options.yes) {
|
|
12
|
+
try {
|
|
13
|
+
const memory = await client.memories.get(id);
|
|
14
|
+
console.log(chalk.yellow(`\n Delete "${memory.title}" [${memory.category}]?\n`));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
console.log(chalk.yellow(`\n Delete memory ${id}?\n`));
|
|
18
|
+
}
|
|
19
|
+
const confirmed = await confirm(" Type y to confirm: ");
|
|
20
|
+
if (!confirmed) {
|
|
21
|
+
console.log(chalk.gray(" Cancelled.\n"));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
8
25
|
try {
|
|
9
|
-
await
|
|
10
|
-
console.log(chalk.green("
|
|
26
|
+
await client.memories.delete(id);
|
|
27
|
+
console.log(chalk.green(" Forgotten."), chalk.gray(id + "\n"));
|
|
11
28
|
}
|
|
12
29
|
catch (err) {
|
|
13
|
-
console.error(chalk.red(`Delete failed: ${err.message}`));
|
|
30
|
+
console.error(chalk.red(` Delete failed: ${err.message}\n`));
|
|
14
31
|
process.exit(1);
|
|
15
32
|
}
|
|
16
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAU,EACV,OAA0B;IAE1B,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,wCAAwC;IACxC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,eAAe,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,QAAQ,MAAM,CAAC,CACrE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAqB,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../src/commands/hub.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAgCpD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlE;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
3
|
+
export async function hubListCommand() {
|
|
4
|
+
try {
|
|
5
|
+
const client = getClient();
|
|
6
|
+
const hubs = await client.hubs.list();
|
|
7
|
+
if (!hubs || hubs.length === 0) {
|
|
8
|
+
console.log(chalk.dim(" No hubs found. Run: memax hub create <name>"));
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// Get active hub ID
|
|
12
|
+
const settings = await client.settings.get();
|
|
13
|
+
const activeHubID = settings?.active_hub_id || "";
|
|
14
|
+
console.log();
|
|
15
|
+
for (const { hub, role } of hubs) {
|
|
16
|
+
const isActive = hub.id === activeHubID;
|
|
17
|
+
const marker = isActive ? chalk.green("● ") : " ";
|
|
18
|
+
const typeTag = hub.hub_type === "personal"
|
|
19
|
+
? chalk.dim("(personal)")
|
|
20
|
+
: chalk.cyan("(team)");
|
|
21
|
+
const roleTag = chalk.dim(`[${role}]`);
|
|
22
|
+
console.log(`${marker}${chalk.bold(hub.name)} ${typeTag} ${roleTag} ${chalk.dim(hub.id)}`);
|
|
23
|
+
}
|
|
24
|
+
console.log();
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
console.error(chalk.red(err.message || "Failed to list hubs"));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function hubCreateCommand(name) {
|
|
32
|
+
try {
|
|
33
|
+
const hub = await getClient().hubs.create(name);
|
|
34
|
+
console.log(chalk.green(`\n Created hub: ${hub.name} (${hub.slug})\n`));
|
|
35
|
+
console.log(chalk.dim(` ID: ${hub.id}`));
|
|
36
|
+
console.log(chalk.dim(` Switch to it: memax hub switch ${hub.id}\n`));
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error(chalk.red(err.message || "Failed to create hub"));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function hubSwitchCommand(idOrSlug) {
|
|
44
|
+
try {
|
|
45
|
+
const result = await getClient().hubs.switch(idOrSlug);
|
|
46
|
+
console.log(chalk.green(`\n Switched to: ${result.hub?.name || idOrSlug}\n`));
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error(chalk.red(err.message || "Failed to switch hub"));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/commands/hub.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/list.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmErE"}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { getClient } from "../lib/client.js";
|
|
3
3
|
export async function listCommand(options) {
|
|
4
4
|
try {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
6
|
+
const sort = (options.sort ?? "newest");
|
|
7
|
+
const client = getClient();
|
|
8
|
+
let allMemories = [];
|
|
9
|
+
let cursor = "";
|
|
10
|
+
let total = 0;
|
|
11
|
+
// Fetch pages
|
|
12
|
+
do {
|
|
13
|
+
const res = await client.memories.list({
|
|
14
|
+
limit,
|
|
15
|
+
sort,
|
|
16
|
+
cursor: cursor || undefined,
|
|
17
|
+
});
|
|
18
|
+
allMemories.push(...(res.memories ?? []));
|
|
19
|
+
cursor = res.next_cursor;
|
|
20
|
+
total = res.total;
|
|
21
|
+
// If not --all, just show first page
|
|
22
|
+
if (!options.all)
|
|
23
|
+
break;
|
|
24
|
+
} while (cursor);
|
|
25
|
+
// Filter by category if specified
|
|
26
|
+
let memories = allMemories;
|
|
27
|
+
if (options.category) {
|
|
28
|
+
memories = memories.filter((m) => m.category.toLowerCase().startsWith(options.category.toLowerCase()));
|
|
29
|
+
}
|
|
30
|
+
if (memories.length === 0) {
|
|
31
|
+
console.log(chalk.yellow("No memories yet. Push your first one:"));
|
|
8
32
|
console.log(chalk.gray(" memax push --file ./README.md"));
|
|
9
33
|
return;
|
|
10
34
|
}
|
|
11
|
-
console.log(chalk.blue(`${
|
|
35
|
+
console.log(chalk.blue(`${memories.length} memor${memories.length > 1 ? "ies" : "y"}`), chalk.gray(`(${total} total)`));
|
|
12
36
|
console.log();
|
|
13
|
-
for (const
|
|
14
|
-
console.log(chalk.bold(
|
|
15
|
-
console.log(chalk.gray(` id: ${
|
|
37
|
+
for (const memory of memories) {
|
|
38
|
+
console.log(chalk.bold(memory.title), chalk.gray(`[${memory.category}]`), chalk.gray(`· ${memory.source}`));
|
|
39
|
+
console.log(chalk.gray(` id: ${memory.id}`));
|
|
40
|
+
}
|
|
41
|
+
if (!options.all && allMemories.length < total) {
|
|
42
|
+
console.log(chalk.gray(`\n Showing ${allMemories.length} of ${total}. Use --all to fetch everything.`));
|
|
16
43
|
}
|
|
17
44
|
}
|
|
18
45
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAUA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAUA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAsHlD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAInD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA+CnD"}
|
package/dist/commands/login.js
CHANGED
|
@@ -50,16 +50,21 @@ export async function loginCommand() {
|
|
|
50
50
|
res.end("<html><body><h2>Login failed</h2><p>No authorization code received.</p></body></html>");
|
|
51
51
|
reject(new Error("No authorization code received from callback."));
|
|
52
52
|
}
|
|
53
|
-
// Close the server
|
|
54
|
-
setTimeout(() =>
|
|
53
|
+
// Close the server and force-kill connections so the process exits
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
server.close();
|
|
56
|
+
server.closeAllConnections();
|
|
57
|
+
}, 500);
|
|
55
58
|
}
|
|
56
59
|
});
|
|
57
60
|
server.listen(port);
|
|
58
|
-
// Timeout after 2 minutes
|
|
59
|
-
setTimeout(() => {
|
|
61
|
+
// Timeout after 2 minutes — use unref() so it doesn't keep the process alive
|
|
62
|
+
const timeout = setTimeout(() => {
|
|
60
63
|
server.close();
|
|
64
|
+
server.closeAllConnections();
|
|
61
65
|
reject(new Error("Login timed out — no callback received within 2 minutes."));
|
|
62
66
|
}, 120_000);
|
|
67
|
+
timeout.unref();
|
|
63
68
|
});
|
|
64
69
|
// Build the GitHub OAuth URL with our local callback as the redirect
|
|
65
70
|
const authUrl = `${apiUrl}/v1/auth/github?redirect_uri=${encodeURIComponent(callbackUrl)}`;
|
|
@@ -99,15 +104,35 @@ export async function logoutCommand() {
|
|
|
99
104
|
}
|
|
100
105
|
export async function whoamiCommand() {
|
|
101
106
|
const { loadCredentials } = await import("../lib/credentials.js");
|
|
102
|
-
const {
|
|
107
|
+
const { getClient } = await import("../lib/client.js");
|
|
108
|
+
const chalk = (await import("chalk")).default;
|
|
103
109
|
const creds = loadCredentials();
|
|
104
110
|
if (!creds?.access_token) {
|
|
105
111
|
console.log(" Not logged in. Run: memax login\n");
|
|
106
112
|
return;
|
|
107
113
|
}
|
|
108
114
|
try {
|
|
109
|
-
const
|
|
110
|
-
|
|
115
|
+
const me = await getClient().auth.me();
|
|
116
|
+
const u = me.user;
|
|
117
|
+
console.log();
|
|
118
|
+
console.log(` ${chalk.bold(u.display_name || u.name)} ${chalk.dim(`(${u.email})`)}`);
|
|
119
|
+
console.log(` Plan: ${chalk.cyan(u.plan)}`);
|
|
120
|
+
// Active hub
|
|
121
|
+
if (me.hubs && me.hubs.length > 0 && me.active_hub_id) {
|
|
122
|
+
const active = me.hubs.find((h) => h.hub.id === me.active_hub_id);
|
|
123
|
+
if (active) {
|
|
124
|
+
const typeTag = active.hub.hub_type === "personal" ? "" : chalk.dim(" (team)");
|
|
125
|
+
console.log(` Hub: ${active.hub.name}${typeTag}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Usage this period
|
|
129
|
+
if (me.usage &&
|
|
130
|
+
(me.usage.push_count > 0 ||
|
|
131
|
+
me.usage.recall_count > 0 ||
|
|
132
|
+
me.usage.ask_count > 0)) {
|
|
133
|
+
console.log(` Usage: ${me.usage.push_count} pushes, ${me.usage.recall_count} recalls, ${me.usage.ask_count} asks`);
|
|
134
|
+
}
|
|
135
|
+
console.log();
|
|
111
136
|
}
|
|
112
137
|
catch {
|
|
113
138
|
console.log(" Session expired or invalid. Run: memax login\n");
|