@hasna/mementos 0.4.22 → 0.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +84 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -5110,6 +5110,90 @@ program2.command("stats").description("Show memory statistics").option("--format
|
|
|
5110
5110
|
handleError(e);
|
|
5111
5111
|
}
|
|
5112
5112
|
});
|
|
5113
|
+
program2.command("report").description("Rich summary of memory activity and top memories").option("--days <n>", "Activity window in days (default: 7)", "7").option("--project <path>", "Filter by project path").option("--markdown", "Output as Markdown (for PRs, docs, etc.)").option("--json", "Output as JSON").action((opts) => {
|
|
5114
|
+
try {
|
|
5115
|
+
const globalOpts = program2.opts();
|
|
5116
|
+
const days = parseInt(opts.days, 10) || 7;
|
|
5117
|
+
const projectPath = opts.project || globalOpts.project;
|
|
5118
|
+
let projectId;
|
|
5119
|
+
if (projectPath) {
|
|
5120
|
+
const project = getProject(resolve3(projectPath));
|
|
5121
|
+
if (project)
|
|
5122
|
+
projectId = project.id;
|
|
5123
|
+
}
|
|
5124
|
+
const db = getDatabase();
|
|
5125
|
+
const conditions = projectId ? "AND project_id = ?" : "";
|
|
5126
|
+
const params = projectId ? [projectId] : [];
|
|
5127
|
+
const total = db.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' ${conditions}`).get(...params).c;
|
|
5128
|
+
const pinned = db.query(`SELECT COUNT(*) as c FROM memories WHERE status = 'active' AND pinned = 1 ${conditions}`).get(...params).c;
|
|
5129
|
+
const activityRows = db.query(`
|
|
5130
|
+
SELECT date(created_at) AS d, COUNT(*) AS cnt
|
|
5131
|
+
FROM memories WHERE status = 'active' AND date(created_at) >= date('now', '-${days} days') ${conditions}
|
|
5132
|
+
GROUP BY d ORDER BY d ASC
|
|
5133
|
+
`).all(...params);
|
|
5134
|
+
const recentTotal = activityRows.reduce((s, r) => s + r.cnt, 0);
|
|
5135
|
+
const avgPerDay = activityRows.length > 0 ? (recentTotal / activityRows.length).toFixed(1) : "0";
|
|
5136
|
+
const byScopeRows = db.query(`SELECT scope, COUNT(*) as c FROM memories WHERE status = 'active' ${conditions} GROUP BY scope`).all(...params);
|
|
5137
|
+
const byScope = Object.fromEntries(byScopeRows.map((r) => [r.scope, r.c]));
|
|
5138
|
+
const byCatRows = db.query(`SELECT category, COUNT(*) as c FROM memories WHERE status = 'active' ${conditions} GROUP BY category`).all(...params);
|
|
5139
|
+
const byCat = Object.fromEntries(byCatRows.map((r) => [r.category, r.c]));
|
|
5140
|
+
const topMems = db.query(`SELECT key, value, importance, scope, category FROM memories WHERE status = 'active' ${conditions} ORDER BY importance DESC, access_count DESC LIMIT 5`).all(...params);
|
|
5141
|
+
const topAgents = db.query(`SELECT agent_id, COUNT(*) as c FROM memories WHERE status = 'active' AND agent_id IS NOT NULL ${conditions} GROUP BY agent_id ORDER BY c DESC LIMIT 5`).all(...params);
|
|
5142
|
+
if (opts.json) {
|
|
5143
|
+
console.log(JSON.stringify({ total, pinned, recent: { days, total: recentTotal, avg_per_day: parseFloat(avgPerDay) }, by_scope: byScope, by_category: byCat, top_memories: topMems, top_agents: topAgents }, null, 2));
|
|
5144
|
+
return;
|
|
5145
|
+
}
|
|
5146
|
+
if (opts.markdown) {
|
|
5147
|
+
const lines = [
|
|
5148
|
+
`## Mementos Report (last ${days} days)`,
|
|
5149
|
+
"",
|
|
5150
|
+
`- **Total memories:** ${total} (${pinned} pinned)`,
|
|
5151
|
+
`- **Recent activity:** ${recentTotal} new in ${days} days (~${avgPerDay}/day)`,
|
|
5152
|
+
`- **Scopes:** global=${byScope["global"] || 0} shared=${byScope["shared"] || 0} private=${byScope["private"] || 0}`,
|
|
5153
|
+
`- **Categories:** knowledge=${byCat["knowledge"] || 0} fact=${byCat["fact"] || 0} preference=${byCat["preference"] || 0} history=${byCat["history"] || 0}`,
|
|
5154
|
+
"",
|
|
5155
|
+
"### Top Memories",
|
|
5156
|
+
...topMems.map((m) => `- **${m.key}** (${m.scope}/${m.category}, imp:${m.importance}): ${m.value.slice(0, 80)}${m.value.length > 80 ? "..." : ""}`)
|
|
5157
|
+
];
|
|
5158
|
+
if (topAgents.length > 0) {
|
|
5159
|
+
lines.push("", "### Top Agents", ...topAgents.map((a) => `- ${a.agent_id}: ${a.c} memories`));
|
|
5160
|
+
}
|
|
5161
|
+
console.log(lines.join(`
|
|
5162
|
+
`));
|
|
5163
|
+
return;
|
|
5164
|
+
}
|
|
5165
|
+
const sparkline = activityRows.map((r) => {
|
|
5166
|
+
const bars = "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
|
|
5167
|
+
const maxC = Math.max(...activityRows.map((x) => x.cnt), 1);
|
|
5168
|
+
return bars[Math.round(r.cnt / maxC * 7)] || "\u2581";
|
|
5169
|
+
}).join("");
|
|
5170
|
+
console.log(chalk.bold(`
|
|
5171
|
+
mementos report \u2014 last ${days} days
|
|
5172
|
+
`));
|
|
5173
|
+
console.log(` ${chalk.cyan("Total:")} ${total} memories (${chalk.yellow(String(pinned))} pinned)`);
|
|
5174
|
+
console.log(` ${chalk.cyan("Recent:")} ${recentTotal} new \xB7 ${chalk.dim(`~${avgPerDay}/day`)}`);
|
|
5175
|
+
console.log(` ${chalk.cyan("Activity:")} ${sparkline || chalk.dim("no activity")}`);
|
|
5176
|
+
console.log(` ${chalk.cyan("Scopes:")} global=${byScope["global"] || 0} shared=${byScope["shared"] || 0} private=${byScope["private"] || 0}`);
|
|
5177
|
+
console.log(` ${chalk.cyan("Categories:")} knowledge=${byCat["knowledge"] || 0} fact=${byCat["fact"] || 0} preference=${byCat["preference"] || 0} history=${byCat["history"] || 0}`);
|
|
5178
|
+
if (topMems.length > 0) {
|
|
5179
|
+
console.log(`
|
|
5180
|
+
${chalk.bold("Top memories by importance:")}`);
|
|
5181
|
+
topMems.forEach((m) => {
|
|
5182
|
+
console.log(` ${chalk.green(`[${m.importance}]`)} ${chalk.bold(m.key)} ${chalk.dim(`(${m.scope}/${m.category})`)}`);
|
|
5183
|
+
console.log(` ${m.value.slice(0, 90)}${m.value.length > 90 ? "..." : ""}`);
|
|
5184
|
+
});
|
|
5185
|
+
}
|
|
5186
|
+
if (topAgents.length > 0) {
|
|
5187
|
+
console.log(`
|
|
5188
|
+
${chalk.bold("Top agents:")}`);
|
|
5189
|
+
topAgents.forEach((a) => console.log(` ${a.agent_id}: ${a.c} memories`));
|
|
5190
|
+
}
|
|
5191
|
+
console.log("");
|
|
5192
|
+
} catch (e) {
|
|
5193
|
+
console.error(chalk.red(`report failed: ${e instanceof Error ? e.message : String(e)}`));
|
|
5194
|
+
process.exit(1);
|
|
5195
|
+
}
|
|
5196
|
+
});
|
|
5113
5197
|
program2.command("export").description("Export memories as JSON").option("-s, --scope <scope>", "Scope filter").option("-c, --category <cat>", "Category filter").option("--agent <name>", "Agent filter").option("--project <path>", "Project filter").action((opts) => {
|
|
5114
5198
|
try {
|
|
5115
5199
|
const globalOpts = program2.opts();
|