@aman_asmuei/aman-agent 0.16.2 → 0.17.1

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/index.js CHANGED
@@ -797,18 +797,18 @@ var McpManager = class {
797
797
 
798
798
  // src/agent.ts
799
799
  import * as readline from "readline";
800
- import fs12 from "fs";
801
- import path12 from "path";
802
- import os11 from "os";
800
+ import fs13 from "fs";
801
+ import path13 from "path";
802
+ import os12 from "os";
803
803
  import pc6 from "picocolors";
804
804
  import { marked } from "marked";
805
805
  import { markedTerminal } from "marked-terminal";
806
806
  import logUpdate from "log-update";
807
807
 
808
808
  // src/commands.ts
809
- import fs8 from "fs";
810
- import path8 from "path";
811
- import os8 from "os";
809
+ import fs9 from "fs";
810
+ import path9 from "path";
811
+ import os9 from "os";
812
812
  import { execFileSync } from "child_process";
813
813
  import pc3 from "picocolors";
814
814
 
@@ -869,10 +869,151 @@ function getEcosystemStatus(mcpToolCount, amemConnected) {
869
869
  };
870
870
  }
871
871
 
872
- // src/profile-templates.ts
873
- import fs5 from "fs";
872
+ // src/memory.ts
873
+ import {
874
+ createDatabase,
875
+ recall,
876
+ buildContext,
877
+ storeMemory,
878
+ consolidateMemories,
879
+ cosineSimilarity,
880
+ preloadEmbeddings,
881
+ buildVectorIndex,
882
+ recallMemories,
883
+ generateEmbedding,
884
+ getVectorIndex
885
+ } from "@aman_asmuei/amem-core";
874
886
  import path5 from "path";
875
887
  import os5 from "os";
888
+ import fs5 from "fs";
889
+ var db = null;
890
+ var currentProject = "global";
891
+ async function initMemory(project) {
892
+ if (db) return db;
893
+ const amemDir = process.env.AMEM_DIR ?? path5.join(os5.homedir(), ".amem");
894
+ if (!fs5.existsSync(amemDir)) fs5.mkdirSync(amemDir, { recursive: true });
895
+ const dbPath = process.env.AMEM_DB ?? path5.join(amemDir, "memory.db");
896
+ db = createDatabase(dbPath);
897
+ currentProject = project ?? "global";
898
+ preloadEmbeddings();
899
+ setTimeout(() => {
900
+ try {
901
+ buildVectorIndex(db);
902
+ } catch {
903
+ }
904
+ }, 1e3);
905
+ return db;
906
+ }
907
+ function getDb() {
908
+ if (!db) throw new Error("Memory not initialized \u2014 call initMemory() first");
909
+ return db;
910
+ }
911
+ async function memoryRecall(query, opts) {
912
+ return recall(getDb(), {
913
+ query,
914
+ limit: opts?.limit ?? 10,
915
+ compact: opts?.compact ?? true,
916
+ type: opts?.type,
917
+ tag: opts?.tag,
918
+ minConfidence: opts?.minConfidence,
919
+ explain: opts?.explain,
920
+ scope: currentProject
921
+ });
922
+ }
923
+ async function memoryContext(topic, maxTokens) {
924
+ return buildContext(getDb(), topic, { maxTokens, scope: currentProject });
925
+ }
926
+ async function memoryStore(opts) {
927
+ return storeMemory(getDb(), opts);
928
+ }
929
+ function memoryLog(sessionId, role, content) {
930
+ return getDb().appendLog({
931
+ sessionId,
932
+ role,
933
+ content,
934
+ project: currentProject,
935
+ metadata: {}
936
+ });
937
+ }
938
+ function reminderCheck() {
939
+ const all = getDb().checkReminders();
940
+ return all.filter((r) => r.scope === "global" || r.scope === currentProject);
941
+ }
942
+ async function memoryForget(opts) {
943
+ const db2 = getDb();
944
+ if (opts.id) {
945
+ const fullId = db2.resolveId(opts.id) ?? opts.id;
946
+ const memory = db2.getById(fullId);
947
+ if (!memory) return { deleted: 0, message: `Memory ${opts.id} not found.` };
948
+ db2.deleteMemory(fullId);
949
+ const vecIdx = getVectorIndex();
950
+ if (vecIdx) vecIdx.remove(fullId);
951
+ return { deleted: 1, message: `Deleted: "${memory.content}" (${memory.type})` };
952
+ }
953
+ if (opts.type) {
954
+ const all = db2.getAllForProject(currentProject);
955
+ const matches = all.filter((m) => m.type === opts.type);
956
+ if (matches.length === 0) return { deleted: 0, message: `No memories of type "${opts.type}" found.` };
957
+ const vecIdx = getVectorIndex();
958
+ for (const m of matches) {
959
+ db2.deleteMemory(m.id);
960
+ if (vecIdx) vecIdx.remove(m.id);
961
+ }
962
+ return { deleted: matches.length, message: `Deleted ${matches.length} "${opts.type}" memories.` };
963
+ }
964
+ if (opts.query) {
965
+ const queryEmbedding = await generateEmbedding(opts.query);
966
+ const matches = recallMemories(db2, { query: opts.query, queryEmbedding, limit: 50, minConfidence: 0, scope: currentProject });
967
+ if (matches.length === 0) return { deleted: 0, message: `No memories found matching "${opts.query}".` };
968
+ const vecIdx = getVectorIndex();
969
+ for (const m of matches) {
970
+ db2.deleteMemory(m.id);
971
+ if (vecIdx) vecIdx.remove(m.id);
972
+ }
973
+ return { deleted: matches.length, message: `Deleted ${matches.length} memories matching "${opts.query}".` };
974
+ }
975
+ return { deleted: 0, message: "Provide an id, type, or query to forget." };
976
+ }
977
+ function memoryConsolidate(dryRun = false) {
978
+ return consolidateMemories(getDb(), cosineSimilarity, {
979
+ dryRun,
980
+ maxStaleDays: 90,
981
+ minConfidence: 0.3,
982
+ minAccessCount: 0
983
+ });
984
+ }
985
+ function isMemoryInitialized() {
986
+ return db !== null;
987
+ }
988
+ function memoryStats() {
989
+ return getDb().getStats();
990
+ }
991
+ function memoryExport() {
992
+ return getDb().getAllForProject(currentProject);
993
+ }
994
+ function memorySince(hours) {
995
+ const since = Date.now() - hours * 60 * 60 * 1e3;
996
+ const all = getDb().getMemoriesSince(since);
997
+ return all.filter((m) => m.scope === "global" || m.scope === currentProject);
998
+ }
999
+ function memorySearch(query, limit) {
1000
+ return getDb().fullTextSearch(query, limit, currentProject);
1001
+ }
1002
+ function reminderSet(content, dueAt) {
1003
+ return getDb().insertReminder(content, dueAt ?? null, currentProject);
1004
+ }
1005
+ function reminderList(includeCompleted) {
1006
+ return getDb().listReminders(includeCompleted, currentProject);
1007
+ }
1008
+ function reminderComplete(id) {
1009
+ const fullId = getDb().resolveReminderId(id) ?? id;
1010
+ return getDb().completeReminder(fullId);
1011
+ }
1012
+
1013
+ // src/profile-templates.ts
1014
+ import fs6 from "fs";
1015
+ import path6 from "path";
1016
+ import os6 from "os";
876
1017
  var BUILT_IN_PROFILES = [
877
1018
  {
878
1019
  name: "coder",
@@ -965,9 +1106,9 @@ var BUILT_IN_PROFILES = [
965
1106
  function installProfileTemplate(templateName, userName) {
966
1107
  const template = BUILT_IN_PROFILES.find((t) => t.name === templateName);
967
1108
  if (!template) return null;
968
- const profileDir = path5.join(os5.homedir(), ".acore", "profiles", template.name);
969
- if (fs5.existsSync(profileDir)) return `Profile already exists: ${template.name}`;
970
- fs5.mkdirSync(profileDir, { recursive: true });
1109
+ const profileDir = path6.join(os6.homedir(), ".acore", "profiles", template.name);
1110
+ if (fs6.existsSync(profileDir)) return `Profile already exists: ${template.name}`;
1111
+ fs6.mkdirSync(profileDir, { recursive: true });
971
1112
  let core = template.core;
972
1113
  if (userName) {
973
1114
  core += `
@@ -981,12 +1122,12 @@ function installProfileTemplate(templateName, userName) {
981
1122
  - Detail level: balanced
982
1123
  `;
983
1124
  }
984
- fs5.writeFileSync(path5.join(profileDir, "core.md"), core, "utf-8");
1125
+ fs6.writeFileSync(path6.join(profileDir, "core.md"), core, "utf-8");
985
1126
  if (template.rules) {
986
- fs5.writeFileSync(path5.join(profileDir, "rules.md"), template.rules, "utf-8");
1127
+ fs6.writeFileSync(path6.join(profileDir, "rules.md"), template.rules, "utf-8");
987
1128
  }
988
1129
  if (template.skills) {
989
- fs5.writeFileSync(path5.join(profileDir, "skills.md"), template.skills, "utf-8");
1130
+ fs6.writeFileSync(path6.join(profileDir, "skills.md"), template.skills, "utf-8");
990
1131
  }
991
1132
  return null;
992
1133
  }
@@ -1113,43 +1254,43 @@ async function delegatePipeline(steps, initialInput, client, mcpManager, options
1113
1254
  }
1114
1255
 
1115
1256
  // src/teams.ts
1116
- import fs6 from "fs";
1117
- import path6 from "path";
1118
- import os6 from "os";
1257
+ import fs7 from "fs";
1258
+ import path7 from "path";
1259
+ import os7 from "os";
1119
1260
  import pc2 from "picocolors";
1120
1261
  function getTeamsDir() {
1121
- return path6.join(os6.homedir(), ".acore", "teams");
1262
+ return path7.join(os7.homedir(), ".acore", "teams");
1122
1263
  }
1123
1264
  function ensureTeamsDir() {
1124
1265
  const dir = getTeamsDir();
1125
- if (!fs6.existsSync(dir)) fs6.mkdirSync(dir, { recursive: true });
1266
+ if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
1126
1267
  return dir;
1127
1268
  }
1128
1269
  function teamPath(name) {
1129
1270
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
1130
- return path6.join(ensureTeamsDir(), `${slug}.json`);
1271
+ return path7.join(ensureTeamsDir(), `${slug}.json`);
1131
1272
  }
1132
1273
  function createTeam(team) {
1133
1274
  const fp = teamPath(team.name);
1134
- fs6.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
1275
+ fs7.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
1135
1276
  }
1136
1277
  function loadTeam(name) {
1137
1278
  const fp = teamPath(name);
1138
- if (!fs6.existsSync(fp)) return null;
1279
+ if (!fs7.existsSync(fp)) return null;
1139
1280
  try {
1140
- return JSON.parse(fs6.readFileSync(fp, "utf-8"));
1281
+ return JSON.parse(fs7.readFileSync(fp, "utf-8"));
1141
1282
  } catch {
1142
1283
  return null;
1143
1284
  }
1144
1285
  }
1145
1286
  function listTeams() {
1146
1287
  const dir = getTeamsDir();
1147
- if (!fs6.existsSync(dir)) return [];
1288
+ if (!fs7.existsSync(dir)) return [];
1148
1289
  const teams = [];
1149
- for (const file of fs6.readdirSync(dir)) {
1290
+ for (const file of fs7.readdirSync(dir)) {
1150
1291
  if (!file.endsWith(".json")) continue;
1151
1292
  try {
1152
- const content = fs6.readFileSync(path6.join(dir, file), "utf-8");
1293
+ const content = fs7.readFileSync(path7.join(dir, file), "utf-8");
1153
1294
  teams.push(JSON.parse(content));
1154
1295
  } catch {
1155
1296
  }
@@ -1158,8 +1299,8 @@ function listTeams() {
1158
1299
  }
1159
1300
  function deleteTeam(name) {
1160
1301
  const fp = teamPath(name);
1161
- if (!fs6.existsSync(fp)) return false;
1162
- fs6.unlinkSync(fp);
1302
+ if (!fs7.existsSync(fp)) return false;
1303
+ fs7.unlinkSync(fp);
1163
1304
  return true;
1164
1305
  }
1165
1306
  async function runTeam(team, task, client, mcpManager, tools) {
@@ -1385,23 +1526,23 @@ var BUILT_IN_TEAMS = [
1385
1526
  ];
1386
1527
 
1387
1528
  // src/plans.ts
1388
- import fs7 from "fs";
1389
- import path7 from "path";
1390
- import os7 from "os";
1529
+ import fs8 from "fs";
1530
+ import path8 from "path";
1531
+ import os8 from "os";
1391
1532
  function getPlansDir() {
1392
- const localDir = path7.join(process.cwd(), ".acore", "plans");
1393
- const localAcore = path7.join(process.cwd(), ".acore");
1394
- if (fs7.existsSync(localAcore)) return localDir;
1395
- return path7.join(os7.homedir(), ".acore", "plans");
1533
+ const localDir = path8.join(process.cwd(), ".acore", "plans");
1534
+ const localAcore = path8.join(process.cwd(), ".acore");
1535
+ if (fs8.existsSync(localAcore)) return localDir;
1536
+ return path8.join(os8.homedir(), ".acore", "plans");
1396
1537
  }
1397
1538
  function ensurePlansDir() {
1398
1539
  const dir = getPlansDir();
1399
- if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
1540
+ if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
1400
1541
  return dir;
1401
1542
  }
1402
1543
  function planPath(name) {
1403
1544
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
1404
- return path7.join(ensurePlansDir(), `${slug}.md`);
1545
+ return path8.join(ensurePlansDir(), `${slug}.md`);
1405
1546
  }
1406
1547
  function serializePlan(plan) {
1407
1548
  const lines = [];
@@ -1427,7 +1568,7 @@ function parsePlan(content, filePath) {
1427
1568
  const createdMatch = content.match(/\*\*Created:\*\*\s*(.+)/);
1428
1569
  const updatedMatch = content.match(/\*\*Updated:\*\*\s*(.+)/);
1429
1570
  const activeMatch = content.match(/\*\*Active:\*\*\s*(.+)/);
1430
- const name = nameMatch?.[1]?.trim() || path7.basename(filePath, ".md");
1571
+ const name = nameMatch?.[1]?.trim() || path8.basename(filePath, ".md");
1431
1572
  const goal = goalMatch?.[1]?.trim() || "";
1432
1573
  const createdAt = createdMatch?.[1]?.trim() || "";
1433
1574
  const updatedAt = updatedMatch?.[1]?.trim() || "";
@@ -1469,22 +1610,22 @@ function createPlan(name, goal, steps) {
1469
1610
  }
1470
1611
  function savePlan(plan) {
1471
1612
  const fp = planPath(plan.name);
1472
- fs7.writeFileSync(fp, serializePlan(plan), "utf-8");
1613
+ fs8.writeFileSync(fp, serializePlan(plan), "utf-8");
1473
1614
  }
1474
1615
  function loadPlan(name) {
1475
1616
  const fp = planPath(name);
1476
- if (!fs7.existsSync(fp)) return null;
1477
- const content = fs7.readFileSync(fp, "utf-8");
1617
+ if (!fs8.existsSync(fp)) return null;
1618
+ const content = fs8.readFileSync(fp, "utf-8");
1478
1619
  return parsePlan(content, fp);
1479
1620
  }
1480
1621
  function listPlans() {
1481
1622
  const dir = getPlansDir();
1482
- if (!fs7.existsSync(dir)) return [];
1623
+ if (!fs8.existsSync(dir)) return [];
1483
1624
  const plans = [];
1484
- for (const file of fs7.readdirSync(dir)) {
1625
+ for (const file of fs8.readdirSync(dir)) {
1485
1626
  if (!file.endsWith(".md")) continue;
1486
- const fp = path7.join(dir, file);
1487
- const content = fs7.readFileSync(fp, "utf-8");
1627
+ const fp = path8.join(dir, file);
1628
+ const content = fs8.readFileSync(fp, "utf-8");
1488
1629
  const plan = parsePlan(content, fp);
1489
1630
  if (plan) plans.push(plan);
1490
1631
  }
@@ -1580,16 +1721,17 @@ function progressBar(pct) {
1580
1721
 
1581
1722
  // src/commands.ts
1582
1723
  function readEcosystemFile(filePath, label) {
1583
- if (!fs8.existsSync(filePath)) {
1724
+ if (!fs9.existsSync(filePath)) {
1584
1725
  return pc3.dim(`No ${label} file found at ${filePath}`);
1585
1726
  }
1586
- return fs8.readFileSync(filePath, "utf-8").trim();
1727
+ return fs9.readFileSync(filePath, "utf-8").trim();
1587
1728
  }
1588
1729
  function parseCommand(input) {
1589
1730
  const trimmed = input.trim();
1590
1731
  const parts = trimmed.split(/\s+/);
1591
1732
  const base = parts[0].toLowerCase().replace(/^\//, "");
1592
- const action = parts.length > 1 ? parts[1].toLowerCase() : void 0;
1733
+ let action = parts.length > 1 ? parts[1].toLowerCase() : void 0;
1734
+ if (action === "--help" || action === "-h") action = "help";
1593
1735
  const args = parts.slice(2);
1594
1736
  return { base, action, args };
1595
1737
  }
@@ -1604,9 +1746,9 @@ async function mcpWrite(ctx, layer, tool, args) {
1604
1746
  return pc3.green(result);
1605
1747
  }
1606
1748
  async function handleIdentityCommand(action, args, ctx) {
1607
- const home2 = os8.homedir();
1749
+ const home2 = os9.homedir();
1608
1750
  if (!action) {
1609
- const content = readEcosystemFile(path8.join(home2, ".acore", "core.md"), "identity (acore)");
1751
+ const content = readEcosystemFile(path9.join(home2, ".acore", "core.md"), "identity (acore)");
1610
1752
  return { handled: true, output: content };
1611
1753
  }
1612
1754
  if (action === "update") {
@@ -1627,12 +1769,19 @@ async function handleIdentityCommand(action, args, ctx) {
1627
1769
  const output = await mcpWrite(ctx, "identity", "identity_update_section", { section, content });
1628
1770
  return { handled: true, output };
1629
1771
  }
1630
- return { handled: true, output: pc3.yellow(`Unknown action: /identity ${action}. Use /identity or /identity update <section>.`) };
1772
+ if (action === "help") {
1773
+ return { handled: true, output: [
1774
+ pc3.bold("Identity commands:"),
1775
+ ` ${pc3.cyan("/identity")} View current identity`,
1776
+ ` ${pc3.cyan("/identity update")} <section> Update a section`
1777
+ ].join("\n") };
1778
+ }
1779
+ return { handled: true, output: pc3.yellow(`Unknown action: /identity ${action}. Try /identity --help`) };
1631
1780
  }
1632
1781
  async function handleRulesCommand(action, args, ctx) {
1633
- const home2 = os8.homedir();
1782
+ const home2 = os9.homedir();
1634
1783
  if (!action) {
1635
- const content = readEcosystemFile(path8.join(home2, ".arules", "rules.md"), "guardrails (arules)");
1784
+ const content = readEcosystemFile(path9.join(home2, ".arules", "rules.md"), "guardrails (arules)");
1636
1785
  return { handled: true, output: content };
1637
1786
  }
1638
1787
  if (action === "add") {
@@ -1658,12 +1807,21 @@ async function handleRulesCommand(action, args, ctx) {
1658
1807
  const output = await mcpWrite(ctx, "rules", "rules_toggle", { category: args[0], index: parseInt(args[1], 10) });
1659
1808
  return { handled: true, output };
1660
1809
  }
1661
- return { handled: true, output: pc3.yellow(`Unknown action: /rules ${action}. Use /rules [add|remove|toggle].`) };
1810
+ if (action === "help") {
1811
+ return { handled: true, output: [
1812
+ pc3.bold("Rules commands:"),
1813
+ ` ${pc3.cyan("/rules")} View current rules`,
1814
+ ` ${pc3.cyan("/rules add")} <category> <text> Add a rule`,
1815
+ ` ${pc3.cyan("/rules remove")} <category> <idx> Remove a rule`,
1816
+ ` ${pc3.cyan("/rules toggle")} <category> <idx> Toggle a rule`
1817
+ ].join("\n") };
1818
+ }
1819
+ return { handled: true, output: pc3.yellow(`Unknown action: /rules ${action}. Try /rules --help`) };
1662
1820
  }
1663
1821
  async function handleWorkflowsCommand(action, args, ctx) {
1664
- const home2 = os8.homedir();
1822
+ const home2 = os9.homedir();
1665
1823
  if (!action) {
1666
- const content = readEcosystemFile(path8.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
1824
+ const content = readEcosystemFile(path9.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
1667
1825
  return { handled: true, output: content };
1668
1826
  }
1669
1827
  if (action === "add") {
@@ -1680,7 +1838,15 @@ async function handleWorkflowsCommand(action, args, ctx) {
1680
1838
  const output = await mcpWrite(ctx, "workflows", "workflow_remove", { name: args.join(" ") });
1681
1839
  return { handled: true, output };
1682
1840
  }
1683
- return { handled: true, output: pc3.yellow(`Unknown action: /workflows ${action}. Use /workflows [add|remove].`) };
1841
+ if (action === "help") {
1842
+ return { handled: true, output: [
1843
+ pc3.bold("Workflow commands:"),
1844
+ ` ${pc3.cyan("/workflows")} View current workflows`,
1845
+ ` ${pc3.cyan("/workflows add")} <name> Add a workflow`,
1846
+ ` ${pc3.cyan("/workflows remove")} <name> Remove a workflow`
1847
+ ].join("\n") };
1848
+ }
1849
+ return { handled: true, output: pc3.yellow(`Unknown action: /workflows ${action}. Try /workflows --help`) };
1684
1850
  }
1685
1851
  var AKIT_REGISTRY = [
1686
1852
  { name: "web-search", description: "Search the web for current information", category: "search", mcp: { package: "@anthropic/web-search", command: "npx", args: ["-y", "@anthropic/web-search"] } },
@@ -1702,38 +1868,38 @@ var AKIT_REGISTRY = [
1702
1868
  { name: "docling", description: "Convert PDF, DOCX, PPTX, XLSX to markdown", category: "documents", mcp: { package: "docling-mcp", command: "uvx", args: ["docling-mcp"] }, envHint: "Requires Python 3.10+. Install: pip install docling" }
1703
1869
  ];
1704
1870
  function loadAkitInstalled() {
1705
- const filePath = path8.join(os8.homedir(), ".akit", "installed.json");
1706
- if (!fs8.existsSync(filePath)) return [];
1871
+ const filePath = path9.join(os9.homedir(), ".akit", "installed.json");
1872
+ if (!fs9.existsSync(filePath)) return [];
1707
1873
  try {
1708
- return JSON.parse(fs8.readFileSync(filePath, "utf-8"));
1874
+ return JSON.parse(fs9.readFileSync(filePath, "utf-8"));
1709
1875
  } catch {
1710
1876
  return [];
1711
1877
  }
1712
1878
  }
1713
1879
  function saveAkitInstalled(tools) {
1714
- const dir = path8.join(os8.homedir(), ".akit");
1715
- fs8.mkdirSync(dir, { recursive: true });
1716
- fs8.writeFileSync(path8.join(dir, "installed.json"), JSON.stringify(tools, null, 2) + "\n", "utf-8");
1880
+ const dir = path9.join(os9.homedir(), ".akit");
1881
+ fs9.mkdirSync(dir, { recursive: true });
1882
+ fs9.writeFileSync(path9.join(dir, "installed.json"), JSON.stringify(tools, null, 2) + "\n", "utf-8");
1717
1883
  }
1718
1884
  function addToAmanAgentConfig(name, mcpConfig) {
1719
- const configPath = path8.join(os8.homedir(), ".aman-agent", "config.json");
1720
- if (!fs8.existsSync(configPath)) return;
1885
+ const configPath = path9.join(os9.homedir(), ".aman-agent", "config.json");
1886
+ if (!fs9.existsSync(configPath)) return;
1721
1887
  try {
1722
- const config = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
1888
+ const config = JSON.parse(fs9.readFileSync(configPath, "utf-8"));
1723
1889
  if (!config.mcpServers) config.mcpServers = {};
1724
1890
  config.mcpServers[name] = mcpConfig;
1725
- fs8.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1891
+ fs9.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1726
1892
  } catch {
1727
1893
  }
1728
1894
  }
1729
1895
  function removeFromAmanAgentConfig(name) {
1730
- const configPath = path8.join(os8.homedir(), ".aman-agent", "config.json");
1731
- if (!fs8.existsSync(configPath)) return;
1896
+ const configPath = path9.join(os9.homedir(), ".aman-agent", "config.json");
1897
+ if (!fs9.existsSync(configPath)) return;
1732
1898
  try {
1733
- const config = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
1899
+ const config = JSON.parse(fs9.readFileSync(configPath, "utf-8"));
1734
1900
  if (config.mcpServers) {
1735
1901
  delete config.mcpServers[name];
1736
- fs8.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1902
+ fs9.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1737
1903
  }
1738
1904
  } catch {
1739
1905
  }
@@ -1883,9 +2049,9 @@ function handleAkitCommand(action, args) {
1883
2049
  return { handled: true, output: lines.join("\n") };
1884
2050
  }
1885
2051
  async function handleSkillsCommand(action, args, ctx) {
1886
- const home2 = os8.homedir();
2052
+ const home2 = os9.homedir();
1887
2053
  if (!action) {
1888
- const content = readEcosystemFile(path8.join(home2, ".askill", "skills.md"), "skills (askill)");
2054
+ const content = readEcosystemFile(path9.join(home2, ".askill", "skills.md"), "skills (askill)");
1889
2055
  return { handled: true, output: content };
1890
2056
  }
1891
2057
  if (action === "install") {
@@ -1902,12 +2068,20 @@ async function handleSkillsCommand(action, args, ctx) {
1902
2068
  const output = await mcpWrite(ctx, "skills", "skill_uninstall", { name: args.join(" ") });
1903
2069
  return { handled: true, output };
1904
2070
  }
1905
- return { handled: true, output: pc3.yellow(`Unknown action: /skills ${action}. Use /skills [install|uninstall].`) };
2071
+ if (action === "help") {
2072
+ return { handled: true, output: [
2073
+ pc3.bold("Skills commands:"),
2074
+ ` ${pc3.cyan("/skills")} View installed skills`,
2075
+ ` ${pc3.cyan("/skills install")} <name> Install a skill`,
2076
+ ` ${pc3.cyan("/skills uninstall")} <name> Uninstall a skill`
2077
+ ].join("\n") };
2078
+ }
2079
+ return { handled: true, output: pc3.yellow(`Unknown action: /skills ${action}. Try /skills --help`) };
1906
2080
  }
1907
2081
  async function handleEvalCommand(action, args, ctx) {
1908
- const home2 = os8.homedir();
2082
+ const home2 = os9.homedir();
1909
2083
  if (!action) {
1910
- const content = readEcosystemFile(path8.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
2084
+ const content = readEcosystemFile(path9.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
1911
2085
  return { handled: true, output: content };
1912
2086
  }
1913
2087
  if (action === "milestone") {
@@ -1922,98 +2096,208 @@ async function handleEvalCommand(action, args, ctx) {
1922
2096
  }
1923
2097
  async function handleMemoryCommand(action, args, ctx) {
1924
2098
  if (!action) {
1925
- if (!ctx.mcpManager) {
1926
- return {
1927
- handled: true,
1928
- output: pc3.red("Memory not available: aman-mcp not connected. Start it with: npx @aman_asmuei/aman-mcp")
1929
- };
1930
- }
1931
- const result = await ctx.mcpManager.callTool("memory_context", { topic: "recent context" });
1932
- if (result.startsWith("Error")) {
1933
- return { handled: true, output: pc3.red(result) };
2099
+ try {
2100
+ const result = await memoryContext("recent context");
2101
+ if (result.memoriesUsed === 0) {
2102
+ return { handled: true, output: pc3.dim("No memories yet. Start chatting and I'll remember what matters.") };
2103
+ }
2104
+ return { handled: true, output: result.text };
2105
+ } catch (err) {
2106
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
1934
2107
  }
1935
- return { handled: true, output: result };
1936
2108
  }
1937
- if (action && !["search", "clear", "timeline"].includes(action)) {
1938
- if (!ctx.mcpManager) {
1939
- return { handled: true, output: pc3.red("Memory not available: MCP not connected.") };
1940
- }
1941
- const topic = [action, ...args].join(" ");
1942
- const result = await ctx.mcpManager.callTool("memory_context", { topic });
1943
- if (result.startsWith("Error")) {
1944
- return { handled: true, output: pc3.red(result) };
2109
+ if (action && !["search", "clear", "timeline", "stats", "export", "since", "fts", "help"].includes(action)) {
2110
+ try {
2111
+ const topic = [action, ...args].join(" ");
2112
+ const result = await memoryContext(topic);
2113
+ if (result.memoriesUsed === 0) {
2114
+ return { handled: true, output: pc3.dim(`No memories found for: "${topic}".`) };
2115
+ }
2116
+ return { handled: true, output: result.text };
2117
+ } catch (err) {
2118
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
1945
2119
  }
1946
- return { handled: true, output: result };
1947
2120
  }
1948
2121
  if (action === "search") {
1949
2122
  if (args.length < 1) {
1950
2123
  return { handled: true, output: pc3.yellow("Usage: /memory search <query...>") };
1951
2124
  }
1952
2125
  const query = args.join(" ");
1953
- const output = await mcpWrite(ctx, "memory", "memory_recall", { query });
1954
- return { handled: true, output };
2126
+ try {
2127
+ const result = await memoryRecall(query);
2128
+ return { handled: true, output: result.total === 0 ? pc3.dim("No memories found.") : result.text };
2129
+ } catch (err) {
2130
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2131
+ }
1955
2132
  }
1956
2133
  if (action === "clear") {
1957
2134
  if (args.length < 1) {
1958
- return { handled: true, output: pc3.yellow("Usage: /memory clear <category>") };
2135
+ return { handled: true, output: pc3.yellow("Usage: /memory clear <query> \u2014 delete memories matching a search query\n /memory clear --type <type> \u2014 delete all memories of a type (correction|decision|pattern|preference|topology|fact)") };
2136
+ }
2137
+ try {
2138
+ if (args[0] === "--type" && args[1]) {
2139
+ const result2 = await memoryForget({ query: args[1], type: args[1] });
2140
+ return { handled: true, output: result2.deleted > 0 ? pc3.green(result2.message) : pc3.dim(result2.message) };
2141
+ }
2142
+ const result = await memoryForget({ query: args.join(" ") });
2143
+ return { handled: true, output: result.deleted > 0 ? pc3.green(result.message) : pc3.dim(result.message) };
2144
+ } catch (err) {
2145
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
1959
2146
  }
1960
- const output = await mcpWrite(ctx, "memory", "memory_forget", { category: args[0] });
1961
- return { handled: true, output };
1962
2147
  }
1963
2148
  if (action === "timeline") {
1964
- if (!ctx.mcpManager) {
1965
- return { handled: true, output: pc3.red("Memory not available: MCP not connected.") };
1966
- }
1967
2149
  try {
1968
- const result = await ctx.mcpManager.callTool("memory_recall", { query: "*", limit: 500 });
1969
- if (result.startsWith("Error") || result.includes("No memories found")) {
2150
+ const result = await memoryRecall("*", { limit: 500, compact: false });
2151
+ if (result.total === 0) {
1970
2152
  return { handled: true, output: pc3.dim("No memories yet. Start chatting and I'll remember what matters.") };
1971
2153
  }
1972
- try {
1973
- const memories = JSON.parse(result);
1974
- if (Array.isArray(memories) && memories.length > 0) {
1975
- const byDate = /* @__PURE__ */ new Map();
1976
- for (const mem of memories) {
1977
- const date = mem.created_at ? new Date(mem.created_at).toLocaleDateString("en-US", { month: "short", day: "numeric" }) : "Unknown";
1978
- byDate.set(date, (byDate.get(date) || 0) + 1);
1979
- }
1980
- const maxCount = Math.max(...byDate.values());
1981
- const barWidth = 10;
1982
- const lines = [pc3.bold("Memory Timeline:"), ""];
1983
- for (const [date, count] of byDate) {
1984
- const filled = Math.round(count / maxCount * barWidth);
1985
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(barWidth - filled);
1986
- lines.push(` ${date.padEnd(8)} ${bar} ${count} memories`);
1987
- }
1988
- const tags = /* @__PURE__ */ new Map();
1989
- for (const mem of memories) {
1990
- if (Array.isArray(mem.tags)) {
1991
- for (const tag of mem.tags) {
1992
- tags.set(tag, (tags.get(tag) || 0) + 1);
1993
- }
2154
+ const memories = result.memories;
2155
+ if (memories.length > 0) {
2156
+ const byDate = /* @__PURE__ */ new Map();
2157
+ for (const mem of memories) {
2158
+ const createdAt = mem.created_at;
2159
+ const date = createdAt ? new Date(createdAt).toLocaleDateString("en-US", { month: "short", day: "numeric" }) : "Unknown";
2160
+ byDate.set(date, (byDate.get(date) || 0) + 1);
2161
+ }
2162
+ const maxCount = Math.max(...byDate.values());
2163
+ const barWidth = 10;
2164
+ const lines = [pc3.bold("Memory Timeline:"), ""];
2165
+ for (const [date, count] of byDate) {
2166
+ const filled = Math.round(count / maxCount * barWidth);
2167
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(barWidth - filled);
2168
+ lines.push(` ${date.padEnd(8)} ${bar} ${count} memories`);
2169
+ }
2170
+ const tags = /* @__PURE__ */ new Map();
2171
+ for (const mem of memories) {
2172
+ const memTags = mem.tags;
2173
+ if (Array.isArray(memTags)) {
2174
+ for (const tag of memTags) {
2175
+ tags.set(tag, (tags.get(tag) || 0) + 1);
1994
2176
  }
1995
2177
  }
1996
- lines.push("");
1997
- lines.push(` Total: ${memories.length} memories`);
1998
- if (tags.size > 0) {
1999
- const topTags = [...tags.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([tag, count]) => `#${tag} (${count})`).join(", ");
2000
- lines.push(` Top tags: ${topTags}`);
2001
- }
2002
- return { handled: true, output: lines.join("\n") };
2003
2178
  }
2004
- } catch {
2179
+ lines.push("");
2180
+ lines.push(` Total: ${result.total} memories`);
2181
+ if (tags.size > 0) {
2182
+ const topTags = [...tags.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([tag, count]) => `#${tag} (${count})`).join(", ");
2183
+ lines.push(` Top tags: ${topTags}`);
2184
+ }
2185
+ return { handled: true, output: lines.join("\n") };
2005
2186
  }
2006
- const lineCount = result.split("\n").filter((l) => l.trim()).length;
2007
- return { handled: true, output: `Total memories: ~${lineCount} entries.` };
2187
+ return { handled: true, output: `Total memories: ${result.total} entries.` };
2008
2188
  } catch {
2009
2189
  return { handled: true, output: pc3.red("Failed to retrieve memory timeline.") };
2010
2190
  }
2011
2191
  }
2012
- return { handled: true, output: pc3.yellow(`Unknown action: /memory ${action}. Use /memory [search|clear|timeline].`) };
2192
+ if (action === "stats") {
2193
+ try {
2194
+ const stats = memoryStats();
2195
+ const lines = [pc3.bold("Memory Statistics:"), ""];
2196
+ lines.push(` Total memories: ${pc3.bold(String(stats.total))}`);
2197
+ if (Object.keys(stats.byType).length > 0) {
2198
+ lines.push("");
2199
+ lines.push(` ${pc3.dim("By type:")}`);
2200
+ for (const [type, count] of Object.entries(stats.byType)) {
2201
+ lines.push(` ${type.padEnd(16)} ${count}`);
2202
+ }
2203
+ }
2204
+ return { handled: true, output: lines.join("\n") };
2205
+ } catch (err) {
2206
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2207
+ }
2208
+ }
2209
+ if (action === "export") {
2210
+ try {
2211
+ const format = args[0] === "json" ? "json" : "markdown";
2212
+ const memories = memoryExport();
2213
+ if (memories.length === 0) {
2214
+ return { handled: true, output: pc3.dim("No memories to export.") };
2215
+ }
2216
+ if (format === "json") {
2217
+ const jsonOut = memories.map((m) => ({ id: m.id, type: m.type, content: m.content, tags: m.tags, confidence: m.confidence, createdAt: m.createdAt, tier: m.tier }));
2218
+ return { handled: true, output: JSON.stringify(jsonOut, null, 2) };
2219
+ }
2220
+ const lines = [`# Memory Export (${memories.length} memories)`, ""];
2221
+ for (const m of memories) {
2222
+ const date = new Date(m.createdAt).toLocaleDateString();
2223
+ const tags = m.tags.length > 0 ? ` [${m.tags.map((t) => `#${t}`).join(", ")}]` : "";
2224
+ lines.push(`- **[${m.type}]** ${m.content}${tags} ${pc3.dim(`(${date}, ${Math.round(m.confidence * 100)}%)`)}`);
2225
+ }
2226
+ return { handled: true, output: lines.join("\n") };
2227
+ } catch (err) {
2228
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2229
+ }
2230
+ }
2231
+ if (action === "since") {
2232
+ try {
2233
+ let hours = 24;
2234
+ if (args[0]) {
2235
+ const match = args[0].match(/^(\d+)(h|d|w)$/);
2236
+ if (match) {
2237
+ const value = parseInt(match[1], 10);
2238
+ const unit = match[2];
2239
+ if (unit === "h") hours = value;
2240
+ else if (unit === "d") hours = value * 24;
2241
+ else if (unit === "w") hours = value * 24 * 7;
2242
+ } else {
2243
+ return { handled: true, output: pc3.yellow("Usage: /memory since <Nh|Nd|Nw> (e.g., 24h, 7d, 1w)") };
2244
+ }
2245
+ }
2246
+ const memories = memorySince(hours);
2247
+ if (memories.length === 0) {
2248
+ return { handled: true, output: pc3.dim(`No memories in the last ${args[0] || "24h"}.`) };
2249
+ }
2250
+ const lines = [pc3.bold(`Memories since ${args[0] || "24h"} (${memories.length}):`), ""];
2251
+ for (const m of memories) {
2252
+ const age = Math.round((Date.now() - m.createdAt) / 36e5);
2253
+ const ageStr = age < 1 ? "<1h ago" : `${age}h ago`;
2254
+ lines.push(` ${pc3.dim(ageStr.padEnd(10))} [${m.type}] ${m.content}`);
2255
+ }
2256
+ return { handled: true, output: lines.join("\n") };
2257
+ } catch (err) {
2258
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2259
+ }
2260
+ }
2261
+ if (action === "fts") {
2262
+ if (args.length < 1) {
2263
+ return { handled: true, output: pc3.yellow("Usage: /memory fts <query...> \u2014 full-text search") };
2264
+ }
2265
+ try {
2266
+ const query = args.join(" ");
2267
+ const results = memorySearch(query, 20);
2268
+ if (results.length === 0) {
2269
+ return { handled: true, output: pc3.dim(`No results for full-text search: "${query}".`) };
2270
+ }
2271
+ const lines = [pc3.bold(`FTS results for "${query}" (${results.length}):`), ""];
2272
+ for (const m of results) {
2273
+ const tags = m.tags.length > 0 ? ` ${pc3.dim(m.tags.map((t) => `#${t}`).join(" "))}` : "";
2274
+ lines.push(` [${m.type}] ${m.content}${tags}`);
2275
+ }
2276
+ return { handled: true, output: lines.join("\n") };
2277
+ } catch (err) {
2278
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2279
+ }
2280
+ }
2281
+ if (action === "help") {
2282
+ return { handled: true, output: [
2283
+ pc3.bold("Memory commands:"),
2284
+ ` ${pc3.cyan("/memory")} View recent context`,
2285
+ ` ${pc3.cyan("/memory")} <topic> Context for a topic`,
2286
+ ` ${pc3.cyan("/memory search")} <query> Search memories (semantic)`,
2287
+ ` ${pc3.cyan("/memory fts")} <query> Full-text search (FTS5)`,
2288
+ ` ${pc3.cyan("/memory since")} <Nh|Nd|Nw> Memories from time window`,
2289
+ ` ${pc3.cyan("/memory stats")} Show memory statistics`,
2290
+ ` ${pc3.cyan("/memory export")} [json] Export all memories`,
2291
+ ` ${pc3.cyan("/memory timeline")} View memory timeline`,
2292
+ ` ${pc3.cyan("/memory clear")} <query> Delete matching memories`,
2293
+ ` ${pc3.cyan("/memory clear --type")} <type> Delete all of a type`
2294
+ ].join("\n") };
2295
+ }
2296
+ return { handled: true, output: pc3.yellow(`Unknown action: /memory ${action}. Try /memory --help`) };
2013
2297
  }
2014
2298
  function handleStatusCommand(ctx) {
2015
2299
  const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;
2016
- const amemConnected = mcpToolCount > 0;
2300
+ const amemConnected = isMemoryInitialized();
2017
2301
  const status = getEcosystemStatus(mcpToolCount, amemConnected);
2018
2302
  const lines = [pc3.bold("Aman Ecosystem Dashboard"), ""];
2019
2303
  for (const layer of status.layers) {
@@ -2029,7 +2313,7 @@ function handleStatusCommand(ctx) {
2029
2313
  }
2030
2314
  function handleDoctorCommand(ctx) {
2031
2315
  const mcpToolCount = ctx.mcpManager ? ctx.mcpManager.getTools().length : 0;
2032
- const amemConnected = mcpToolCount > 0;
2316
+ const amemConnected = isMemoryInitialized();
2033
2317
  const status = getEcosystemStatus(mcpToolCount, amemConnected);
2034
2318
  const lines = [pc3.bold("Aman Health Check"), ""];
2035
2319
  let healthy = 0;
@@ -2063,7 +2347,7 @@ function handleDoctorCommand(ctx) {
2063
2347
  }
2064
2348
  lines.push(` ${status.amemConnected ? pc3.green("\u2713") : pc3.red("\u2717")} ${"Memory".padEnd(12)} ${status.amemConnected ? pc3.green("connected") : pc3.red("not connected")}`);
2065
2349
  if (!status.amemConnected) {
2066
- lines.push(` ${pc3.dim("\u2192 Fix: npx @aman_asmuei/amem")}`);
2350
+ lines.push(` ${pc3.dim("\u2192 Fix: restart aman-agent (memory initializes automatically)")}`);
2067
2351
  fixes++;
2068
2352
  } else {
2069
2353
  healthy++;
@@ -2085,7 +2369,8 @@ function handleHelp() {
2085
2369
  ` ${pc3.cyan("/akit")} Manage tools [add|remove <tool>]`,
2086
2370
  ` ${pc3.cyan("/skills")} View skills [install|uninstall ...]`,
2087
2371
  ` ${pc3.cyan("/eval")} View evaluation [milestone ...]`,
2088
- ` ${pc3.cyan("/memory")} View recent memories [search|clear|timeline]`,
2372
+ ` ${pc3.cyan("/memory")} View recent memories [search|fts|since|stats|export|clear|timeline]`,
2373
+ ` ${pc3.cyan("/reminder")} Manage reminders [set|check|done]`,
2089
2374
  ` ${pc3.cyan("/status")} Ecosystem dashboard`,
2090
2375
  ` ${pc3.cyan("/doctor")} Health check all layers`,
2091
2376
  ` ${pc3.cyan("/decisions")} View decision log [<project>]`,
@@ -2094,7 +2379,7 @@ function handleHelp() {
2094
2379
  ` ${pc3.cyan("/save")} Save conversation to memory`,
2095
2380
  ` ${pc3.cyan("/model")} Show current LLM model`,
2096
2381
  ` ${pc3.cyan("/update")} Check for updates`,
2097
- ` ${pc3.cyan("/reconfig")} Reset LLM config`,
2382
+ ` ${pc3.cyan("/reset")} Full reset [all|memory|config|identity|rules]`,
2098
2383
  ` ${pc3.cyan("/clear")} Clear conversation history`,
2099
2384
  ` ${pc3.cyan("/quit")} Exit`
2100
2385
  ].join("\n")
@@ -2103,27 +2388,62 @@ function handleHelp() {
2103
2388
  function handleSave() {
2104
2389
  return { handled: true, saveConversation: true };
2105
2390
  }
2106
- function handleReconfig() {
2107
- const configDir = path8.join(os8.homedir(), ".aman-agent");
2108
- const configPath = path8.join(configDir, "config.json");
2109
- if (fs8.existsSync(configPath)) {
2110
- fs8.unlinkSync(configPath);
2391
+ function handleReset(action) {
2392
+ const dirs = {
2393
+ config: path9.join(os9.homedir(), ".aman-agent"),
2394
+ memory: path9.join(os9.homedir(), ".amem"),
2395
+ identity: path9.join(os9.homedir(), ".acore"),
2396
+ rules: path9.join(os9.homedir(), ".arules")
2397
+ };
2398
+ if (action === "help" || !action) {
2399
+ return {
2400
+ handled: true,
2401
+ output: [
2402
+ pc3.bold("Reset options:"),
2403
+ ` ${pc3.cyan("/reset all")} Full reset \u2014 config, memory, identity, rules`,
2404
+ ` ${pc3.cyan("/reset memory")} Clear all memories only`,
2405
+ ` ${pc3.cyan("/reset config")} Reset LLM config only`,
2406
+ ` ${pc3.cyan("/reset identity")} Reset persona/identity only`,
2407
+ ` ${pc3.cyan("/reset rules")} Reset guardrails only`,
2408
+ "",
2409
+ pc3.dim("Directories:"),
2410
+ ...Object.entries(dirs).map(([k, v]) => ` ${k}: ${pc3.dim(v)}`)
2411
+ ].join("\n")
2412
+ };
2413
+ }
2414
+ const targets = action === "all" ? ["config", "memory", "identity", "rules"] : [action];
2415
+ if (!targets.every((t) => t in dirs)) {
2416
+ return { handled: true, output: pc3.red(`Unknown target: ${action}. Use /reset help`) };
2417
+ }
2418
+ const removed = [];
2419
+ for (const target of targets) {
2420
+ const dir = dirs[target];
2421
+ if (fs9.existsSync(dir)) {
2422
+ fs9.rmSync(dir, { recursive: true, force: true });
2423
+ removed.push(target);
2424
+ }
2425
+ }
2426
+ if (targets.includes("config")) {
2427
+ const configDir = dirs.config;
2428
+ fs9.mkdirSync(configDir, { recursive: true });
2429
+ fs9.writeFileSync(path9.join(configDir, ".reconfig"), "", "utf-8");
2430
+ }
2431
+ if (removed.length === 0) {
2432
+ return { handled: true, output: pc3.dim("Nothing to reset \u2014 directories don't exist.") };
2111
2433
  }
2112
- fs8.mkdirSync(configDir, { recursive: true });
2113
- fs8.writeFileSync(path8.join(configDir, ".reconfig"), "", "utf-8");
2114
2434
  return {
2115
2435
  handled: true,
2116
2436
  quit: true,
2117
2437
  output: [
2118
- pc3.green("Config reset."),
2119
- "Next run will prompt you to choose your LLM provider."
2438
+ pc3.green(`Reset complete: ${removed.join(", ")}`),
2439
+ "Restart aman-agent to begin fresh."
2120
2440
  ].join("\n")
2121
2441
  };
2122
2442
  }
2123
2443
  function handleUpdate() {
2124
2444
  try {
2125
2445
  const current = execFileSync("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
2126
- const local = JSON.parse(fs8.readFileSync(path8.join(__dirname, "..", "package.json"), "utf-8")).version;
2446
+ const local = JSON.parse(fs9.readFileSync(path9.join(__dirname, "..", "package.json"), "utf-8")).version;
2127
2447
  if (current === local) {
2128
2448
  return { handled: true, output: `${pc3.green("Up to date")} \u2014 v${local}` };
2129
2449
  }
@@ -2152,31 +2472,26 @@ function handleUpdate() {
2152
2472
  };
2153
2473
  }
2154
2474
  }
2155
- async function handleDecisionsCommand(action, _args, ctx) {
2156
- if (!ctx.mcpManager) {
2157
- return { handled: true, output: pc3.red("Decisions not available: MCP not connected.") };
2158
- }
2159
- const scope = action || void 0;
2160
- const result = await ctx.mcpManager.callTool("memory_recall", {
2161
- query: "decision",
2162
- type: "decision",
2163
- limit: 20,
2164
- ...scope ? { scope } : {}
2165
- });
2166
- if (result.startsWith("Error")) {
2167
- return { handled: true, output: pc3.red(result) };
2475
+ async function handleDecisionsCommand(action, _args, _ctx) {
2476
+ try {
2477
+ const result = await memoryRecall("decision", { type: "decision", limit: 20 });
2478
+ if (result.total === 0) {
2479
+ return { handled: true, output: pc3.dim("No decisions recorded yet.") };
2480
+ }
2481
+ return { handled: true, output: pc3.bold("Decision Log:\n") + result.text };
2482
+ } catch (err) {
2483
+ return { handled: true, output: pc3.red(`Memory error: ${err instanceof Error ? err.message : String(err)}`) };
2168
2484
  }
2169
- return { handled: true, output: pc3.bold("Decision Log:\n") + result };
2170
2485
  }
2171
2486
  function handleExportCommand() {
2172
2487
  return { handled: true, exportConversation: true };
2173
2488
  }
2174
2489
  function handleDebugCommand() {
2175
- const logPath = path8.join(os8.homedir(), ".aman-agent", "debug.log");
2176
- if (!fs8.existsSync(logPath)) {
2490
+ const logPath = path9.join(os9.homedir(), ".aman-agent", "debug.log");
2491
+ if (!fs9.existsSync(logPath)) {
2177
2492
  return { handled: true, output: pc3.dim("No debug log found.") };
2178
2493
  }
2179
- const content = fs8.readFileSync(logPath, "utf-8");
2494
+ const content = fs9.readFileSync(logPath, "utf-8");
2180
2495
  const lines = content.trim().split("\n");
2181
2496
  const last20 = lines.slice(-20).join("\n");
2182
2497
  return { handled: true, output: pc3.bold("Debug Log (last 20 entries):\n") + pc3.dim(last20) };
@@ -2374,7 +2689,7 @@ ${result.response}`
2374
2689
  };
2375
2690
  }
2376
2691
  function handleProfileCommand(action, args) {
2377
- const profilesDir = path8.join(os8.homedir(), ".acore", "profiles");
2692
+ const profilesDir = path9.join(os9.homedir(), ".acore", "profiles");
2378
2693
  if (!action || action === "list") {
2379
2694
  const profiles = listProfiles();
2380
2695
  if (profiles.length === 0) {
@@ -2398,8 +2713,8 @@ function handleProfileCommand(action, args) {
2398
2713
  };
2399
2714
  }
2400
2715
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
2401
- const profileDir = path8.join(profilesDir, slug);
2402
- if (fs8.existsSync(profileDir)) {
2716
+ const profileDir = path9.join(profilesDir, slug);
2717
+ if (fs9.existsSync(profileDir)) {
2403
2718
  return { handled: true, output: pc3.yellow(`Profile already exists: ${slug}`) };
2404
2719
  }
2405
2720
  const builtIn = BUILT_IN_PROFILES.find((t) => t.name === slug);
@@ -2415,16 +2730,16 @@ function handleProfileCommand(action, args) {
2415
2730
  Use: aman-agent --profile ${slug}`
2416
2731
  };
2417
2732
  }
2418
- fs8.mkdirSync(profileDir, { recursive: true });
2419
- const globalCore = path8.join(os8.homedir(), ".acore", "core.md");
2420
- if (fs8.existsSync(globalCore)) {
2421
- let content = fs8.readFileSync(globalCore, "utf-8");
2733
+ fs9.mkdirSync(profileDir, { recursive: true });
2734
+ const globalCore = path9.join(os9.homedir(), ".acore", "core.md");
2735
+ if (fs9.existsSync(globalCore)) {
2736
+ let content = fs9.readFileSync(globalCore, "utf-8");
2422
2737
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
2423
2738
  content = content.replace(/^# .+$/m, `# ${aiName}`);
2424
- fs8.writeFileSync(path8.join(profileDir, "core.md"), content, "utf-8");
2739
+ fs9.writeFileSync(path9.join(profileDir, "core.md"), content, "utf-8");
2425
2740
  } else {
2426
2741
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
2427
- fs8.writeFileSync(path8.join(profileDir, "core.md"), `# ${aiName}
2742
+ fs9.writeFileSync(path9.join(profileDir, "core.md"), `# ${aiName}
2428
2743
 
2429
2744
  ## Identity
2430
2745
  - Role: ${aiName} is your AI companion
@@ -2437,7 +2752,7 @@ function handleProfileCommand(action, args) {
2437
2752
  return {
2438
2753
  handled: true,
2439
2754
  output: pc3.green(`Profile created: ${slug}`) + `
2440
- Edit: ${path8.join(profileDir, "core.md")}
2755
+ Edit: ${path9.join(profileDir, "core.md")}
2441
2756
  Use: aman-agent --profile ${slug}
2442
2757
 
2443
2758
  ${pc3.dim("Add rules.md or skills.md for profile-specific overrides.")}`
@@ -2446,9 +2761,9 @@ function handleProfileCommand(action, args) {
2446
2761
  case "show": {
2447
2762
  const name = args[0];
2448
2763
  if (!name) return { handled: true, output: pc3.yellow("Usage: /profile show <name>") };
2449
- const profileDir = path8.join(profilesDir, name);
2450
- if (!fs8.existsSync(profileDir)) return { handled: true, output: pc3.red(`Profile not found: ${name}`) };
2451
- const files = fs8.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
2764
+ const profileDir = path9.join(profilesDir, name);
2765
+ if (!fs9.existsSync(profileDir)) return { handled: true, output: pc3.red(`Profile not found: ${name}`) };
2766
+ const files = fs9.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
2452
2767
  const lines = files.map((f) => ` ${f}`);
2453
2768
  return { handled: true, output: `Profile: ${pc3.bold(name)}
2454
2769
  Files:
@@ -2457,9 +2772,9 @@ ${lines.join("\n")}` };
2457
2772
  case "delete": {
2458
2773
  const name = args[0];
2459
2774
  if (!name) return { handled: true, output: pc3.yellow("Usage: /profile delete <name>") };
2460
- const profileDir = path8.join(profilesDir, name);
2461
- if (!fs8.existsSync(profileDir)) return { handled: true, output: pc3.red(`Profile not found: ${name}`) };
2462
- fs8.rmSync(profileDir, { recursive: true });
2775
+ const profileDir = path9.join(profilesDir, name);
2776
+ if (!fs9.existsSync(profileDir)) return { handled: true, output: pc3.red(`Profile not found: ${name}`) };
2777
+ fs9.rmSync(profileDir, { recursive: true });
2463
2778
  return { handled: true, output: pc3.dim(`Profile deleted: ${name}`) };
2464
2779
  }
2465
2780
  case "help":
@@ -2566,6 +2881,86 @@ function handlePlanCommand(action, args) {
2566
2881
  return { handled: true, output: pc3.yellow(`Unknown plan action: ${action}. Try /plan help`) };
2567
2882
  }
2568
2883
  }
2884
+ async function handleReminderCommand(action, args) {
2885
+ if (!action || action === "list") {
2886
+ try {
2887
+ const reminders = reminderList();
2888
+ if (reminders.length === 0) return { handled: true, output: pc3.dim("No reminders.") };
2889
+ const lines = [pc3.bold(`Reminders (${reminders.length}):`), ""];
2890
+ for (const r of reminders) {
2891
+ const status = r.completed ? pc3.green("[done]") : pc3.yellow("[todo]");
2892
+ const due = r.dueAt ? ` ${pc3.dim(`due: ${new Date(r.dueAt).toLocaleString()}`)}` : "";
2893
+ lines.push(` ${status} ${r.content}${due} ${pc3.dim(`(${r.id.slice(0, 8)})`)}`);
2894
+ }
2895
+ return { handled: true, output: lines.join("\n") };
2896
+ } catch (err) {
2897
+ return { handled: true, output: pc3.red(`Reminder error: ${err instanceof Error ? err.message : String(err)}`) };
2898
+ }
2899
+ }
2900
+ if (action === "set" || action === "add") {
2901
+ if (args.length === 0) return { handled: true, output: pc3.yellow("Usage: /reminder set <text> [--due <time>]\n Time formats: 1h, 2d, 1w, or ISO date (2026-04-10)") };
2902
+ let dueAt;
2903
+ const dueIdx = args.indexOf("--due");
2904
+ let contentArgs = args;
2905
+ if (dueIdx >= 0 && args[dueIdx + 1]) {
2906
+ const dueStr = args[dueIdx + 1];
2907
+ contentArgs = [...args.slice(0, dueIdx), ...args.slice(dueIdx + 2)];
2908
+ const relMatch = dueStr.match(/^(\d+)(h|d|w)$/);
2909
+ if (relMatch) {
2910
+ const num = parseInt(relMatch[1], 10);
2911
+ const unit = relMatch[2];
2912
+ const ms = unit === "h" ? num * 36e5 : unit === "d" ? num * 864e5 : num * 6048e5;
2913
+ dueAt = Date.now() + ms;
2914
+ } else {
2915
+ const parsed = Date.parse(dueStr);
2916
+ if (!isNaN(parsed)) dueAt = parsed;
2917
+ }
2918
+ }
2919
+ const content = contentArgs.join(" ");
2920
+ if (!content) return { handled: true, output: pc3.yellow("Usage: /reminder set <text> [--due <time>]") };
2921
+ try {
2922
+ const id = reminderSet(content, dueAt);
2923
+ const dueInfo = dueAt ? ` (due: ${new Date(dueAt).toLocaleDateString()})` : "";
2924
+ return { handled: true, output: pc3.green(`Reminder set: "${content}"${dueInfo} (ID: ${id.slice(0, 8)})`) };
2925
+ } catch (err) {
2926
+ return { handled: true, output: pc3.red(`Reminder error: ${err instanceof Error ? err.message : String(err)}`) };
2927
+ }
2928
+ }
2929
+ if (action === "done" || action === "complete") {
2930
+ if (!args[0]) return { handled: true, output: pc3.yellow("Usage: /reminder done <id>") };
2931
+ try {
2932
+ const result = reminderComplete(args[0]);
2933
+ return { handled: true, output: result ? pc3.green("Reminder completed.") : pc3.yellow("Reminder not found.") };
2934
+ } catch (err) {
2935
+ return { handled: true, output: pc3.red(`Reminder error: ${err instanceof Error ? err.message : String(err)}`) };
2936
+ }
2937
+ }
2938
+ if (action === "check") {
2939
+ try {
2940
+ const reminders = reminderCheck();
2941
+ if (reminders.length === 0) return { handled: true, output: pc3.dim("No pending reminders.") };
2942
+ const lines = [pc3.bold("Pending Reminders:"), ""];
2943
+ for (const r of reminders) {
2944
+ const icon = r.status === "overdue" ? pc3.red("!!!") : r.status === "today" ? pc3.yellow("(!)") : pc3.dim("( )");
2945
+ const due = r.dueAt ? ` ${pc3.dim(`due: ${new Date(r.dueAt).toLocaleString()}`)}` : "";
2946
+ lines.push(` ${icon} ${r.content}${due} ${pc3.dim(`[${r.status}]`)}`);
2947
+ }
2948
+ return { handled: true, output: lines.join("\n") };
2949
+ } catch (err) {
2950
+ return { handled: true, output: pc3.red(`Reminder error: ${err instanceof Error ? err.message : String(err)}`) };
2951
+ }
2952
+ }
2953
+ if (action === "help") {
2954
+ return { handled: true, output: [
2955
+ pc3.bold("Reminder commands:"),
2956
+ ` ${pc3.cyan("/reminder")} List all reminders`,
2957
+ ` ${pc3.cyan("/reminder set")} <text> Create a reminder [--due 1h|2d|1w|date]`,
2958
+ ` ${pc3.cyan("/reminder check")} Show overdue/upcoming`,
2959
+ ` ${pc3.cyan("/reminder done")} <id> Mark as completed`
2960
+ ].join("\n") };
2961
+ }
2962
+ return { handled: true, output: pc3.yellow(`Unknown action: /reminder ${action}. Try /reminder --help`) };
2963
+ }
2569
2964
  var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
2570
2965
  "quit",
2571
2966
  "exit",
@@ -2587,8 +2982,8 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
2587
2982
  "decisions",
2588
2983
  "export",
2589
2984
  "debug",
2590
- "update-config",
2591
- "reconfig",
2985
+ "reset",
2986
+ "reminder",
2592
2987
  "update",
2593
2988
  "upgrade",
2594
2989
  "plan",
@@ -2639,9 +3034,8 @@ async function handleCommand(input, ctx) {
2639
3034
  return handleExportCommand();
2640
3035
  case "debug":
2641
3036
  return handleDebugCommand();
2642
- case "update-config":
2643
- case "reconfig":
2644
- return handleReconfig();
3037
+ case "reset":
3038
+ return handleReset(action);
2645
3039
  case "plan":
2646
3040
  return handlePlanCommand(action, args);
2647
3041
  case "profile":
@@ -2650,6 +3044,8 @@ async function handleCommand(input, ctx) {
2650
3044
  return handleDelegateCommand(action, args, ctx);
2651
3045
  case "team":
2652
3046
  return handleTeamCommand(action, args, ctx);
3047
+ case "reminder":
3048
+ return handleReminderCommand(action, args);
2653
3049
  case "update":
2654
3050
  case "upgrade":
2655
3051
  return handleUpdate();
@@ -2661,8 +3057,8 @@ async function handleCommand(input, ctx) {
2661
3057
  // src/hooks.ts
2662
3058
  import pc4 from "picocolors";
2663
3059
  import * as p from "@clack/prompts";
2664
- import fs9 from "fs";
2665
- import path9 from "path";
3060
+ import fs10 from "fs";
3061
+ import path10 from "path";
2666
3062
 
2667
3063
  // src/personality.ts
2668
3064
  var FRUSTRATION_SIGNALS = [
@@ -2865,16 +3261,18 @@ async function onSessionStart(ctx) {
2865
3261
  let firstRun = false;
2866
3262
  let resumeTopic;
2867
3263
  const visibleReminders = [];
2868
- try {
2869
- isHookCall = true;
2870
- const recallResult = await ctx.mcpManager.callTool("memory_recall", { query: "*", limit: 1 });
2871
- if (!recallResult || recallResult.startsWith("Error") || recallResult.includes("No memories found")) {
3264
+ if (!isMemoryInitialized()) {
3265
+ firstRun = false;
3266
+ } else {
3267
+ try {
3268
+ isHookCall = true;
3269
+ const recallResult = await memoryRecall("*", { limit: 1 });
3270
+ firstRun = recallResult.total === 0;
3271
+ } catch {
2872
3272
  firstRun = true;
3273
+ } finally {
3274
+ isHookCall = false;
2873
3275
  }
2874
- } catch {
2875
- firstRun = true;
2876
- } finally {
2877
- isHookCall = false;
2878
3276
  }
2879
3277
  if (firstRun) {
2880
3278
  contextInjection = `<first-session>
@@ -2900,9 +3298,9 @@ ${contextInjection}`;
2900
3298
  if (ctx.config.memoryRecall) {
2901
3299
  try {
2902
3300
  isHookCall = true;
2903
- const result = await ctx.mcpManager.callTool("memory_context", { topic: "session context" });
2904
- if (result && !result.startsWith("Error")) {
2905
- greeting += result;
3301
+ const contextResult = await memoryContext("session context");
3302
+ if (contextResult.memoriesUsed > 0) {
3303
+ greeting += contextResult.text;
2906
3304
  }
2907
3305
  } catch (err) {
2908
3306
  log.warn("hooks", "memory_context recall failed", err);
@@ -2933,12 +3331,12 @@ ${contextInjection}`;
2933
3331
  else greeting = timeContext;
2934
3332
  try {
2935
3333
  isHookCall = true;
2936
- const reminderResult = await ctx.mcpManager.callTool("reminder_check", {});
2937
- if (reminderResult && !reminderResult.startsWith("Error") && !reminderResult.includes("No pending")) {
2938
- greeting += "\n\n<pending-reminders>\n" + reminderResult + "\n</pending-reminders>";
2939
- const lines = reminderResult.split("\n").filter((l) => l.trim().length > 0);
2940
- for (const line of lines) {
2941
- visibleReminders.push(line.trim());
3334
+ const reminders = reminderCheck();
3335
+ if (reminders.length > 0) {
3336
+ const reminderText = reminders.map((r) => r.content).join("\n");
3337
+ greeting += "\n\n<pending-reminders>\n" + reminderText + "\n</pending-reminders>";
3338
+ for (const r of reminders) {
3339
+ visibleReminders.push(r.content);
2942
3340
  }
2943
3341
  }
2944
3342
  } catch (err) {
@@ -3053,11 +3451,7 @@ async function onSessionEnd(ctx, messages, sessionId) {
3053
3451
  for (const msg of textMessages) {
3054
3452
  try {
3055
3453
  isHookCall = true;
3056
- await ctx.mcpManager.callTool("memory_log", {
3057
- session_id: sessionId,
3058
- role: msg.role,
3059
- content: msg.content.slice(0, 5e3)
3060
- });
3454
+ memoryLog(sessionId, msg.role, msg.content.slice(0, 5e3));
3061
3455
  } catch (err) {
3062
3456
  log.debug("hooks", "memory_log write failed for " + sessionId, err);
3063
3457
  } finally {
@@ -3085,10 +3479,10 @@ async function onSessionEnd(ctx, messages, sessionId) {
3085
3479
  }
3086
3480
  console.log(pc4.dim(` Saved ${textMessages.length} messages (session: ${sessionId})`));
3087
3481
  }
3088
- const projectContextPath = path9.join(process.cwd(), ".acore", "context.md");
3089
- if (fs9.existsSync(projectContextPath) && messages.length > 2) {
3482
+ const projectContextPath = path10.join(process.cwd(), ".acore", "context.md");
3483
+ if (fs10.existsSync(projectContextPath) && messages.length > 2) {
3090
3484
  try {
3091
- let contextContent = fs9.readFileSync(projectContextPath, "utf-8");
3485
+ let contextContent = fs10.readFileSync(projectContextPath, "utf-8");
3092
3486
  const now = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
3093
3487
  let lastUserMsg = "";
3094
3488
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -3106,7 +3500,7 @@ async function onSessionEnd(ctx, messages, sessionId) {
3106
3500
  - Recent decisions: [see memory]
3107
3501
  - Temp notes: [cleared]`;
3108
3502
  contextContent = contextContent.replace(sessionPattern, newSession);
3109
- fs9.writeFileSync(projectContextPath, contextContent, "utf-8");
3503
+ fs10.writeFileSync(projectContextPath, contextContent, "utf-8");
3110
3504
  log.debug("hooks", `Updated project context: ${projectContextPath}`);
3111
3505
  }
3112
3506
  } catch (err) {
@@ -3236,9 +3630,9 @@ ${summaryParts.slice(0, 20).join("\n")}
3236
3630
  }
3237
3631
 
3238
3632
  // src/skill-engine.ts
3239
- import fs10 from "fs";
3240
- import path10 from "path";
3241
- import os9 from "os";
3633
+ import fs11 from "fs";
3634
+ import path11 from "path";
3635
+ import os10 from "os";
3242
3636
  var SKILL_TRIGGERS = {
3243
3637
  testing: ["test", "spec", "coverage", "tdd", "jest", "vitest", "mocha", "assert", "mock", "stub", "fixture", "e2e", "integration test", "unit test"],
3244
3638
  "api-design": ["api", "endpoint", "rest", "graphql", "route", "controller", "middleware", "http", "request", "response", "status code", "pagination"],
@@ -3253,20 +3647,20 @@ var SKILL_TRIGGERS = {
3253
3647
  typescript: ["typescript", "type", "interface", "generic", "infer", "utility type", "zod", "discriminated union", "type guard", "as const"],
3254
3648
  accessibility: ["accessibility", "a11y", "aria", "screen reader", "wcag", "semantic html", "tab order", "focus", "contrast"]
3255
3649
  };
3256
- var LEVEL_FILE = path10.join(os9.homedir(), ".aman-agent", "skill-levels.json");
3650
+ var LEVEL_FILE = path11.join(os10.homedir(), ".aman-agent", "skill-levels.json");
3257
3651
  function loadSkillLevels() {
3258
3652
  try {
3259
- if (fs10.existsSync(LEVEL_FILE)) {
3260
- return JSON.parse(fs10.readFileSync(LEVEL_FILE, "utf-8"));
3653
+ if (fs11.existsSync(LEVEL_FILE)) {
3654
+ return JSON.parse(fs11.readFileSync(LEVEL_FILE, "utf-8"));
3261
3655
  }
3262
3656
  } catch {
3263
3657
  }
3264
3658
  return {};
3265
3659
  }
3266
3660
  function saveSkillLevels(levels) {
3267
- const dir = path10.dirname(LEVEL_FILE);
3268
- if (!fs10.existsSync(dir)) fs10.mkdirSync(dir, { recursive: true });
3269
- fs10.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
3661
+ const dir = path11.dirname(LEVEL_FILE);
3662
+ if (!fs11.existsSync(dir)) fs11.mkdirSync(dir, { recursive: true });
3663
+ fs11.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
3270
3664
  }
3271
3665
  function computeLevel(activations) {
3272
3666
  if (activations >= 50) return { level: 5, label: "Expert" };
@@ -3644,7 +4038,7 @@ function parseExtractionResult(raw) {
3644
4038
  return [];
3645
4039
  }
3646
4040
  }
3647
- async function extractMemories(userMessage, assistantResponse, client, mcpManager, state) {
4041
+ async function extractMemories(userMessage, assistantResponse, client, state) {
3648
4042
  if (!shouldExtract(assistantResponse, state.turnsSinceLastExtraction, state.lastExtractionCount)) {
3649
4043
  state.turnsSinceLastExtraction++;
3650
4044
  return 0;
@@ -3668,24 +4062,18 @@ Assistant: ${assistantResponse.slice(0, 2e3)}`;
3668
4062
  let stored = 0;
3669
4063
  for (const candidate of candidates) {
3670
4064
  try {
3671
- const existing = await mcpManager.callTool("memory_recall", {
3672
- query: candidate.content,
3673
- limit: 1
3674
- });
3675
- if (existing && !existing.startsWith("Error")) {
3676
- try {
3677
- const parsed = JSON.parse(existing);
3678
- if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].score > 0.85) {
3679
- log.debug("extractor", "Skipping duplicate: " + candidate.content);
3680
- continue;
3681
- }
3682
- } catch {
4065
+ const existing = await memoryRecall(candidate.content, { limit: 1 });
4066
+ if (existing.total > 0 && existing.memories.length > 0) {
4067
+ const topScore = existing.memories[0]?.score;
4068
+ if (topScore && topScore > 0.85) {
4069
+ log.debug("extractor", "Skipping duplicate: " + candidate.content);
4070
+ continue;
3683
4071
  }
3684
4072
  }
3685
4073
  } catch {
3686
4074
  }
3687
4075
  try {
3688
- await mcpManager.callTool("memory_store", {
4076
+ await memoryStore({
3689
4077
  content: candidate.content,
3690
4078
  type: candidate.type,
3691
4079
  tags: candidate.tags,
@@ -3858,7 +4246,7 @@ var BackgroundTaskManager = class {
3858
4246
  // src/errors.ts
3859
4247
  var ERROR_MAPPINGS = [
3860
4248
  { pattern: /rate.?limit|429/i, message: "Rate limited. I'll retry automatically." },
3861
- { pattern: /401|unauthorized/i, message: "API key invalid. Run /reconfig to fix." },
4249
+ { pattern: /401|unauthorized/i, message: "API key invalid. Run /reset config to fix." },
3862
4250
  { pattern: /403|forbidden/i, message: "API key doesn't have access to this model. Try a different model with --model." },
3863
4251
  { pattern: /fetch failed|network/i, message: "Network error. Check your internet connection." },
3864
4252
  { pattern: /ECONNREFUSED/i, message: "Can't reach the API. Are you behind a proxy or firewall?" },
@@ -3876,9 +4264,9 @@ function humanizeError(message) {
3876
4264
  }
3877
4265
 
3878
4266
  // src/hints.ts
3879
- import fs11 from "fs";
3880
- import path11 from "path";
3881
- import os10 from "os";
4267
+ import fs12 from "fs";
4268
+ import path12 from "path";
4269
+ import os11 from "os";
3882
4270
  var HINTS = [
3883
4271
  {
3884
4272
  id: "eval",
@@ -3916,11 +4304,11 @@ function getHint(state, ctx) {
3916
4304
  }
3917
4305
  return null;
3918
4306
  }
3919
- var HINTS_FILE = path11.join(os10.homedir(), ".aman-agent", "hints-seen.json");
4307
+ var HINTS_FILE = path12.join(os11.homedir(), ".aman-agent", "hints-seen.json");
3920
4308
  function loadShownHints() {
3921
4309
  try {
3922
- if (fs11.existsSync(HINTS_FILE)) {
3923
- const data = JSON.parse(fs11.readFileSync(HINTS_FILE, "utf-8"));
4310
+ if (fs12.existsSync(HINTS_FILE)) {
4311
+ const data = JSON.parse(fs12.readFileSync(HINTS_FILE, "utf-8"));
3924
4312
  return new Set(Array.isArray(data) ? data : []);
3925
4313
  }
3926
4314
  } catch {
@@ -3929,31 +4317,27 @@ function loadShownHints() {
3929
4317
  }
3930
4318
  function saveShownHints(shown) {
3931
4319
  try {
3932
- const dir = path11.dirname(HINTS_FILE);
3933
- fs11.mkdirSync(dir, { recursive: true });
3934
- fs11.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
4320
+ const dir = path12.dirname(HINTS_FILE);
4321
+ fs12.mkdirSync(dir, { recursive: true });
4322
+ fs12.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
3935
4323
  } catch {
3936
4324
  }
3937
4325
  }
3938
4326
 
3939
4327
  // src/agent.ts
3940
4328
  marked.use(markedTerminal());
3941
- async function recallForMessage(input, mcpManager) {
4329
+ async function recallForMessage(input) {
3942
4330
  try {
3943
- const result = await mcpManager.callTool("memory_recall", {
3944
- query: input,
3945
- limit: 5,
3946
- compact: true
3947
- });
3948
- if (!result || result.startsWith("Error") || result.includes("No memories found")) {
4331
+ const result = await memoryRecall(input, { limit: 5, compact: true });
4332
+ if (result.total === 0) {
3949
4333
  return null;
3950
4334
  }
3951
- const tokenEstimate = Math.round(result.split(/\s+/).filter(Boolean).length * 1.3);
4335
+ const tokenEstimate = result.tokenEstimate ?? Math.round(result.text.split(/\s+/).filter(Boolean).length * 1.3);
3952
4336
  return {
3953
4337
  text: `
3954
4338
 
3955
4339
  <relevant-memories>
3956
- ${result}
4340
+ ${result.text}
3957
4341
  </relevant-memories>`,
3958
4342
  tokenEstimate
3959
4343
  };
@@ -4124,9 +4508,9 @@ Type a message, ${pc6.dim("/help")} for commands, or ${pc6.dim("/quit")} to exit
4124
4508
  }
4125
4509
  if (cmdResult.exportConversation) {
4126
4510
  try {
4127
- const exportDir = path12.join(os11.homedir(), ".aman-agent", "exports");
4128
- fs12.mkdirSync(exportDir, { recursive: true });
4129
- const exportPath = path12.join(exportDir, `${sessionId}.md`);
4511
+ const exportDir = path13.join(os12.homedir(), ".aman-agent", "exports");
4512
+ fs13.mkdirSync(exportDir, { recursive: true });
4513
+ const exportPath = path13.join(exportDir, `${sessionId}.md`);
4130
4514
  const lines = [
4131
4515
  `# Conversation \u2014 ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
4132
4516
  `**Model:** ${model}`,
@@ -4140,16 +4524,16 @@ Type a message, ${pc6.dim("/help")} for commands, or ${pc6.dim("/quit")} to exit
4140
4524
  lines.push(`${label} ${msg.content}`, "");
4141
4525
  }
4142
4526
  }
4143
- fs12.writeFileSync(exportPath, lines.join("\n"), "utf-8");
4527
+ fs13.writeFileSync(exportPath, lines.join("\n"), "utf-8");
4144
4528
  console.log(pc6.green(`Exported to ${exportPath}`));
4145
4529
  } catch {
4146
4530
  console.log(pc6.red("Failed to export conversation."));
4147
4531
  }
4148
4532
  continue;
4149
4533
  }
4150
- if (cmdResult.saveConversation && mcpManager) {
4534
+ if (cmdResult.saveConversation) {
4151
4535
  try {
4152
- await saveConversationToMemory(mcpManager, messages, sessionId);
4536
+ await saveConversationToMemory(messages, sessionId);
4153
4537
  console.log(pc6.green("Conversation saved to memory."));
4154
4538
  } catch {
4155
4539
  console.log(pc6.red("Failed to save conversation."));
@@ -4266,25 +4650,25 @@ ${knowledgeItem.content}
4266
4650
  for (const match of filePathMatches) {
4267
4651
  let filePath = match[1];
4268
4652
  if (filePath.startsWith("~/")) {
4269
- filePath = path12.join(os11.homedir(), filePath.slice(2));
4653
+ filePath = path13.join(os12.homedir(), filePath.slice(2));
4270
4654
  }
4271
- if (!fs12.existsSync(filePath) || !fs12.statSync(filePath).isFile()) continue;
4272
- const ext = path12.extname(filePath).toLowerCase();
4655
+ if (!fs13.existsSync(filePath) || !fs13.statSync(filePath).isFile()) continue;
4656
+ const ext = path13.extname(filePath).toLowerCase();
4273
4657
  if (imageExts.has(ext)) {
4274
4658
  try {
4275
- const stat = fs12.statSync(filePath);
4659
+ const stat = fs13.statSync(filePath);
4276
4660
  if (stat.size > maxImageBytes) {
4277
- process.stdout.write(pc6.yellow(` [skipped: ${path12.basename(filePath)} \u2014 exceeds 20MB limit]
4661
+ process.stdout.write(pc6.yellow(` [skipped: ${path13.basename(filePath)} \u2014 exceeds 20MB limit]
4278
4662
  `));
4279
4663
  continue;
4280
4664
  }
4281
- const data = fs12.readFileSync(filePath).toString("base64");
4665
+ const data = fs13.readFileSync(filePath).toString("base64");
4282
4666
  const mediaType = mimeMap[ext] || "image/png";
4283
4667
  imageBlocks.push({
4284
4668
  type: "image",
4285
4669
  source: { type: "base64", media_type: mediaType, data }
4286
4670
  });
4287
- process.stdout.write(pc6.dim(` [attached image: ${path12.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
4671
+ process.stdout.write(pc6.dim(` [attached image: ${path13.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
4288
4672
  `));
4289
4673
  } catch {
4290
4674
  process.stdout.write(pc6.dim(` [could not read image: ${filePath}]
@@ -4292,7 +4676,7 @@ ${knowledgeItem.content}
4292
4676
  }
4293
4677
  } else if (textExts.has(ext) || ext === "") {
4294
4678
  try {
4295
- const content = fs12.readFileSync(filePath, "utf-8");
4679
+ const content = fs13.readFileSync(filePath, "utf-8");
4296
4680
  const maxChars = 5e4;
4297
4681
  const trimmed = content.length > maxChars ? content.slice(0, maxChars) + `
4298
4682
 
@@ -4302,7 +4686,7 @@ ${knowledgeItem.content}
4302
4686
  <file path="${filePath}" size="${content.length} chars">
4303
4687
  ${trimmed}
4304
4688
  </file>`;
4305
- process.stdout.write(pc6.dim(` [attached: ${path12.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
4689
+ process.stdout.write(pc6.dim(` [attached: ${path13.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
4306
4690
  `));
4307
4691
  } catch {
4308
4692
  process.stdout.write(pc6.dim(` [could not read: ${filePath}]
@@ -4311,7 +4695,7 @@ ${trimmed}
4311
4695
  } else if (docExts.has(ext)) {
4312
4696
  if (mcpManager) {
4313
4697
  try {
4314
- process.stdout.write(pc6.dim(` [converting: ${path12.basename(filePath)}...]
4698
+ process.stdout.write(pc6.dim(` [converting: ${path13.basename(filePath)}...]
4315
4699
  `));
4316
4700
  const converted = await mcpManager.callTool("doc_convert", { path: filePath });
4317
4701
  if (converted && !converted.startsWith("Error") && !converted.includes("Could not convert")) {
@@ -4320,7 +4704,7 @@ ${trimmed}
4320
4704
  <file path="${filePath}" format="${ext}">
4321
4705
  ${converted.slice(0, 5e4)}
4322
4706
  </file>`;
4323
- process.stdout.write(pc6.dim(` [attached: ${path12.basename(filePath)} (converted from ${ext})]
4707
+ process.stdout.write(pc6.dim(` [attached: ${path13.basename(filePath)} (converted from ${ext})]
4324
4708
  `));
4325
4709
  } else {
4326
4710
  textContent += `
@@ -4332,7 +4716,7 @@ ${converted}
4332
4716
  `));
4333
4717
  }
4334
4718
  } catch {
4335
- process.stdout.write(pc6.dim(` [could not convert: ${path12.basename(filePath)}]
4719
+ process.stdout.write(pc6.dim(` [could not convert: ${path13.basename(filePath)}]
4336
4720
  `));
4337
4721
  }
4338
4722
  } else {
@@ -4387,11 +4771,11 @@ ${converted}
4387
4771
  }
4388
4772
  let augmentedSystemPrompt = activeSystemPrompt;
4389
4773
  let memoryTokens = 0;
4390
- if (mcpManager) {
4391
- const recall = await recallForMessage(input, mcpManager);
4392
- if (recall) {
4393
- augmentedSystemPrompt = activeSystemPrompt + recall.text;
4394
- memoryTokens = recall.tokenEstimate;
4774
+ {
4775
+ const recall2 = await recallForMessage(input);
4776
+ if (recall2) {
4777
+ augmentedSystemPrompt = activeSystemPrompt + recall2.text;
4778
+ memoryTokens = recall2.tokenEstimate;
4395
4779
  }
4396
4780
  }
4397
4781
  const userTurnCount = messages.filter((m) => m.role === "user").length;
@@ -4493,12 +4877,10 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
4493
4877
  const result = await mcpManager.callTool(toolUse.name, toolUse.input);
4494
4878
  const skipLogging = ["memory_log", "memory_recall", "memory_context", "memory_detail", "reminder_check"].includes(toolUse.name);
4495
4879
  if (!skipLogging) {
4496
- mcpManager.callTool("memory_log", {
4497
- session_id: sessionId,
4498
- role: "system",
4499
- content: `[tool:${toolUse.name}] input=${JSON.stringify(toolUse.input).slice(0, 500)} result=${result.slice(0, 500)}`
4500
- }).catch(() => {
4501
- });
4880
+ try {
4881
+ memoryLog(sessionId, "system", `[tool:${toolUse.name}] input=${JSON.stringify(toolUse.input).slice(0, 500)} result=${result.slice(0, 500)}`);
4882
+ } catch {
4883
+ }
4502
4884
  }
4503
4885
  return {
4504
4886
  type: "tool_result",
@@ -4523,14 +4905,13 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
4523
4905
  const footerDivider = "\u2500".repeat(Math.min(process.stdout.columns || 60, 60) - footer.length - 1);
4524
4906
  process.stdout.write(pc6.dim(` ${footerDivider}${footer}
4525
4907
  `));
4526
- if (mcpManager && hooksConfig?.extractMemories) {
4908
+ if (hooksConfig?.extractMemories) {
4527
4909
  const assistantText = typeof response.message.content === "string" ? response.message.content : response.message.content.filter((b) => b.type === "text").map((b) => "text" in b ? b.text : "").join("");
4528
4910
  if (assistantText) {
4529
4911
  const count = await extractMemories(
4530
4912
  input,
4531
4913
  assistantText,
4532
4914
  client,
4533
- mcpManager,
4534
4915
  extractorState
4535
4916
  );
4536
4917
  if (count > 0) {
@@ -4543,7 +4924,7 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
4543
4924
  }
4544
4925
  if (hooksConfig?.featureHints) {
4545
4926
  hintState.turnCount++;
4546
- const hasWorkflows = fs12.existsSync(path12.join(os11.homedir(), ".aflow", "flow.md"));
4927
+ const hasWorkflows = fs13.existsSync(path13.join(os12.homedir(), ".aflow", "flow.md"));
4547
4928
  const memoryCount = memoryTokens > 0 ? Math.floor(memoryTokens / 5) : 0;
4548
4929
  const hint = getHint(hintState, { hasWorkflows, memoryCount });
4549
4930
  if (hint) {
@@ -4560,16 +4941,12 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
4560
4941
  }
4561
4942
  }
4562
4943
  }
4563
- async function saveConversationToMemory(mcpManager, messages, sessionId) {
4944
+ async function saveConversationToMemory(messages, sessionId) {
4564
4945
  const recentMessages = messages.slice(-50);
4565
4946
  for (const msg of recentMessages) {
4566
4947
  if (typeof msg.content !== "string") continue;
4567
4948
  try {
4568
- await mcpManager.callTool("memory_log", {
4569
- session_id: sessionId,
4570
- role: msg.role,
4571
- content: msg.content.slice(0, 5e3)
4572
- });
4949
+ memoryLog(sessionId, msg.role, msg.content.slice(0, 5e3));
4573
4950
  } catch (err) {
4574
4951
  log.debug("agent", "memory_log write failed", err);
4575
4952
  }
@@ -4577,9 +4954,9 @@ async function saveConversationToMemory(mcpManager, messages, sessionId) {
4577
4954
  }
4578
4955
 
4579
4956
  // src/index.ts
4580
- import fs13 from "fs";
4581
- import path13 from "path";
4582
- import os12 from "os";
4957
+ import fs14 from "fs";
4958
+ import path14 from "path";
4959
+ import os13 from "os";
4583
4960
 
4584
4961
  // src/presets.ts
4585
4962
  var PRESETS = {
@@ -4688,9 +5065,9 @@ ${wfSections}`;
4688
5065
 
4689
5066
  // src/index.ts
4690
5067
  async function autoDetectConfig() {
4691
- const reconfigMarker = path13.join(os12.homedir(), ".aman-agent", ".reconfig");
4692
- if (fs13.existsSync(reconfigMarker)) {
4693
- fs13.unlinkSync(reconfigMarker);
5068
+ const reconfigMarker = path14.join(os13.homedir(), ".aman-agent", ".reconfig");
5069
+ if (fs14.existsSync(reconfigMarker)) {
5070
+ fs14.unlinkSync(reconfigMarker);
4694
5071
  return null;
4695
5072
  }
4696
5073
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
@@ -4719,11 +5096,11 @@ async function autoDetectConfig() {
4719
5096
  return null;
4720
5097
  }
4721
5098
  function bootstrapEcosystem() {
4722
- const home2 = os12.homedir();
4723
- const corePath = path13.join(home2, ".acore", "core.md");
4724
- if (fs13.existsSync(corePath)) return false;
4725
- fs13.mkdirSync(path13.join(home2, ".acore"), { recursive: true });
4726
- fs13.writeFileSync(corePath, [
5099
+ const home2 = os13.homedir();
5100
+ const corePath = path14.join(home2, ".acore", "core.md");
5101
+ if (fs14.existsSync(corePath)) return false;
5102
+ fs14.mkdirSync(path14.join(home2, ".acore"), { recursive: true });
5103
+ fs14.writeFileSync(corePath, [
4727
5104
  "# Aman",
4728
5105
  "",
4729
5106
  "## Personality",
@@ -4735,11 +5112,11 @@ function bootstrapEcosystem() {
4735
5112
  "## Session",
4736
5113
  "_New companion \u2014 no prior sessions._"
4737
5114
  ].join("\n"), "utf-8");
4738
- const rulesDir = path13.join(home2, ".arules");
4739
- const rulesPath = path13.join(rulesDir, "rules.md");
4740
- if (!fs13.existsSync(rulesPath)) {
4741
- fs13.mkdirSync(rulesDir, { recursive: true });
4742
- fs13.writeFileSync(rulesPath, [
5115
+ const rulesDir = path14.join(home2, ".arules");
5116
+ const rulesPath = path14.join(rulesDir, "rules.md");
5117
+ if (!fs14.existsSync(rulesPath)) {
5118
+ fs14.mkdirSync(rulesDir, { recursive: true });
5119
+ fs14.writeFileSync(rulesPath, [
4743
5120
  "# Guardrails",
4744
5121
  "",
4745
5122
  "## safety",
@@ -4754,7 +5131,7 @@ function bootstrapEcosystem() {
4754
5131
  return true;
4755
5132
  }
4756
5133
  var program = new Command();
4757
- program.name("aman-agent").description("Your AI companion, running locally").version("0.1.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
5134
+ program.name("aman-agent").description("Your AI companion, running locally").version("0.17.1").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
4758
5135
  p2.intro(pc7.bold("aman agent") + pc7.dim(" \u2014 your AI companion"));
4759
5136
  let config = loadConfig();
4760
5137
  if (!config) {
@@ -4763,7 +5140,7 @@ program.name("aman-agent").description("Your AI companion, running locally").ver
4763
5140
  config = detected;
4764
5141
  const providerLabel = detected.provider === "anthropic" ? "Anthropic API key" : detected.provider === "openai" ? "OpenAI API key" : "Ollama";
4765
5142
  p2.log.success(`Auto-detected ${providerLabel}. Using ${pc7.bold(detected.model)}.`);
4766
- p2.log.info(pc7.dim("Change anytime with /reconfig"));
5143
+ p2.log.info(pc7.dim("Change anytime with /reset config"));
4767
5144
  saveConfig(config);
4768
5145
  } else {
4769
5146
  p2.log.info("First-time setup \u2014 configure your LLM connection.");
@@ -4881,11 +5258,30 @@ program.name("aman-agent").description("Your AI companion, running locally").ver
4881
5258
  }
4882
5259
  }
4883
5260
  const aiName = getProfileAiName(profile);
5261
+ try {
5262
+ await initMemory();
5263
+ } catch (err) {
5264
+ p2.log.warning(`Memory initialization failed: ${err instanceof Error ? err.message : String(err)}`);
5265
+ }
5266
+ if (isMemoryInitialized()) {
5267
+ const memSpinner = p2.spinner();
5268
+ memSpinner.start("Consolidating memory");
5269
+ try {
5270
+ const report = memoryConsolidate();
5271
+ memSpinner.stop("Memory consolidated");
5272
+ if (report.merged > 0 || report.pruned > 0 || report.promoted > 0) {
5273
+ p2.log.info(
5274
+ `Memory health: ${report.healthScore ?? "?"}% ` + pc7.dim(`(merged ${report.merged}, pruned ${report.pruned}, promoted ${report.promoted})`)
5275
+ );
5276
+ }
5277
+ } catch {
5278
+ memSpinner.stop("Memory consolidation skipped");
5279
+ }
5280
+ }
4884
5281
  const mcpManager = new McpManager();
4885
5282
  const mcpSpinner = p2.spinner();
4886
5283
  mcpSpinner.start("Connecting to MCP servers");
4887
5284
  await mcpManager.connect("aman", "npx", ["-y", "@aman_asmuei/aman-mcp"]);
4888
- await mcpManager.connect("amem", "npx", ["-y", "@aman_asmuei/amem"]);
4889
5285
  if (config.mcpServers) {
4890
5286
  for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
4891
5287
  if (name === "aman" || name === "amem") continue;
@@ -4896,33 +5292,9 @@ program.name("aman-agent").description("Your AI companion, running locally").ver
4896
5292
  mcpSpinner.stop("MCP connected");
4897
5293
  if (mcpTools.length > 0) {
4898
5294
  p2.log.success(`${mcpTools.length} MCP tools available`);
4899
- if (mcpTools.some((t) => t.name === "memory_consolidate")) {
4900
- const memSpinner = p2.spinner();
4901
- memSpinner.start("Consolidating memory");
4902
- try {
4903
- const consolidateResult = await mcpManager.callTool("memory_consolidate", { dry_run: false });
4904
- if (consolidateResult && !consolidateResult.startsWith("Error")) {
4905
- try {
4906
- const report = JSON.parse(consolidateResult);
4907
- memSpinner.stop("Memory consolidated");
4908
- if (report.merged > 0 || report.pruned > 0 || report.promoted > 0) {
4909
- p2.log.info(
4910
- `Memory health: ${report.healthScore ?? "?"}% ` + pc7.dim(`(merged ${report.merged}, pruned ${report.pruned}, promoted ${report.promoted})`)
4911
- );
4912
- }
4913
- } catch {
4914
- memSpinner.stop("Memory consolidated");
4915
- }
4916
- } else {
4917
- memSpinner.stop("Memory consolidated");
4918
- }
4919
- } catch {
4920
- memSpinner.stop("Memory consolidation skipped");
4921
- }
4922
- }
4923
5295
  } else {
4924
5296
  p2.log.info(
4925
- "No MCP tools connected (install aman-mcp or amem for tool support)"
5297
+ "No MCP tools connected (install aman-mcp for tool support)"
4926
5298
  );
4927
5299
  }
4928
5300
  const toolDefs = mcpTools.map((t) => ({
@@ -4971,19 +5343,19 @@ program.command("init").description("Set up your AI companion with a guided wiza
4971
5343
  });
4972
5344
  if (p2.isCancel(preset)) process.exit(0);
4973
5345
  const result = applyPreset(preset, name || "Aman");
4974
- const home2 = os12.homedir();
4975
- fs13.mkdirSync(path13.join(home2, ".acore"), { recursive: true });
4976
- fs13.writeFileSync(path13.join(home2, ".acore", "core.md"), result.coreMd, "utf-8");
5346
+ const home2 = os13.homedir();
5347
+ fs14.mkdirSync(path14.join(home2, ".acore"), { recursive: true });
5348
+ fs14.writeFileSync(path14.join(home2, ".acore", "core.md"), result.coreMd, "utf-8");
4977
5349
  p2.log.success(`Identity created \u2014 ${PRESETS[preset].identity.personality.split(".")[0].toLowerCase()}`);
4978
5350
  if (result.rulesMd) {
4979
- fs13.mkdirSync(path13.join(home2, ".arules"), { recursive: true });
4980
- fs13.writeFileSync(path13.join(home2, ".arules", "rules.md"), result.rulesMd, "utf-8");
5351
+ fs14.mkdirSync(path14.join(home2, ".arules"), { recursive: true });
5352
+ fs14.writeFileSync(path14.join(home2, ".arules", "rules.md"), result.rulesMd, "utf-8");
4981
5353
  const ruleCount = (result.rulesMd.match(/^- /gm) || []).length;
4982
5354
  p2.log.success(`${ruleCount} rules set`);
4983
5355
  }
4984
5356
  if (result.flowMd) {
4985
- fs13.mkdirSync(path13.join(home2, ".aflow"), { recursive: true });
4986
- fs13.writeFileSync(path13.join(home2, ".aflow", "flow.md"), result.flowMd, "utf-8");
5357
+ fs14.mkdirSync(path14.join(home2, ".aflow"), { recursive: true });
5358
+ fs14.writeFileSync(path14.join(home2, ".aflow", "flow.md"), result.flowMd, "utf-8");
4987
5359
  const wfCount = (result.flowMd.match(/^## /gm) || []).length;
4988
5360
  p2.log.success(`${wfCount} workflow${wfCount > 1 ? "s" : ""} added`);
4989
5361
  }