@memories.sh/cli 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +113 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ import { Command as Command29 } from "commander";
33
33
  // src/commands/init.ts
34
34
  import { Command } from "commander";
35
35
  import chalk3 from "chalk";
36
- import { confirm } from "@inquirer/prompts";
36
+ import { confirm, checkbox } from "@inquirer/prompts";
37
37
 
38
38
  // src/lib/auth.ts
39
39
  import { readFile, writeFile, mkdir, unlink } from "fs/promises";
@@ -121,6 +121,9 @@ var MEMORIES_MCP_CONFIG = {
121
121
  command: "npx",
122
122
  args: ["-y", "@memories.sh/cli", "serve"]
123
123
  };
124
+ function getAllTools() {
125
+ return [...TOOLS];
126
+ }
124
127
  function detectTools(cwd = process.cwd()) {
125
128
  const home = homedir2();
126
129
  const detected = [];
@@ -271,10 +274,32 @@ var initCommand = new Command("init").description("Initialize memories - set up
271
274
  success("Global scope (rules apply to all projects)");
272
275
  }
273
276
  step(3, 4, "Detecting AI coding tools...");
274
- const detected = detectTools(cwd);
277
+ let detected = detectTools(cwd);
275
278
  if (detected.length === 0) {
276
- dim("No AI coding tools detected (.cursor/, .claude/, .windsurf/, .vscode/)");
277
- dim("MCP will work with any tool that supports it.");
279
+ dim("No AI coding tools auto-detected.");
280
+ if (!opts.skipMcp) {
281
+ const allTools = getAllTools();
282
+ const selected = await checkbox({
283
+ message: "Which tools do you want to configure?",
284
+ choices: allTools.map((t) => ({
285
+ name: t.name,
286
+ value: t,
287
+ checked: false
288
+ }))
289
+ });
290
+ if (selected.length > 0) {
291
+ detected = selected.map((tool) => ({
292
+ tool,
293
+ hasConfig: false,
294
+ hasMcp: false,
295
+ hasInstructions: false,
296
+ globalConfig: false
297
+ }));
298
+ }
299
+ }
300
+ }
301
+ if (detected.length === 0) {
302
+ dim("No tools selected. MCP will work with any tool that supports it.");
278
303
  } else {
279
304
  for (const d of detected) {
280
305
  const scope = d.globalConfig ? chalk3.dim(" [global]") : "";
@@ -1238,6 +1263,8 @@ import { Command as Command11 } from "commander";
1238
1263
  // src/mcp/index.ts
1239
1264
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
1240
1265
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1266
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1267
+ import { createServer } from "http";
1241
1268
  import { z } from "zod";
1242
1269
  var TYPE_LABELS2 = {
1243
1270
  rule: "\u{1F4CC} RULE",
@@ -1261,7 +1288,7 @@ function formatMemoriesSection(memories, title) {
1261
1288
  return `## ${title}
1262
1289
  ${memories.map(formatMemory4).join("\n")}`;
1263
1290
  }
1264
- async function startMcpServer() {
1291
+ async function createMcpServer() {
1265
1292
  const projectId = getProjectId();
1266
1293
  const server = new McpServer({
1267
1294
  name: "memories",
@@ -1619,19 +1646,93 @@ Find the memory ID first with search_memories or list_memories.`,
1619
1646
  }
1620
1647
  }
1621
1648
  );
1649
+ return server;
1650
+ }
1651
+ async function startMcpServer() {
1652
+ const server = await createMcpServer();
1622
1653
  const transport = new StdioServerTransport();
1623
1654
  await server.connect(transport);
1624
1655
  }
1656
+ async function startMcpHttpServer(options) {
1657
+ const { port, host, cors } = options;
1658
+ const server = await createMcpServer();
1659
+ const transport = new StreamableHTTPServerTransport({
1660
+ sessionIdGenerator: void 0
1661
+ // Stateless mode
1662
+ });
1663
+ await server.connect(transport);
1664
+ const httpServer = createServer(async (req, res) => {
1665
+ if (cors) {
1666
+ res.setHeader("Access-Control-Allow-Origin", "*");
1667
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
1668
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
1669
+ }
1670
+ if (req.method === "OPTIONS") {
1671
+ res.writeHead(204);
1672
+ res.end();
1673
+ return;
1674
+ }
1675
+ const url = new URL(req.url || "/", `http://${host}:${port}`);
1676
+ if (url.pathname === "/health") {
1677
+ res.writeHead(200, { "Content-Type": "application/json" });
1678
+ res.end(JSON.stringify({ status: "ok" }));
1679
+ return;
1680
+ }
1681
+ if (url.pathname === "/mcp" || url.pathname === "/") {
1682
+ try {
1683
+ let body = void 0;
1684
+ if (req.method === "POST") {
1685
+ const chunks = [];
1686
+ for await (const chunk of req) {
1687
+ chunks.push(chunk);
1688
+ }
1689
+ const rawBody = Buffer.concat(chunks).toString("utf-8");
1690
+ if (rawBody) {
1691
+ body = JSON.parse(rawBody);
1692
+ }
1693
+ }
1694
+ await transport.handleRequest(req, res, body);
1695
+ } catch (error2) {
1696
+ console.error("[memories] Error handling MCP request:", error2);
1697
+ res.writeHead(500, { "Content-Type": "application/json" });
1698
+ res.end(JSON.stringify({ error: "Internal server error" }));
1699
+ }
1700
+ return;
1701
+ }
1702
+ res.writeHead(404, { "Content-Type": "application/json" });
1703
+ res.end(JSON.stringify({ error: "Not found" }));
1704
+ });
1705
+ httpServer.listen(port, host);
1706
+ await new Promise(() => {
1707
+ });
1708
+ }
1625
1709
 
1626
1710
  // src/commands/serve.ts
1627
- var serveCommand = new Command11("serve").description("Start the MCP server (stdio transport)").action(async () => {
1711
+ var serveCommand = new Command11("serve").description("Start the MCP server").option("--sse", "Use SSE/HTTP transport instead of stdio (for web clients like v0)").option("-p, --port <port>", "Port for SSE server", "3030").option("--host <host>", "Host to bind to", "127.0.0.1").option("--cors", "Enable CORS for cross-origin requests").action(async (opts) => {
1628
1712
  const projectId = getProjectId();
1629
- if (projectId) {
1630
- console.error(`[memories] MCP server starting (project: ${projectId})`);
1713
+ if (opts.sse) {
1714
+ const port = parseInt(opts.port || "3030", 10);
1715
+ const host = opts.host || "127.0.0.1";
1716
+ console.log(`[memories] Starting MCP server with SSE transport`);
1717
+ console.log(`[memories] Listening on http://${host}:${port}`);
1718
+ if (projectId) {
1719
+ console.log(`[memories] Project: ${projectId}`);
1720
+ } else {
1721
+ console.log(`[memories] Global only (not in a git repo)`);
1722
+ }
1723
+ if (opts.cors) {
1724
+ console.log(`[memories] CORS enabled`);
1725
+ }
1726
+ console.log(`[memories] Connect v0 or other clients to: http://${host}:${port}/mcp`);
1727
+ await startMcpHttpServer({ port, host, cors: opts.cors });
1631
1728
  } else {
1632
- console.error("[memories] MCP server starting (global only - not in a git repo)");
1729
+ if (projectId) {
1730
+ console.error(`[memories] MCP server starting (project: ${projectId})`);
1731
+ } else {
1732
+ console.error("[memories] MCP server starting (global only - not in a git repo)");
1733
+ }
1734
+ await startMcpServer();
1633
1735
  }
1634
- await startMcpServer();
1635
1736
  });
1636
1737
 
1637
1738
  // src/commands/sync.ts
@@ -1803,7 +1904,7 @@ import { writeFile as writeFile5, readFile as readFile5, mkdir as mkdir4 } from
1803
1904
  import { existsSync as existsSync5, watch as fsWatch } from "fs";
1804
1905
  import { dirname as dirname2, resolve, join as join5 } from "path";
1805
1906
  import { homedir as homedir4 } from "os";
1806
- import { checkbox } from "@inquirer/prompts";
1907
+ import { checkbox as checkbox2 } from "@inquirer/prompts";
1807
1908
  var MARKER = "Generated by memories.sh";
1808
1909
  var VALID_TYPES6 = ["rule", "decision", "fact", "note"];
1809
1910
  function groupByType(memories) {
@@ -2045,7 +2146,7 @@ var generateCommand = new Command13("generate").description("Generate IDE rule/i
2045
2146
  generateCommand.outputHelp();
2046
2147
  return;
2047
2148
  }
2048
- const selected = await checkbox({
2149
+ const selected = await checkbox2({
2049
2150
  message: "Select targets to generate",
2050
2151
  choices: TARGETS.map((t) => ({
2051
2152
  name: `${t.name} ${chalk12.dim(`\u2192 ${t.defaultPath}`)}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memories.sh/cli",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "A local-first memory layer for AI coding agents — persistent context for Claude, Cursor, and more",
5
5
  "type": "module",
6
6
  "license": "MIT",