stackmem 1.0.16 → 1.0.18

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 (3) hide show
  1. package/dist/cli.js +35 -3
  2. package/package.json +1 -1
  3. package/src/cli.ts +41 -3
package/dist/cli.js CHANGED
@@ -353,7 +353,7 @@ async function confirmSupersede(oldId, newContent) {
353
353
  }
354
354
  async function cmdSave(project, type, content, force = false) {
355
355
  if (!MEMORY_TYPES.includes(type)) {
356
- fail(`Invalid type "${type}". Must be one of: ${MEMORY_TYPES.join(", ")}`);
356
+ fail(`Invalid memory type '${type}'. Valid types: decision, constraint, discovery, rejection.`);
357
357
  }
358
358
  const { data: existingRows, error: existingError } = await supabase
359
359
  .from("memories")
@@ -930,6 +930,24 @@ function registerMcpServer(distIndexPath) {
930
930
  nodeFs.writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2), "utf-8");
931
931
  console.log("stackmem MCP server registered with Claude Code.");
932
932
  }
933
+ const DEFAULT_GITIGNORE_CONTENT = `node_modules/
934
+ dist/
935
+ .env
936
+ .env.local
937
+ .DS_Store
938
+ *.log
939
+ coverage/
940
+ `;
941
+ // Returns true if the file was created, false if it already existed
942
+ // (and was left untouched).
943
+ function writeGitignore(resolvedPath) {
944
+ const gitignorePath = nodePath.join(resolvedPath, ".gitignore");
945
+ if (nodeFs.existsSync(gitignorePath)) {
946
+ return false;
947
+ }
948
+ nodeFs.writeFileSync(gitignorePath, DEFAULT_GITIGNORE_CONTENT, "utf-8");
949
+ return true;
950
+ }
933
951
  function writeClaudeMd(project, resolvedPath) {
934
952
  const claudeMdPath = nodePath.join(resolvedPath, "CLAUDE.md");
935
953
  if (nodeFs.existsSync(claudeMdPath)) {
@@ -1171,9 +1189,10 @@ async function cmdInit(project, targetPath) {
1171
1189
  const resolvedPath = nodePath.resolve(targetPath);
1172
1190
  const gitDir = nodePath.join(resolvedPath, ".git");
1173
1191
  if (!nodeFs.existsSync(gitDir)) {
1174
- console.error(`No git repo found at ${targetPath}`);
1192
+ console.error(`No git repo found at ${targetPath}. Run 'git init' first, then run 'cm init' again.`);
1175
1193
  process.exit(1);
1176
1194
  }
1195
+ const gitignoreCreated = writeGitignore(resolvedPath);
1177
1196
  const codingMemoryDir = nodePath.join(resolvedPath, ".coding-memory");
1178
1197
  nodeFs.mkdirSync(codingMemoryDir, { recursive: true });
1179
1198
  const hookLogicPath = nodePath.join(codingMemoryDir, "post-commit-hook.mjs");
@@ -1193,6 +1212,9 @@ async function cmdInit(project, targetPath) {
1193
1212
  const windsurfRulesWritten = writeWindsurfRules(resolvedPath, rulesContent);
1194
1213
  const backendOk = await verifyBackendConnection(project);
1195
1214
  console.log("");
1215
+ if (gitignoreCreated) {
1216
+ console.log("✓ .gitignore created");
1217
+ }
1196
1218
  console.log("✓ Git hook installed");
1197
1219
  console.log("✓ MCP server registered");
1198
1220
  console.log("✓ CLAUDE.md written");
@@ -1627,7 +1649,14 @@ async function main() {
1627
1649
  let explicitProject;
1628
1650
  let type;
1629
1651
  let rest;
1630
- if (MEMORY_TYPES.includes(positional[0])) {
1652
+ // Exactly two positional args can only mean <type> <content> with the
1653
+ // project omitted — an explicit project would need a third slot for
1654
+ // content, which wouldn't exist. Without this check, a typo'd type
1655
+ // (failing the MEMORY_TYPES.includes test below) used to fall into
1656
+ // the "explicit project" branch instead, shifting content out of
1657
+ // existence and surfacing a generic usage() dump instead of the
1658
+ // targeted invalid-type error.
1659
+ if (positional.length === 2 || MEMORY_TYPES.includes(positional[0])) {
1631
1660
  explicitProject = null;
1632
1661
  [type, ...rest] = positional;
1633
1662
  }
@@ -1635,6 +1664,9 @@ async function main() {
1635
1664
  explicitProject = positional[0] ?? null;
1636
1665
  [, type, ...rest] = positional;
1637
1666
  }
1667
+ if (type !== undefined && !MEMORY_TYPES.includes(type)) {
1668
+ fail(`Invalid memory type '${type}'. Valid types: decision, constraint, discovery, rejection.`);
1669
+ }
1638
1670
  if (!type || rest.length === 0)
1639
1671
  usage();
1640
1672
  const project = requireProject(explicitProject);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stackmem",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/cli.ts CHANGED
@@ -411,7 +411,7 @@ async function confirmSupersede(oldId: string, newContent: string): Promise<bool
411
411
 
412
412
  async function cmdSave(project: string, type: string, content: string, force = false) {
413
413
  if (!MEMORY_TYPES.includes(type as MemoryType)) {
414
- fail(`Invalid type "${type}". Must be one of: ${MEMORY_TYPES.join(", ")}`);
414
+ fail(`Invalid memory type '${type}'. Valid types: decision, constraint, discovery, rejection.`);
415
415
  }
416
416
 
417
417
 
@@ -1059,6 +1059,28 @@ function registerMcpServer(distIndexPath: string): void {
1059
1059
  console.log("stackmem MCP server registered with Claude Code.");
1060
1060
  }
1061
1061
 
1062
+ const DEFAULT_GITIGNORE_CONTENT = `node_modules/
1063
+ dist/
1064
+ .env
1065
+ .env.local
1066
+ .DS_Store
1067
+ *.log
1068
+ coverage/
1069
+ `;
1070
+
1071
+ // Returns true if the file was created, false if it already existed
1072
+ // (and was left untouched).
1073
+ function writeGitignore(resolvedPath: string): boolean {
1074
+ const gitignorePath = nodePath.join(resolvedPath, ".gitignore");
1075
+
1076
+ if (nodeFs.existsSync(gitignorePath)) {
1077
+ return false;
1078
+ }
1079
+
1080
+ nodeFs.writeFileSync(gitignorePath, DEFAULT_GITIGNORE_CONTENT, "utf-8");
1081
+ return true;
1082
+ }
1083
+
1062
1084
  function writeClaudeMd(project: string, resolvedPath: string): void {
1063
1085
  const claudeMdPath = nodePath.join(resolvedPath, "CLAUDE.md");
1064
1086
 
@@ -1333,10 +1355,12 @@ async function cmdInit(project: string, targetPath: string) {
1333
1355
  const gitDir = nodePath.join(resolvedPath, ".git");
1334
1356
 
1335
1357
  if (!nodeFs.existsSync(gitDir)) {
1336
- console.error(`No git repo found at ${targetPath}`);
1358
+ console.error(`No git repo found at ${targetPath}. Run 'git init' first, then run 'cm init' again.`);
1337
1359
  process.exit(1);
1338
1360
  }
1339
1361
 
1362
+ const gitignoreCreated = writeGitignore(resolvedPath);
1363
+
1340
1364
  const codingMemoryDir = nodePath.join(resolvedPath, ".coding-memory");
1341
1365
  nodeFs.mkdirSync(codingMemoryDir, { recursive: true });
1342
1366
 
@@ -1365,6 +1389,9 @@ async function cmdInit(project: string, targetPath: string) {
1365
1389
  const backendOk = await verifyBackendConnection(project);
1366
1390
 
1367
1391
  console.log("");
1392
+ if (gitignoreCreated) {
1393
+ console.log("✓ .gitignore created");
1394
+ }
1368
1395
  console.log("✓ Git hook installed");
1369
1396
  console.log("✓ MCP server registered");
1370
1397
  console.log("✓ CLAUDE.md written");
@@ -1858,7 +1885,14 @@ async function main() {
1858
1885
  let explicitProject: string | null;
1859
1886
  let type: string | undefined;
1860
1887
  let rest: string[];
1861
- if (MEMORY_TYPES.includes(positional[0] as MemoryType)) {
1888
+ // Exactly two positional args can only mean <type> <content> with the
1889
+ // project omitted — an explicit project would need a third slot for
1890
+ // content, which wouldn't exist. Without this check, a typo'd type
1891
+ // (failing the MEMORY_TYPES.includes test below) used to fall into
1892
+ // the "explicit project" branch instead, shifting content out of
1893
+ // existence and surfacing a generic usage() dump instead of the
1894
+ // targeted invalid-type error.
1895
+ if (positional.length === 2 || MEMORY_TYPES.includes(positional[0] as MemoryType)) {
1862
1896
  explicitProject = null;
1863
1897
  [type, ...rest] = positional;
1864
1898
  } else {
@@ -1866,6 +1900,10 @@ async function main() {
1866
1900
  [, type, ...rest] = positional;
1867
1901
  }
1868
1902
 
1903
+ if (type !== undefined && !MEMORY_TYPES.includes(type as MemoryType)) {
1904
+ fail(`Invalid memory type '${type}'. Valid types: decision, constraint, discovery, rejection.`);
1905
+ }
1906
+
1869
1907
  if (!type || rest.length === 0) usage();
1870
1908
  const project = requireProject(explicitProject);
1871
1909
  await cmdSave(project, type, rest.join(" "), force);