memorix 0.7.1 → 0.7.3

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/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.7.3] — 2026-02-22
6
+
7
+ ### Fixed
8
+ - **Windows: git remote detection fails due to "dubious ownership"** — Added `safe.directory=*` flag to all git commands so MCP subprocess can read git info regardless of directory ownership settings. If git CLI still fails, falls back to directly parsing `.git/config` file. This fixes projects incorrectly getting `local/<dirname>` instead of `owner/repo` as their project ID.
9
+
10
+ ## [0.7.2] — 2026-02-22
11
+
12
+ ### Fixed
13
+ - **`memorix_workspace_sync` rejects `kiro` as target** — Added `kiro` to `AGENT_TARGETS` enum (adapter was already implemented but missing from the tool's input schema)
14
+ - **`memorix_rules_sync` missing `kiro` target** — Added `kiro` to `RULE_SOURCES` enum so Kiro steering rules can be generated as a sync target
15
+ - **VS Code Copilot README config** — Separated `.vscode/mcp.json` (workspace) and `settings.json` (global) formats which have different JSON structures
16
+
5
17
  ## [0.7.1] — 2026-02-22
6
18
 
7
19
  ### Fixed
package/README.md CHANGED
@@ -197,7 +197,19 @@ args = ["-y", "memorix@latest", "serve"]
197
197
 
198
198
  ### VS Code Copilot
199
199
 
200
- `.vscode/mcp.json` or VS Code `settings.json`:
200
+ **Option A** — `.vscode/mcp.json` (workspace-scoped):
201
+ ```json
202
+ {
203
+ "servers": {
204
+ "memorix": {
205
+ "command": "npx",
206
+ "args": ["-y", "memorix@latest", "serve"]
207
+ }
208
+ }
209
+ }
210
+ ```
211
+
212
+ **Option B** — VS Code `settings.json` (global):
201
213
  ```json
202
214
  {
203
215
  "mcp": {
package/dist/cli/index.js CHANGED
@@ -1335,7 +1335,7 @@ __export(detector_exports, {
1335
1335
  detectProject: () => detectProject
1336
1336
  });
1337
1337
  import { execSync } from "child_process";
1338
- import { existsSync } from "fs";
1338
+ import { existsSync, readFileSync } from "fs";
1339
1339
  import os2 from "os";
1340
1340
  import path3 from "path";
1341
1341
  function detectProject(cwd) {
@@ -1431,24 +1431,43 @@ function findPackageRoot(cwd) {
1431
1431
  }
1432
1432
  function getGitRoot(cwd) {
1433
1433
  try {
1434
- const root = execSync("git rev-parse --show-toplevel", {
1434
+ const root = execSync("git -c safe.directory=* rev-parse --show-toplevel", {
1435
1435
  cwd,
1436
1436
  encoding: "utf-8",
1437
1437
  stdio: ["pipe", "pipe", "pipe"]
1438
1438
  }).trim();
1439
1439
  return root || null;
1440
1440
  } catch {
1441
+ let dir = path3.resolve(cwd);
1442
+ const fsRoot = path3.parse(dir).root;
1443
+ while (dir !== fsRoot) {
1444
+ if (existsSync(path3.join(dir, ".git"))) return dir;
1445
+ dir = path3.dirname(dir);
1446
+ }
1441
1447
  return null;
1442
1448
  }
1443
1449
  }
1444
1450
  function getGitRemote(cwd) {
1445
1451
  try {
1446
- const remote = execSync("git remote get-url origin", {
1452
+ const remote = execSync("git -c safe.directory=* remote get-url origin", {
1447
1453
  cwd,
1448
1454
  encoding: "utf-8",
1449
1455
  stdio: ["pipe", "pipe", "pipe"]
1450
1456
  }).trim();
1451
1457
  return remote || null;
1458
+ } catch {
1459
+ return readGitConfigRemote(cwd);
1460
+ }
1461
+ }
1462
+ function readGitConfigRemote(cwd) {
1463
+ try {
1464
+ const configPath = path3.join(cwd, ".git", "config");
1465
+ if (!existsSync(configPath)) return null;
1466
+ const content = readFileSync(configPath, "utf-8");
1467
+ const remoteMatch = content.match(/\[remote\s+"origin"\]([\s\S]*?)(?=\n\[|$)/);
1468
+ if (!remoteMatch) return null;
1469
+ const urlMatch = remoteMatch[1].match(/^\s*url\s*=\s*(.+)$/m);
1470
+ return urlMatch ? urlMatch[1].trim() : null;
1452
1471
  } catch {
1453
1472
  return null;
1454
1473
  }
@@ -2558,7 +2577,7 @@ var init_claude_code2 = __esm({
2558
2577
  // src/workspace/mcp-adapters/copilot.ts
2559
2578
  import { homedir as homedir5 } from "os";
2560
2579
  import { join as join5 } from "path";
2561
- import { existsSync as existsSync2, readFileSync } from "fs";
2580
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
2562
2581
  var CopilotMCPAdapter;
2563
2582
  var init_copilot2 = __esm({
2564
2583
  "src/workspace/mcp-adapters/copilot.ts"() {
@@ -2607,7 +2626,7 @@ var init_copilot2 = __esm({
2607
2626
  let existing = {};
2608
2627
  if (existsSync2(configPath)) {
2609
2628
  try {
2610
- existing = JSON.parse(readFileSync(configPath, "utf-8"));
2629
+ existing = JSON.parse(readFileSync2(configPath, "utf-8"));
2611
2630
  } catch {
2612
2631
  }
2613
2632
  }
@@ -2997,7 +3016,7 @@ var init_applier = __esm({
2997
3016
  });
2998
3017
 
2999
3018
  // src/workspace/engine.ts
3000
- import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync4, cpSync, mkdirSync as mkdirSync2 } from "fs";
3019
+ import { readFileSync as readFileSync3, readdirSync, existsSync as existsSync4, cpSync, mkdirSync as mkdirSync2 } from "fs";
3001
3020
  import { join as join9 } from "path";
3002
3021
  import { homedir as homedir8 } from "os";
3003
3022
  var WorkspaceSyncEngine;
@@ -3053,7 +3072,7 @@ var init_engine2 = __esm({
3053
3072
  for (const path8 of [configPath, globalPath]) {
3054
3073
  if (existsSync4(path8)) {
3055
3074
  try {
3056
- const content = readFileSync2(path8, "utf-8");
3075
+ const content = readFileSync3(path8, "utf-8");
3057
3076
  const servers = adapter.parse(content);
3058
3077
  if (servers.length > 0) {
3059
3078
  mcpConfigs[target] = servers;
@@ -3170,7 +3189,7 @@ var init_engine2 = __esm({
3170
3189
  if (!existsSync4(skillMd)) continue;
3171
3190
  let description = "";
3172
3191
  try {
3173
- const content = readFileSync2(skillMd, "utf-8");
3192
+ const content = readFileSync3(skillMd, "utf-8");
3174
3193
  const match = content.match(/^---[\s\S]*?description:\s*["']?(.+?)["']?\s*$/m);
3175
3194
  if (match) description = match[1];
3176
3195
  } catch {
@@ -3237,7 +3256,7 @@ var init_engine2 = __esm({
3237
3256
  const files = readdirSync(wfDir).filter((f) => f.endsWith(".md"));
3238
3257
  for (const file of files) {
3239
3258
  try {
3240
- const content = readFileSync2(join9(wfDir, file), "utf-8");
3259
+ const content = readFileSync3(join9(wfDir, file), "utf-8");
3241
3260
  workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));
3242
3261
  } catch {
3243
3262
  }
@@ -3864,7 +3883,7 @@ var engine_exports = {};
3864
3883
  __export(engine_exports, {
3865
3884
  SkillsEngine: () => SkillsEngine
3866
3885
  });
3867
- import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync2 } from "fs";
3886
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync2 } from "fs";
3868
3887
  import { join as join11 } from "path";
3869
3888
  import { homedir as homedir10 } from "os";
3870
3889
  var SKILLS_DIRS, SKILL_WORTHY_TYPES, MIN_OBS_FOR_SKILL, MIN_SCORE_FOR_SKILL, SkillsEngine;
@@ -3923,7 +3942,7 @@ var init_engine3 = __esm({
3923
3942
  const skillMd = join11(skillsRoot, name, "SKILL.md");
3924
3943
  if (!existsSync5(skillMd)) continue;
3925
3944
  try {
3926
- const content = readFileSync3(skillMd, "utf-8");
3945
+ const content = readFileSync4(skillMd, "utf-8");
3927
3946
  const description = this.parseDescription(content);
3928
3947
  skills.push({
3929
3948
  name,
@@ -4925,12 +4944,12 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
4925
4944
  };
4926
4945
  }
4927
4946
  );
4928
- const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity", "copilot"];
4947
+ const RULE_SOURCES = ["cursor", "claude-code", "codex", "windsurf", "antigravity", "copilot", "kiro"];
4929
4948
  server.registerTool(
4930
4949
  "memorix_rules_sync",
4931
4950
  {
4932
4951
  title: "Rules Sync",
4933
- description: "Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity, Copilot), deduplicate, detect conflicts, and optionally generate rules for a target agent format. Without target: returns sync status report. With target: generates converted rule files.",
4952
+ description: "Scan project for agent rule files (Cursor, Claude Code, Codex, Windsurf, Antigravity, Copilot, Kiro), deduplicate, detect conflicts, and optionally generate rules for a target agent format. Without target: returns sync status report. With target: generates converted rule files.",
4934
4953
  inputSchema: {
4935
4954
  action: z.enum(["status", "generate"]).describe('Action: "status" for report, "generate" to produce target files'),
4936
4955
  target: z.enum(RULE_SOURCES).optional().describe("Target agent format for generation (required when action=generate)")
@@ -4980,7 +4999,7 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
4980
4999
  };
4981
5000
  }
4982
5001
  );
4983
- const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot", "antigravity"];
5002
+ const AGENT_TARGETS = ["windsurf", "cursor", "claude-code", "codex", "copilot", "antigravity", "kiro"];
4984
5003
  server.registerTool(
4985
5004
  "memorix_workspace_sync",
4986
5005
  {