@vheins/local-memory-mcp 0.16.3 → 0.18.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.
@@ -81,8 +81,8 @@ function loadServerInstructions() {
81
81
  // src/mcp/capabilities.ts
82
82
  var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
83
83
  var pkgVersion = "0.1.0";
84
- if ("0.16.3") {
85
- pkgVersion = "0.16.3";
84
+ if ("0.18.0") {
85
+ pkgVersion = "0.18.0";
86
86
  } else {
87
87
  let searchDir = __dirname2;
88
88
  for (let i = 0; i < 5; i++) {
@@ -294,6 +294,7 @@ var MigrationManager = class {
294
294
  CREATE TABLE IF NOT EXISTS memories (
295
295
  id TEXT PRIMARY KEY,
296
296
  repo TEXT NOT NULL,
297
+ owner TEXT NOT NULL DEFAULT '',
297
298
  type TEXT NOT NULL,
298
299
  title TEXT,
299
300
  content TEXT NOT NULL,
@@ -322,9 +323,11 @@ var MigrationManager = class {
322
323
  CREATE INDEX IF NOT EXISTS idx_memories_title ON memories(title);
323
324
 
324
325
  CREATE TABLE IF NOT EXISTS memory_summary (
325
- repo TEXT PRIMARY KEY,
326
+ repo TEXT NOT NULL,
327
+ owner TEXT NOT NULL DEFAULT '',
326
328
  summary TEXT NOT NULL,
327
- updated_at TEXT NOT NULL
329
+ updated_at TEXT NOT NULL,
330
+ PRIMARY KEY (owner, repo)
328
331
  );
329
332
 
330
333
  CREATE TABLE IF NOT EXISTS memory_vectors (
@@ -337,6 +340,7 @@ var MigrationManager = class {
337
340
  CREATE TABLE IF NOT EXISTS tasks (
338
341
  id TEXT PRIMARY KEY,
339
342
  repo TEXT NOT NULL,
343
+ owner TEXT NOT NULL DEFAULT '',
340
344
  task_code TEXT NOT NULL,
341
345
  phase TEXT,
342
346
  title TEXT NOT NULL,
@@ -373,6 +377,7 @@ var MigrationManager = class {
373
377
  id TEXT PRIMARY KEY,
374
378
  task_id TEXT NOT NULL,
375
379
  repo TEXT NOT NULL,
380
+ owner TEXT NOT NULL DEFAULT '',
376
381
  comment TEXT NOT NULL,
377
382
  agent TEXT NOT NULL DEFAULT 'unknown',
378
383
  role TEXT NOT NULL DEFAULT 'unknown',
@@ -398,6 +403,7 @@ var MigrationManager = class {
398
403
  stack TEXT,
399
404
  is_global INTEGER NOT NULL DEFAULT 0,
400
405
  repo TEXT,
406
+ owner TEXT NOT NULL DEFAULT '',
401
407
  tags TEXT,
402
408
  metadata TEXT,
403
409
  created_at TEXT NOT NULL,
@@ -424,6 +430,7 @@ var MigrationManager = class {
424
430
  CREATE TABLE IF NOT EXISTS memories_archive (
425
431
  id TEXT PRIMARY KEY,
426
432
  repo TEXT NOT NULL,
433
+ owner TEXT NOT NULL DEFAULT '',
427
434
  type TEXT NOT NULL,
428
435
  content TEXT NOT NULL,
429
436
  importance INTEGER NOT NULL,
@@ -450,6 +457,7 @@ var MigrationManager = class {
450
457
  memory_id TEXT,
451
458
  task_id TEXT,
452
459
  repo TEXT NOT NULL,
460
+ owner TEXT NOT NULL DEFAULT '',
453
461
  result_count INTEGER NOT NULL DEFAULT 0,
454
462
  created_at TEXT NOT NULL
455
463
  );
@@ -460,6 +468,7 @@ var MigrationManager = class {
460
468
  CREATE TABLE IF NOT EXISTS handoffs (
461
469
  id TEXT PRIMARY KEY,
462
470
  repo TEXT NOT NULL,
471
+ owner TEXT NOT NULL DEFAULT '',
463
472
  from_agent TEXT NOT NULL,
464
473
  to_agent TEXT,
465
474
  task_id TEXT,
@@ -482,6 +491,7 @@ var MigrationManager = class {
482
491
  CREATE TABLE IF NOT EXISTS claims (
483
492
  id TEXT PRIMARY KEY,
484
493
  repo TEXT NOT NULL,
494
+ owner TEXT NOT NULL DEFAULT '',
485
495
  task_id TEXT NOT NULL,
486
496
  agent TEXT NOT NULL,
487
497
  role TEXT NOT NULL DEFAULT 'unknown',
@@ -590,6 +600,51 @@ var MigrationManager = class {
590
600
  name: "suggested_skills",
591
601
  table: "tasks",
592
602
  definition: "ALTER TABLE tasks ADD COLUMN suggested_skills TEXT"
603
+ },
604
+ {
605
+ name: "owner",
606
+ table: "memories",
607
+ definition: "ALTER TABLE memories ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
608
+ },
609
+ {
610
+ name: "owner",
611
+ table: "tasks",
612
+ definition: "ALTER TABLE tasks ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
613
+ },
614
+ {
615
+ name: "owner",
616
+ table: "task_comments",
617
+ definition: "ALTER TABLE task_comments ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
618
+ },
619
+ {
620
+ name: "owner",
621
+ table: "coding_standards",
622
+ definition: "ALTER TABLE coding_standards ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
623
+ },
624
+ {
625
+ name: "owner",
626
+ table: "memories_archive",
627
+ definition: "ALTER TABLE memories_archive ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
628
+ },
629
+ {
630
+ name: "owner",
631
+ table: "action_log",
632
+ definition: "ALTER TABLE action_log ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
633
+ },
634
+ {
635
+ name: "owner",
636
+ table: "handoffs",
637
+ definition: "ALTER TABLE handoffs ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
638
+ },
639
+ {
640
+ name: "owner",
641
+ table: "claims",
642
+ definition: "ALTER TABLE claims ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
643
+ },
644
+ {
645
+ name: "owner",
646
+ table: "memory_summary",
647
+ definition: "ALTER TABLE memory_summary ADD COLUMN owner TEXT NOT NULL DEFAULT ''"
593
648
  }
594
649
  ];
595
650
  for (const col of columnsToAdd) {
@@ -627,6 +682,7 @@ var MigrationManager = class {
627
682
  CREATE TABLE memories__migrated (
628
683
  id TEXT PRIMARY KEY,
629
684
  repo TEXT NOT NULL,
685
+ owner TEXT NOT NULL DEFAULT '',
630
686
  type TEXT NOT NULL,
631
687
  title TEXT,
632
688
  content TEXT NOT NULL,
@@ -651,12 +707,12 @@ var MigrationManager = class {
651
707
  );
652
708
 
653
709
  INSERT INTO memories__migrated (
654
- id, repo, type, title, content, importance, folder, language,
710
+ id, repo, owner, type, title, content, importance, folder, language,
655
711
  created_at, updated_at, hit_count, recall_count, last_used_at, expires_at,
656
712
  supersedes, status, is_global, tags, metadata, agent, role, model, completed_at
657
713
  )
658
714
  SELECT
659
- id, repo, type, title, content, importance, folder, language,
715
+ id, repo, owner, type, title, content, importance, folder, language,
660
716
  created_at, updated_at, hit_count, recall_count, last_used_at, expires_at,
661
717
  supersedes, status, is_global, tags, metadata, agent, role, model, completed_at
662
718
  FROM memories;
@@ -678,6 +734,7 @@ var MigrationManager = class {
678
734
  CREATE TABLE tasks__migrated (
679
735
  id TEXT PRIMARY KEY,
680
736
  repo TEXT NOT NULL,
737
+ owner TEXT NOT NULL DEFAULT '',
681
738
  task_code TEXT NOT NULL,
682
739
  phase TEXT,
683
740
  title TEXT NOT NULL,
@@ -704,12 +761,12 @@ var MigrationManager = class {
704
761
  );
705
762
 
706
763
  INSERT INTO tasks__migrated (
707
- id, repo, task_code, phase, title, description, status, priority,
764
+ id, repo, owner, task_code, phase, title, description, status, priority,
708
765
  agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
709
766
  commit_id, changed_files
710
767
  )
711
768
  SELECT
712
- id, repo, task_code, phase, title, description, status, priority,
769
+ id, repo, owner, task_code, phase, title, description, status, priority,
713
770
  agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
714
771
  commit_id, changed_files
715
772
  FROM tasks;
@@ -983,6 +1040,15 @@ var STOPWORDS = /* @__PURE__ */ new Set([
983
1040
  function normalize(text) {
984
1041
  return text.toLowerCase().replace(/[^a-z0-9\s_\-.]/g, " ").replace(/\s+/g, " ").trim();
985
1042
  }
1043
+ function parseRepoInput(repo, owner) {
1044
+ if (!repo) return { owner: "", repo: "" };
1045
+ if (owner) return { owner: owner.trim(), repo: repo.trim() };
1046
+ const parts = repo.split("/");
1047
+ if (parts.length > 1) {
1048
+ return { owner: parts[0].trim(), repo: parts.slice(1).join("/").trim() };
1049
+ }
1050
+ return { owner: "", repo: parts[0].trim() };
1051
+ }
986
1052
  function normalizeRepo(repo) {
987
1053
  if (!repo) return "";
988
1054
  const parts = repo.split("/");
@@ -1038,6 +1104,7 @@ var BaseEntity = class {
1038
1104
  role: r.role || "unknown",
1039
1105
  model: r.model || "unknown",
1040
1106
  scope: {
1107
+ owner: r.owner,
1041
1108
  repo: r.repo,
1042
1109
  folder: r.folder || void 0,
1043
1110
  language: r.language || void 0
@@ -1060,6 +1127,7 @@ var BaseEntity = class {
1060
1127
  const r = row;
1061
1128
  return {
1062
1129
  id: r.id,
1130
+ owner: r.owner,
1063
1131
  repo: r.repo,
1064
1132
  task_code: r.task_code,
1065
1133
  phase: r.phase || "",
@@ -1146,14 +1214,15 @@ var MemoryEntity = class extends BaseEntity {
1146
1214
  insert(entry) {
1147
1215
  this.run(
1148
1216
  `INSERT INTO memories (
1149
- id, code, repo, type, title, content, importance, folder, language,
1217
+ id, code, repo, owner, type, title, content, importance, folder, language,
1150
1218
  created_at, updated_at, hit_count, recall_count, last_used_at, expires_at,
1151
1219
  supersedes, status, is_global, tags, metadata, agent, role, model, completed_at
1152
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1220
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1153
1221
  [
1154
1222
  entry.id,
1155
1223
  entry.code || null,
1156
1224
  entry.scope.repo,
1225
+ entry.scope.owner,
1157
1226
  entry.type,
1158
1227
  entry.title || null,
1159
1228
  entry.content,
@@ -1184,6 +1253,10 @@ var MemoryEntity = class extends BaseEntity {
1184
1253
  if (val !== void 0) {
1185
1254
  if (k === "scope") {
1186
1255
  const scope = updates.scope;
1256
+ if (scope?.owner !== void 0) {
1257
+ fields.push("owner = ?");
1258
+ values.push(scope.owner);
1259
+ }
1187
1260
  if (scope?.repo) {
1188
1261
  fields.push("repo = ?");
1189
1262
  values.push(scope.repo);
@@ -1251,10 +1324,17 @@ var MemoryEntity = class extends BaseEntity {
1251
1324
  const rows = this.all(sql, params);
1252
1325
  return rows.map((row) => this.rowToMemoryEntry(row));
1253
1326
  }
1254
- getStats(repo) {
1327
+ getStats(owner, repo) {
1255
1328
  let sql = "SELECT type, COUNT(*) as count FROM memories";
1256
1329
  const params = [];
1257
- if (repo) {
1330
+ if (owner) {
1331
+ sql += " WHERE owner = ?";
1332
+ params.push(owner);
1333
+ if (repo) {
1334
+ sql += " AND repo = ?";
1335
+ params.push(repo);
1336
+ }
1337
+ } else if (repo) {
1258
1338
  sql += " WHERE repo = ?";
1259
1339
  params.push(repo);
1260
1340
  }
@@ -1268,10 +1348,10 @@ var MemoryEntity = class extends BaseEntity {
1268
1348
  });
1269
1349
  return { total, byType };
1270
1350
  }
1271
- searchByRepo(repo, query = "", type, limit = 5) {
1351
+ searchByRepo(owner, repo, query = "", type, limit = 5) {
1272
1352
  const now = (/* @__PURE__ */ new Date()).toISOString();
1273
- let sql = "SELECT * FROM memories WHERE repo = ? AND (content LIKE ? OR title LIKE ? OR tags LIKE ?) AND status = 'active' AND (expires_at IS NULL OR expires_at > ?)";
1274
- const params = [repo, `%${query}%`, `%${query}%`, `%${query}%`, now];
1353
+ let sql = "SELECT * FROM memories WHERE owner = ? AND repo = ? AND (content LIKE ? OR title LIKE ? OR tags LIKE ?) AND status = 'active' AND (expires_at IS NULL OR expires_at > ?)";
1354
+ const params = [owner, repo, `%${query}%`, `%${query}%`, `%${query}%`, now];
1275
1355
  if (type) {
1276
1356
  sql += " AND type = ?";
1277
1357
  params.push(type);
@@ -1287,13 +1367,14 @@ var MemoryEntity = class extends BaseEntity {
1287
1367
  for (const entry of entries) {
1288
1368
  this.run(
1289
1369
  `INSERT INTO memories (
1290
- id, repo, type, title, content, importance, folder, language,
1370
+ id, repo, owner, type, title, content, importance, folder, language,
1291
1371
  created_at, updated_at, hit_count, recall_count, last_used_at, expires_at,
1292
1372
  supersedes, status, is_global, tags, metadata, agent, role, model, completed_at
1293
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1373
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1294
1374
  [
1295
1375
  entry.id,
1296
1376
  entry.scope.repo,
1377
+ entry.scope.owner,
1297
1378
  entry.type,
1298
1379
  entry.title || null,
1299
1380
  entry.content,
@@ -1328,6 +1409,10 @@ var MemoryEntity = class extends BaseEntity {
1328
1409
  if (value !== void 0) {
1329
1410
  if (key === "scope") {
1330
1411
  const scope = updates.scope;
1412
+ if (scope?.owner !== void 0) {
1413
+ fields.push("owner = ?");
1414
+ values.push(scope.owner);
1415
+ }
1331
1416
  if (scope?.repo) {
1332
1417
  fields.push("repo = ?");
1333
1418
  values.push(scope.repo);
@@ -1369,9 +1454,9 @@ var MemoryEntity = class extends BaseEntity {
1369
1454
  return count;
1370
1455
  });
1371
1456
  }
1372
- getRecentMemories(repo, limit, offset = 0, includeArchived = false, excludeTypes = [], sortOrder = "DESC") {
1373
- let query = "SELECT * FROM memories WHERE repo = ?";
1374
- const params = [repo];
1457
+ getRecentMemories(owner, repo, limit, offset = 0, includeArchived = false, excludeTypes = [], sortOrder = "DESC") {
1458
+ let query = "SELECT * FROM memories WHERE owner = ? AND repo = ?";
1459
+ const params = [owner, repo];
1375
1460
  if (!includeArchived) {
1376
1461
  query += " AND status = 'active'";
1377
1462
  }
@@ -1384,9 +1469,9 @@ var MemoryEntity = class extends BaseEntity {
1384
1469
  const rows = this.all(query, params);
1385
1470
  return rows.map((row) => this.rowToMemoryEntry(row));
1386
1471
  }
1387
- getTotalCount(repo, includeArchived = false, excludeTypes = []) {
1388
- let sql = "SELECT COUNT(*) as count FROM memories WHERE repo = ?";
1389
- const params = [repo];
1472
+ getTotalCount(owner, repo, includeArchived = false, excludeTypes = []) {
1473
+ let sql = "SELECT COUNT(*) as count FROM memories WHERE owner = ? AND repo = ?";
1474
+ const params = [owner, repo];
1390
1475
  if (!includeArchived) sql += " AND status = 'active'";
1391
1476
  if (excludeTypes.length > 0) {
1392
1477
  sql += ` AND type NOT IN (${excludeTypes.map(() => "?").join(",")})`;
@@ -1414,32 +1499,33 @@ var MemoryEntity = class extends BaseEntity {
1414
1499
  id
1415
1500
  ]);
1416
1501
  }
1417
- getSummary(repo) {
1502
+ getSummary(owner, repo) {
1418
1503
  const row = this.get(
1419
- "SELECT summary, updated_at FROM memory_summary WHERE repo = ?",
1420
- [repo]
1504
+ "SELECT summary, updated_at FROM memory_summary WHERE owner = ? AND repo = ?",
1505
+ [owner, repo]
1421
1506
  );
1422
1507
  return row;
1423
1508
  }
1424
- getAllMemoriesWithStats(repo) {
1509
+ getAllMemoriesWithStats(owner, repo) {
1425
1510
  const rows = this.all(
1426
- `SELECT *, CASE WHEN hit_count > 0 THEN CAST(recall_count AS REAL) / hit_count ELSE 0 END AS recall_rate FROM memories WHERE repo = ? ORDER BY created_at DESC`,
1427
- [repo]
1511
+ `SELECT *, CASE WHEN hit_count > 0 THEN CAST(recall_count AS REAL) / hit_count ELSE 0 END AS recall_rate FROM memories WHERE owner = ? AND repo = ? ORDER BY created_at DESC`,
1512
+ [owner, repo]
1428
1513
  );
1429
1514
  return rows.map((row) => ({
1430
1515
  ...this.rowToMemoryEntry(row),
1431
1516
  recall_rate: row.recall_rate || 0
1432
1517
  }));
1433
1518
  }
1434
- upsertSummary(repo, summary) {
1519
+ upsertSummary(owner, repo, summary) {
1435
1520
  this.run(
1436
- `INSERT INTO memory_summary (repo, summary, updated_at) VALUES (?, ?, ?)
1437
- ON CONFLICT(repo) DO UPDATE SET summary = excluded.summary, updated_at = excluded.updated_at`,
1438
- [repo, summary, (/* @__PURE__ */ new Date()).toISOString()]
1521
+ `INSERT INTO memory_summary (owner, repo, summary, updated_at) VALUES (?, ?, ?, ?)
1522
+ ON CONFLICT(owner, repo) DO UPDATE SET summary = excluded.summary, updated_at = excluded.updated_at`,
1523
+ [owner, repo, summary, (/* @__PURE__ */ new Date()).toISOString()]
1439
1524
  );
1440
1525
  }
1441
1526
  listMemoriesForDashboard(options) {
1442
1527
  const {
1528
+ owner,
1443
1529
  repo,
1444
1530
  type,
1445
1531
  tag,
@@ -1454,6 +1540,10 @@ var MemoryEntity = class extends BaseEntity {
1454
1540
  } = options;
1455
1541
  const where = ["1=1"];
1456
1542
  const params = [];
1543
+ if (owner) {
1544
+ where.push("owner = ?");
1545
+ params.push(owner);
1546
+ }
1457
1547
  if (repo) {
1458
1548
  where.push("repo = ?");
1459
1549
  params.push(repo);
@@ -1497,12 +1587,15 @@ var MemoryEntity = class extends BaseEntity {
1497
1587
 
1498
1588
  // src/mcp/entities/memory.vector.ts
1499
1589
  var MemoryVectorEntity = class extends BaseEntity {
1500
- getVectorCandidates(repo, limit = 100) {
1590
+ getVectorCandidates(owner, repo, limit = 100) {
1501
1591
  let sql = `SELECT mv.memory_id, mv.vector FROM memory_vectors mv JOIN memories m ON mv.memory_id = m.id`;
1502
1592
  const params = [];
1503
1593
  if (repo) {
1504
- sql += " WHERE m.repo = ?";
1505
- params.push(repo);
1594
+ sql += " WHERE m.owner = ? AND m.repo = ?";
1595
+ params.push(owner, repo);
1596
+ } else if (owner) {
1597
+ sql += " WHERE m.owner = ?";
1598
+ params.push(owner);
1506
1599
  }
1507
1600
  sql += " LIMIT ?";
1508
1601
  params.push(limit);
@@ -1515,11 +1608,11 @@ var MemoryVectorEntity = class extends BaseEntity {
1515
1608
  [memoryId, JSON.stringify(vector), (/* @__PURE__ */ new Date()).toISOString()]
1516
1609
  );
1517
1610
  }
1518
- searchBySimilarity(query, repo, limit = 10, includeArchived = false, currentTags = []) {
1611
+ searchBySimilarity(query, owner, repo, limit = 10, includeArchived = false, currentTags = []) {
1519
1612
  const queryVector = this.computeVector(query);
1520
1613
  const now = /* @__PURE__ */ new Date();
1521
- const where = ["(repo = ? OR is_global = 1)"];
1522
- const params = [repo];
1614
+ const where = ["(owner = ? AND repo = ? OR is_global = 1)"];
1615
+ const params = [owner, repo];
1523
1616
  if (currentTags.length > 0) {
1524
1617
  const tagConditions = currentTags.map(() => "tags LIKE ?").join(" OR ");
1525
1618
  where.push(`(${tagConditions})`);
@@ -1527,8 +1620,8 @@ var MemoryVectorEntity = class extends BaseEntity {
1527
1620
  }
1528
1621
  let sql = `SELECT * FROM memories WHERE (${where.join(" AND ")}) AND (expires_at IS NULL OR expires_at > ?)`;
1529
1622
  if (!includeArchived) sql += " AND status = 'active'";
1530
- sql += ` ORDER BY CASE WHEN repo = ? THEN 0 ELSE 1 END, importance DESC, created_at DESC LIMIT 100`;
1531
- const candidates = this.all(sql, [...params, now.toISOString(), repo]);
1623
+ sql += ` ORDER BY CASE WHEN owner = ? AND repo = ? THEN 0 ELSE 1 END, importance DESC, created_at DESC LIMIT 100`;
1624
+ const candidates = this.all(sql, [...params, now.toISOString(), owner, repo]);
1532
1625
  if (candidates.length < 5) {
1533
1626
  const recentSql = `SELECT * FROM memories WHERE (${where.join(" OR ")}) AND status = 'active' AND (expires_at IS NULL OR expires_at > ?) ORDER BY created_at DESC LIMIT 10`;
1534
1627
  const recent = this.all(recentSql, [...params, now.toISOString()]);
@@ -1556,8 +1649,8 @@ var MemoryVectorEntity = class extends BaseEntity {
1556
1649
  return { ...memory, similarity: score };
1557
1650
  }).filter((r) => r.similarity > 0).sort((a, b) => b.similarity - a.similarity).slice(0, limit);
1558
1651
  }
1559
- async checkConflicts(content, repo, _type, _vectors, threshold = 0.55) {
1560
- const results = await this.searchBySimilarity(content, repo, 1, false);
1652
+ async checkConflicts(content, owner, repo, _type, _vectors, threshold = 0.55) {
1653
+ const results = await this.searchBySimilarity(content, owner, repo, 1, false);
1561
1654
  if (results.length > 0 && results[0].similarity >= threshold) {
1562
1655
  return results[0];
1563
1656
  }
@@ -1620,13 +1713,14 @@ var TaskEntity = class extends BaseEntity {
1620
1713
  insertTask(task) {
1621
1714
  this.run(
1622
1715
  `INSERT INTO tasks (
1623
- id, repo, task_code, phase, title, description, status, priority,
1716
+ id, repo, owner, task_code, phase, title, description, status, priority,
1624
1717
  agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, suggested_skills, metadata, parent_id, depends_on, est_tokens, in_progress_at,
1625
1718
  commit_id, changed_files
1626
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1719
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1627
1720
  [
1628
1721
  task.id,
1629
1722
  task.repo,
1723
+ task.owner || "",
1630
1724
  task.task_code,
1631
1725
  task.phase || null,
1632
1726
  task.title,
@@ -1657,6 +1751,7 @@ var TaskEntity = class extends BaseEntity {
1657
1751
  const values = [];
1658
1752
  const anyUpdates = updates;
1659
1753
  const VALID_COLUMNS2 = /* @__PURE__ */ new Set([
1754
+ "owner",
1660
1755
  "repo",
1661
1756
  "task_code",
1662
1757
  "phase",
@@ -1747,15 +1842,15 @@ var TaskEntity = class extends BaseEntity {
1747
1842
  return task;
1748
1843
  });
1749
1844
  }
1750
- getTaskByCode(repo, taskCode) {
1845
+ getTaskByCode(owner, repo, taskCode) {
1751
1846
  const row = this.get(
1752
1847
  `SELECT t.*, d.task_code as depends_on_code, p.task_code as parent_code,
1753
1848
  ${this.coordinationSelect("t")}
1754
1849
  FROM tasks t
1755
1850
  LEFT JOIN tasks d ON t.depends_on = d.id
1756
1851
  LEFT JOIN tasks p ON t.parent_id = p.id
1757
- WHERE t.repo = ? AND t.task_code = ?`,
1758
- [repo, taskCode]
1852
+ WHERE t.owner = ? AND t.repo = ? AND t.task_code = ?`,
1853
+ [owner, repo, taskCode]
1759
1854
  );
1760
1855
  return row ? {
1761
1856
  ...this.rowToTask(row),
@@ -1765,7 +1860,7 @@ var TaskEntity = class extends BaseEntity {
1765
1860
  )
1766
1861
  } : null;
1767
1862
  }
1768
- getTasksByRepo(repo, status, limit, offset, search) {
1863
+ getTasksByRepo(owner, repo, status, limit, offset, search) {
1769
1864
  let query = `
1770
1865
  SELECT t.*, d.task_code as depends_on_code, p.task_code as parent_code,
1771
1866
  ${this.coordinationSelect("t")},
@@ -1773,9 +1868,9 @@ var TaskEntity = class extends BaseEntity {
1773
1868
  FROM tasks t
1774
1869
  LEFT JOIN tasks d ON t.depends_on = d.id
1775
1870
  LEFT JOIN tasks p ON t.parent_id = p.id
1776
- WHERE t.repo = ?
1871
+ WHERE ${owner ? "t.owner = ? AND " : ""}t.repo = ?
1777
1872
  `;
1778
- const params = [repo];
1873
+ const params = owner ? [owner, repo] : [repo];
1779
1874
  if (status) {
1780
1875
  query += " AND t.status = ?";
1781
1876
  params.push(status);
@@ -1807,9 +1902,10 @@ var TaskEntity = class extends BaseEntity {
1807
1902
  const rows = this.all(query, params);
1808
1903
  return rows.map((r) => this.rowToTask(r));
1809
1904
  }
1810
- countTasks(repo, status, search) {
1811
- let query = "SELECT COUNT(*) as count FROM tasks WHERE repo = ?";
1812
- const params = [repo];
1905
+ countTasks(owner, repo, status, search) {
1906
+ const ownerClause = owner ? "owner = ? AND " : "";
1907
+ let query = `SELECT COUNT(*) as count FROM tasks WHERE ${ownerClause}repo = ?`;
1908
+ const params = owner ? [owner, repo] : [repo];
1813
1909
  if (status) {
1814
1910
  query += " AND status = ?";
1815
1911
  params.push(status);
@@ -1831,7 +1927,6 @@ var TaskEntity = class extends BaseEntity {
1831
1927
  LEFT JOIN tasks d ON t.depends_on = d.id
1832
1928
  LEFT JOIN tasks p ON t.parent_id = p.id
1833
1929
  ORDER BY
1834
- ...
1835
1930
  CASE WHEN t.status = 'completed' THEN 1 ELSE 0 END ASC,
1836
1931
  CASE WHEN t.status = 'completed' THEN t.updated_at ELSE NULL END DESC,
1837
1932
  CASE WHEN t.status = 'in_progress' THEN 0
@@ -1847,8 +1942,9 @@ var TaskEntity = class extends BaseEntity {
1847
1942
  const rows = this.all(query, [limit, offset]);
1848
1943
  return rows.map((r) => this.rowToTask(r));
1849
1944
  }
1850
- getTasksByMultipleStatuses(repo, statuses, limit, offset, search) {
1851
- if (!statuses.length) return this.getTasksByRepo(repo, void 0, limit, offset, search);
1945
+ getTasksByMultipleStatuses(owner, repo, statuses, limit, offset, search) {
1946
+ if (!statuses.length) return this.getTasksByRepo(owner, repo, void 0, limit, offset, search);
1947
+ const ownerClause = owner ? "t.owner = ? AND " : "";
1852
1948
  let query = `
1853
1949
  SELECT t.*, d.task_code as depends_on_code, p.task_code as parent_code,
1854
1950
  ${this.coordinationSelect("t")},
@@ -1856,9 +1952,9 @@ var TaskEntity = class extends BaseEntity {
1856
1952
  FROM tasks t
1857
1953
  LEFT JOIN tasks d ON t.depends_on = d.id
1858
1954
  LEFT JOIN tasks p ON t.parent_id = p.id
1859
- WHERE t.repo = ? AND t.status IN (${statuses.map(() => "?").join(",")})
1955
+ WHERE ${ownerClause}t.repo = ? AND t.status IN (${statuses.map(() => "?").join(",")})
1860
1956
  `;
1861
- const params = [repo, ...statuses];
1957
+ const params = owner ? [owner, repo, ...statuses] : [repo, ...statuses];
1862
1958
  if (search) {
1863
1959
  query += " AND (t.title LIKE ? OR t.description LIKE ? OR t.task_code LIKE ?)";
1864
1960
  const searchPattern = `%${search}%`;
@@ -1886,10 +1982,11 @@ var TaskEntity = class extends BaseEntity {
1886
1982
  const rows = this.all(query, params);
1887
1983
  return rows.map((r) => this.rowToTask(r));
1888
1984
  }
1889
- countTasksByMultipleStatuses(repo, statuses, search) {
1890
- if (!statuses.length) return this.countTasks(repo, void 0, search);
1891
- let query = `SELECT COUNT(*) as count FROM tasks WHERE repo = ? AND status IN (${statuses.map(() => "?").join(",")})`;
1892
- const params = [repo, ...statuses];
1985
+ countTasksByMultipleStatuses(owner, repo, statuses, search) {
1986
+ if (!statuses.length) return this.countTasks(owner, repo, void 0, search);
1987
+ const ownerClause = owner ? "owner = ? AND " : "";
1988
+ let query = `SELECT COUNT(*) as count FROM tasks WHERE ${ownerClause}repo = ? AND status IN (${statuses.map(() => "?").join(",")})`;
1989
+ const params = owner ? [owner, repo, ...statuses] : [repo, ...statuses];
1893
1990
  if (search) {
1894
1991
  query += " AND (title LIKE ? OR description LIKE ? OR task_code LIKE ?)";
1895
1992
  const searchPattern = `%${search}%`;
@@ -1898,9 +1995,9 @@ var TaskEntity = class extends BaseEntity {
1898
1995
  const row = this.get(query, params);
1899
1996
  return row?.count ?? 0;
1900
1997
  }
1901
- isTaskCodeDuplicate(repo, task_code, excludeId) {
1902
- let query = "SELECT COUNT(*) as count FROM tasks WHERE repo = ? AND task_code = ?";
1903
- const params = [repo, task_code];
1998
+ isTaskCodeDuplicate(owner, repo, task_code, excludeId) {
1999
+ let query = "SELECT COUNT(*) as count FROM tasks WHERE owner = ? AND repo = ? AND task_code = ?";
2000
+ const params = [owner, repo, task_code];
1904
2001
  if (excludeId) {
1905
2002
  query += " AND id != ?";
1906
2003
  params.push(excludeId);
@@ -1920,12 +2017,12 @@ var TaskEntity = class extends BaseEntity {
1920
2017
  [id]
1921
2018
  );
1922
2019
  }
1923
- getExistingTaskCodes(repo, codes) {
2020
+ getExistingTaskCodes(owner, repo, codes) {
1924
2021
  if (codes.length === 0) return /* @__PURE__ */ new Set();
1925
2022
  const placeholders = codes.map(() => "?").join(",");
1926
2023
  const rows = this.all(
1927
- `SELECT task_code FROM tasks WHERE repo = ? AND task_code IN (${placeholders})`,
1928
- [repo, ...codes]
2024
+ `SELECT task_code FROM tasks WHERE owner = ? AND repo = ? AND task_code IN (${placeholders})`,
2025
+ [owner, repo, ...codes]
1929
2026
  );
1930
2027
  return new Set(rows.map((r) => r.task_code));
1931
2028
  }
@@ -1935,13 +2032,14 @@ var TaskEntity = class extends BaseEntity {
1935
2032
  for (const task of tasks) {
1936
2033
  this.run(
1937
2034
  `INSERT INTO tasks (
1938
- id, repo, task_code, phase, title, description, status, priority,
2035
+ id, repo, owner, task_code, phase, title, description, status, priority,
1939
2036
  agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, suggested_skills, metadata, parent_id, depends_on, est_tokens, in_progress_at,
1940
2037
  commit_id, changed_files
1941
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2038
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1942
2039
  [
1943
2040
  task.id,
1944
2041
  task.repo,
2042
+ task.owner || "",
1945
2043
  task.task_code,
1946
2044
  task.phase || null,
1947
2045
  task.title,
@@ -1978,12 +2076,13 @@ var TaskCommentEntity = class extends BaseEntity {
1978
2076
  insertTaskComment(comment) {
1979
2077
  this.run(
1980
2078
  `INSERT INTO task_comments (
1981
- id, task_id, repo, comment, agent, role, model, previous_status, next_status, created_at
1982
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2079
+ id, task_id, repo, owner, comment, agent, role, model, previous_status, next_status, created_at
2080
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1983
2081
  [
1984
2082
  comment.id,
1985
2083
  comment.task_id,
1986
2084
  comment.repo,
2085
+ comment.owner,
1987
2086
  comment.comment,
1988
2087
  comment.agent || "unknown",
1989
2088
  comment.role || "unknown",
@@ -1999,6 +2098,7 @@ var TaskCommentEntity = class extends BaseEntity {
1999
2098
  const values = [];
2000
2099
  const anyUpdates = updates;
2001
2100
  const VALID_COLUMNS2 = /* @__PURE__ */ new Set([
2101
+ "owner",
2002
2102
  "repo",
2003
2103
  "comment",
2004
2104
  "agent",
@@ -2028,19 +2128,20 @@ var TaskCommentEntity = class extends BaseEntity {
2028
2128
  taskId
2029
2129
  ]);
2030
2130
  }
2031
- getAllTaskCommentsByRepo(repo) {
2032
- return this.all(`SELECT * FROM task_comments WHERE repo = ? ORDER BY created_at DESC, id DESC`, [
2033
- repo
2034
- ]);
2131
+ getAllTaskCommentsByRepo(owner, repo) {
2132
+ return this.all(
2133
+ `SELECT * FROM task_comments WHERE owner = ? AND repo = ? ORDER BY created_at DESC, id DESC`,
2134
+ [owner, repo]
2135
+ );
2035
2136
  }
2036
2137
  };
2037
2138
 
2038
2139
  // src/mcp/entities/task-stats.ts
2039
2140
  var TaskStatsEntity = class extends BaseEntity {
2040
- getTaskStats(repo) {
2141
+ getTaskStats(owner, repo) {
2041
2142
  const rows = this.all(
2042
- "SELECT status, COUNT(*) as count FROM tasks WHERE repo = ? GROUP BY status",
2043
- [repo]
2143
+ "SELECT status, COUNT(*) as count FROM tasks WHERE owner = ? AND repo = ? GROUP BY status",
2144
+ [owner, repo]
2044
2145
  );
2045
2146
  const stats = { total: 0, backlog: 0, todo: 0, inProgress: 0, completed: 0, blocked: 0, canceled: 0 };
2046
2147
  rows.forEach((r) => {
@@ -2055,14 +2156,14 @@ var TaskStatsEntity = class extends BaseEntity {
2055
2156
  });
2056
2157
  return stats;
2057
2158
  }
2058
- getTaskTimeStats(repo, period) {
2159
+ getTaskTimeStats(owner, repo, period) {
2059
2160
  let dateFilter = "";
2060
2161
  if (period === "daily") dateFilter = "AND date(COALESCE(finished_at, updated_at)) = date('now')";
2061
2162
  else if (period === "weekly") dateFilter = "AND date(COALESCE(finished_at, updated_at)) >= date('now', '-7 days')";
2062
2163
  else if (period === "monthly")
2063
2164
  dateFilter = "AND date(COALESCE(finished_at, updated_at)) >= date('now', '-30 days')";
2064
- const repoWhere = repo ? "repo = ?" : "1=1";
2065
- const repoParams = repo ? [repo] : [];
2165
+ const repoWhere = repo ? "owner = ? AND repo = ?" : "1=1";
2166
+ const repoParams = repo ? [owner, repo] : [];
2066
2167
  const stats = this.get(
2067
2168
  `SELECT
2068
2169
  COUNT(*) as completed_count,
@@ -2096,7 +2197,7 @@ var TaskStatsEntity = class extends BaseEntity {
2096
2197
  added: added?.count || 0
2097
2198
  };
2098
2199
  }
2099
- getTaskComparisonSeries(repo, period) {
2200
+ getTaskComparisonSeries(owner, repo, period) {
2100
2201
  let labelFormat;
2101
2202
  let dateFilter;
2102
2203
  if (period === "daily") {
@@ -2117,8 +2218,8 @@ var TaskStatsEntity = class extends BaseEntity {
2117
2218
  "COALESCE(finished_at, created_at)",
2118
2219
  "COALESCE(finished_at, updated_at)"
2119
2220
  );
2120
- const createdRepoFilter = repo ? "repo = ? AND " : "";
2121
- const completedRepoFilter = repo ? "repo = ? AND " : "";
2221
+ const createdRepoFilter = repo ? "owner = ? AND repo = ? AND " : "";
2222
+ const completedRepoFilter = repo ? "owner = ? AND repo = ? AND " : "";
2122
2223
  const query = `
2123
2224
  SELECT label, SUM(created) as created, SUM(completed) as completed
2124
2225
  FROM (
@@ -2135,16 +2236,16 @@ var TaskStatsEntity = class extends BaseEntity {
2135
2236
  LIMIT 100
2136
2237
  `;
2137
2238
  const params = [labelFormat];
2138
- if (repo) params.push(repo);
2239
+ if (repo) params.push(owner, repo);
2139
2240
  params.push(labelFormat);
2140
- if (repo) params.push(repo);
2241
+ if (repo) params.push(owner, repo);
2141
2242
  return this.all(query, params);
2142
2243
  }
2143
2244
  };
2144
2245
 
2145
2246
  // src/mcp/entities/action.ts
2146
2247
  var ActionEntity = class extends BaseEntity {
2147
- logAction(action, repo, optionsOrQuery, response, memoryId, taskId, resultCount = 0) {
2248
+ logAction(action, owner, repo, optionsOrQuery, response, memoryId, taskId, resultCount = 0) {
2148
2249
  let query = typeof optionsOrQuery === "string" ? optionsOrQuery : void 0;
2149
2250
  let finalResponse = response;
2150
2251
  let finalMemoryId = memoryId;
@@ -2159,9 +2260,10 @@ var ActionEntity = class extends BaseEntity {
2159
2260
  finalResultCount = optionsOrQuery.resultCount !== void 0 ? optionsOrQuery.resultCount : finalResultCount;
2160
2261
  }
2161
2262
  this.run(
2162
- `INSERT INTO action_log (repo, action, query, response, memory_id, task_id, result_count, created_at)
2163
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
2263
+ `INSERT INTO action_log (owner, repo, action, query, response, memory_id, task_id, result_count, created_at)
2264
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2164
2265
  [
2266
+ owner,
2165
2267
  repo || "",
2166
2268
  action || "unknown",
2167
2269
  query || null,
@@ -2185,37 +2287,45 @@ var ActionEntity = class extends BaseEntity {
2185
2287
  [id]
2186
2288
  );
2187
2289
  }
2188
- getRecentActions(repo, limit = 10, offset = 0) {
2290
+ getRecentActions(owner, repo, limit = 10, offset = 0) {
2189
2291
  let query = `
2190
2292
  SELECT a.*, m.title as memory_title, m.type as memory_type
2191
2293
  FROM action_log a LEFT JOIN memories m ON a.memory_id = m.id
2192
2294
  `;
2193
2295
  const params = [];
2296
+ const where = [];
2194
2297
  if (repo) {
2195
- query += " WHERE a.repo = ?";
2298
+ where.push("a.repo = ?");
2196
2299
  params.push(repo);
2197
2300
  }
2301
+ if (owner) {
2302
+ where.push("a.owner = ?");
2303
+ params.push(owner);
2304
+ }
2305
+ if (where.length > 0) {
2306
+ query += " WHERE " + where.join(" AND ");
2307
+ }
2198
2308
  query += " ORDER BY a.created_at DESC, a.id DESC LIMIT ? OFFSET ?";
2199
2309
  params.push(limit, offset);
2200
2310
  return this.all(query, params);
2201
2311
  }
2202
- getActionStatsByDate(repo) {
2312
+ getActionStatsByDate(owner, repo) {
2203
2313
  return this.all(
2204
2314
  `SELECT date(created_at) as date, count(*) as count
2205
2315
  FROM action_log
2206
- WHERE repo = ? AND created_at > date('now', '-30 days')
2316
+ WHERE owner = ? AND repo = ? AND created_at > date('now', '-30 days')
2207
2317
  GROUP BY date(created_at)
2208
2318
  ORDER BY date ASC`,
2209
- [repo]
2319
+ [owner, repo]
2210
2320
  );
2211
2321
  }
2212
- getActionDistribution(repo) {
2322
+ getActionDistribution(owner, repo) {
2213
2323
  return this.all(
2214
2324
  `SELECT action, count(*) as count
2215
2325
  FROM action_log
2216
- WHERE repo = ?
2326
+ WHERE owner = ? AND repo = ?
2217
2327
  GROUP BY action`,
2218
- [repo]
2328
+ [owner, repo]
2219
2329
  );
2220
2330
  }
2221
2331
  getActionById(id) {
@@ -2251,39 +2361,55 @@ var SystemEntity = class extends BaseEntity {
2251
2361
  });
2252
2362
  return taskStats;
2253
2363
  }
2254
- listRepos() {
2255
- const rows = this.all("SELECT DISTINCT repo FROM memories UNION SELECT DISTINCT repo FROM tasks");
2364
+ listRepos(owner) {
2365
+ let sql;
2366
+ if (owner) {
2367
+ sql = "SELECT DISTINCT repo FROM memories WHERE owner = ? UNION SELECT DISTINCT repo FROM tasks WHERE owner = ?";
2368
+ } else {
2369
+ sql = "SELECT DISTINCT repo FROM memories UNION SELECT DISTINCT repo FROM tasks";
2370
+ }
2371
+ const params = owner ? [owner, owner] : [];
2372
+ const rows = this.all(sql, params);
2256
2373
  return rows.map((r) => r.repo);
2257
2374
  }
2258
- listRepoNavigation() {
2259
- const repos = this.listRepos();
2375
+ listRepoNavigation(owner) {
2376
+ const repos = this.listRepos(owner);
2377
+ const ownerFilter = owner ? " AND owner = ?" : "";
2378
+ const ownerParams = owner ? [owner] : [];
2260
2379
  const activeClaimRows = this.all(
2261
- "SELECT repo, COUNT(*) as count FROM claims WHERE released_at IS NULL GROUP BY repo"
2380
+ `SELECT repo, COUNT(*) as count FROM claims WHERE released_at IS NULL${ownerFilter} GROUP BY repo`,
2381
+ ownerParams
2262
2382
  );
2263
2383
  const pendingHandoffRows = this.all(
2264
- "SELECT repo, COUNT(*) as count FROM handoffs WHERE status = 'pending' GROUP BY repo"
2384
+ `SELECT repo, COUNT(*) as count FROM handoffs WHERE status = 'pending'${ownerFilter} GROUP BY repo`,
2385
+ ownerParams
2265
2386
  );
2266
2387
  const unassignedHandoffRows = this.all(
2267
- "SELECT repo, COUNT(*) as count FROM handoffs WHERE status = 'pending' AND to_agent IS NULL GROUP BY repo"
2388
+ `SELECT repo, COUNT(*) as count FROM handoffs WHERE status = 'pending' AND to_agent IS NULL${ownerFilter} GROUP BY repo`,
2389
+ ownerParams
2268
2390
  );
2269
2391
  const staleClaimRows = this.all(
2270
- "SELECT repo, COUNT(*) as count FROM claims WHERE released_at IS NULL AND claimed_at <= datetime('now', '-1 day') GROUP BY repo"
2392
+ `SELECT repo, COUNT(*) as count FROM claims WHERE released_at IS NULL AND claimed_at <= datetime('now', '-1 day')${ownerFilter} GROUP BY repo`,
2393
+ ownerParams
2271
2394
  );
2272
2395
  const activeClaimsByRepo = Object.fromEntries(activeClaimRows.map((row) => [row.repo, row.count]));
2273
2396
  const pendingHandoffsByRepo = Object.fromEntries(pendingHandoffRows.map((row) => [row.repo, row.count]));
2274
2397
  const unassignedHandoffsByRepo = Object.fromEntries(unassignedHandoffRows.map((row) => [row.repo, row.count]));
2275
2398
  const staleClaimsByRepo = Object.fromEntries(staleClaimRows.map((row) => [row.repo, row.count]));
2399
+ const repoOwnerFilter = owner ? " AND owner = ?" : "";
2400
+ const repoOwnerParams = owner ? [owner] : [];
2276
2401
  return repos.map((repo) => {
2277
- const memoryCountRow = this.get("SELECT COUNT(*) as count FROM memories WHERE repo = ?", [
2278
- repo
2279
- ]);
2402
+ const memoryCountRow = this.get(
2403
+ `SELECT COUNT(*) as count FROM memories WHERE repo = ?${repoOwnerFilter}`,
2404
+ owner ? [repo, owner] : [repo]
2405
+ );
2280
2406
  const lastActivityRow = this.get(
2281
- `SELECT MAX(created_at) as last FROM (SELECT created_at FROM memories WHERE repo = ? UNION ALL SELECT created_at FROM tasks WHERE repo = ? UNION ALL SELECT created_at FROM action_log WHERE repo = ?)`,
2282
- [repo, repo, repo]
2407
+ `SELECT MAX(created_at) as last FROM (SELECT created_at FROM memories WHERE repo = ?${repoOwnerFilter} UNION ALL SELECT created_at FROM tasks WHERE repo = ?${repoOwnerFilter} UNION ALL SELECT created_at FROM action_log WHERE repo = ?${repoOwnerFilter})`,
2408
+ owner ? [repo, owner, repo, owner, repo, owner] : [repo, repo, repo]
2283
2409
  );
2284
2410
  const taskStatusRows = this.all(
2285
- "SELECT status, COUNT(*) as count FROM tasks WHERE repo = ? GROUP BY status",
2286
- [repo]
2411
+ `SELECT status, COUNT(*) as count FROM tasks WHERE repo = ?${repoOwnerFilter} GROUP BY status`,
2412
+ owner ? [repo, owner] : [repo]
2287
2413
  );
2288
2414
  const taskStatusMap = {};
2289
2415
  taskStatusRows.forEach((r) => {
@@ -2306,35 +2432,39 @@ var SystemEntity = class extends BaseEntity {
2306
2432
  };
2307
2433
  });
2308
2434
  }
2309
- getDashboardStats(repo) {
2310
- const totalCountRow = this.get("SELECT COUNT(*) as count FROM memories WHERE repo = ?", [repo]);
2311
- const avgImportanceRow = this.get("SELECT AVG(importance) as avg FROM memories WHERE repo = ?", [
2312
- repo
2313
- ]);
2435
+ getDashboardStats(owner, repo) {
2436
+ const totalCountRow = this.get(
2437
+ "SELECT COUNT(*) as count FROM memories WHERE owner = ? AND repo = ?",
2438
+ [owner, repo]
2439
+ );
2440
+ const avgImportanceRow = this.get(
2441
+ "SELECT AVG(importance) as avg FROM memories WHERE owner = ? AND repo = ?",
2442
+ [owner, repo]
2443
+ );
2314
2444
  const totalHitCountRow = this.get(
2315
- "SELECT SUM(hit_count) as count FROM memories WHERE repo = ?",
2316
- [repo]
2445
+ "SELECT SUM(hit_count) as count FROM memories WHERE owner = ? AND repo = ?",
2446
+ [owner, repo]
2317
2447
  );
2318
2448
  const expiringSoonRow = this.get(
2319
- "SELECT COUNT(*) as count FROM memories WHERE repo = ? AND expires_at IS NOT NULL AND expires_at > ? AND expires_at <= ?",
2320
- [repo, (/* @__PURE__ */ new Date()).toISOString(), new Date(Date.now() + 7 * 86400 * 1e3).toISOString()]
2449
+ "SELECT COUNT(*) as count FROM memories WHERE owner = ? AND repo = ? AND expires_at IS NOT NULL AND expires_at > ? AND expires_at <= ?",
2450
+ [owner, repo, (/* @__PURE__ */ new Date()).toISOString(), new Date(Date.now() + 7 * 86400 * 1e3).toISOString()]
2321
2451
  );
2322
2452
  const typeStats = this.all(
2323
- "SELECT type, COUNT(*) as count FROM memories WHERE repo = ? GROUP BY type",
2324
- [repo]
2453
+ "SELECT type, COUNT(*) as count FROM memories WHERE owner = ? AND repo = ? GROUP BY type",
2454
+ [owner, repo]
2325
2455
  );
2326
2456
  const byType = {};
2327
2457
  typeStats.forEach((t) => {
2328
2458
  byType[t.type] = t.count;
2329
2459
  });
2330
2460
  const taskRows = this.all(
2331
- "SELECT status, COUNT(*) as count FROM tasks WHERE repo = ? GROUP BY status",
2332
- [repo]
2461
+ "SELECT status, COUNT(*) as count FROM tasks WHERE owner = ? AND repo = ? GROUP BY status",
2462
+ [owner, repo]
2333
2463
  );
2334
2464
  const taskStats = this.buildTaskStats(taskRows);
2335
2465
  const topMemoriesRows = this.all(
2336
- "SELECT * FROM memories WHERE repo = ? ORDER BY importance DESC, created_at DESC LIMIT 5",
2337
- [repo]
2466
+ "SELECT * FROM memories WHERE owner = ? AND repo = ? ORDER BY importance DESC, created_at DESC LIMIT 5",
2467
+ [owner, repo]
2338
2468
  );
2339
2469
  const topMemories = topMemoriesRows.map((r) => this.rowToMemoryEntry(r));
2340
2470
  return {
@@ -2422,12 +2552,18 @@ var SystemEntity = class extends BaseEntity {
2422
2552
  totalRepos
2423
2553
  };
2424
2554
  }
2425
- getRepoDetails(repo) {
2426
- const memoryCountRow = this.get("SELECT COUNT(*) as count FROM memories WHERE repo = ?", [repo]);
2427
- const taskCountRow = this.get("SELECT COUNT(*) as count FROM tasks WHERE repo = ?", [repo]);
2555
+ getRepoDetails(owner, repo) {
2556
+ const memoryCountRow = this.get(
2557
+ "SELECT COUNT(*) as count FROM memories WHERE owner = ? AND repo = ?",
2558
+ [owner, repo]
2559
+ );
2560
+ const taskCountRow = this.get(
2561
+ "SELECT COUNT(*) as count FROM tasks WHERE owner = ? AND repo = ?",
2562
+ [owner, repo]
2563
+ );
2428
2564
  const languagesRows = this.all(
2429
- "SELECT DISTINCT language FROM memories WHERE repo = ? AND language IS NOT NULL",
2430
- [repo]
2565
+ "SELECT DISTINCT language FROM memories WHERE owner = ? AND repo = ? AND language IS NOT NULL",
2566
+ [owner, repo]
2431
2567
  );
2432
2568
  const languages = languagesRows.map((r) => r.language);
2433
2569
  return {
@@ -2441,19 +2577,33 @@ var SystemEntity = class extends BaseEntity {
2441
2577
 
2442
2578
  // src/mcp/entities/summary.ts
2443
2579
  var SummaryEntity = class extends BaseEntity {
2444
- getSummary(repo) {
2580
+ getSummary(owner, repo) {
2445
2581
  const row = this.get(
2446
- "SELECT summary, updated_at FROM memory_summary WHERE repo = ?",
2447
- [repo]
2582
+ "SELECT summary, updated_at FROM memory_summary WHERE owner = ? AND repo = ?",
2583
+ [owner, repo]
2448
2584
  );
2449
2585
  return row || null;
2450
2586
  }
2451
- upsertSummary(repo, summary) {
2452
- this.run(
2453
- `INSERT INTO memory_summary (repo, summary, updated_at) VALUES (?, ?, ?)
2454
- ON CONFLICT(repo) DO UPDATE SET summary = excluded.summary, updated_at = excluded.updated_at`,
2455
- [repo, summary, (/* @__PURE__ */ new Date()).toISOString()]
2456
- );
2587
+ upsertSummary(owner, repo, summary) {
2588
+ const existing = this.get("SELECT summary FROM memory_summary WHERE owner = ? AND repo = ?", [
2589
+ owner,
2590
+ repo
2591
+ ]);
2592
+ if (existing) {
2593
+ this.run("UPDATE memory_summary SET summary = ?, updated_at = ? WHERE owner = ? AND repo = ?", [
2594
+ summary,
2595
+ (/* @__PURE__ */ new Date()).toISOString(),
2596
+ owner,
2597
+ repo
2598
+ ]);
2599
+ } else {
2600
+ this.run("INSERT INTO memory_summary (owner, repo, summary, updated_at) VALUES (?, ?, ?, ?)", [
2601
+ owner,
2602
+ repo,
2603
+ summary,
2604
+ (/* @__PURE__ */ new Date()).toISOString()
2605
+ ]);
2606
+ }
2457
2607
  }
2458
2608
  };
2459
2609
 
@@ -2463,8 +2613,8 @@ var StandardEntity = class extends BaseEntity {
2463
2613
  this.run(
2464
2614
  `INSERT INTO coding_standards (
2465
2615
  id, code, title, content, parent_id, context, version, language, stack,
2466
- is_global, repo, tags, metadata, created_at, updated_at, hit_count, last_used_at, agent, model
2467
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2616
+ is_global, owner, repo, tags, metadata, created_at, updated_at, hit_count, last_used_at, agent, model
2617
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2468
2618
  [
2469
2619
  entry.id,
2470
2620
  entry.code ?? null,
@@ -2476,6 +2626,7 @@ var StandardEntity = class extends BaseEntity {
2476
2626
  entry.language ?? null,
2477
2627
  entry.stack.length > 0 ? JSON.stringify(entry.stack) : null,
2478
2628
  entry.is_global ? 1 : 0,
2629
+ entry.owner ?? "",
2479
2630
  entry.repo ?? null,
2480
2631
  entry.tags.length > 0 ? JSON.stringify(entry.tags) : null,
2481
2632
  Object.keys(entry.metadata).length > 0 ? JSON.stringify(entry.metadata) : null,
@@ -2495,8 +2646,8 @@ var StandardEntity = class extends BaseEntity {
2495
2646
  this.run(
2496
2647
  `INSERT INTO coding_standards (
2497
2648
  id, code, title, content, parent_id, context, version, language, stack,
2498
- is_global, repo, tags, metadata, created_at, updated_at, hit_count, last_used_at, agent, model
2499
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2649
+ is_global, owner, repo, tags, metadata, created_at, updated_at, hit_count, last_used_at, agent, model
2650
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2500
2651
  [
2501
2652
  entry.id,
2502
2653
  entry.code ?? null,
@@ -2508,6 +2659,7 @@ var StandardEntity = class extends BaseEntity {
2508
2659
  entry.language ?? null,
2509
2660
  entry.stack.length > 0 ? JSON.stringify(entry.stack) : null,
2510
2661
  entry.is_global ? 1 : 0,
2662
+ entry.owner ?? "",
2511
2663
  entry.repo ?? null,
2512
2664
  entry.tags.length > 0 ? JSON.stringify(entry.tags) : null,
2513
2665
  Object.keys(entry.metadata).length > 0 ? JSON.stringify(entry.metadata) : null,
@@ -2533,7 +2685,7 @@ var StandardEntity = class extends BaseEntity {
2533
2685
  return row ? this.rowToEntry(row) : null;
2534
2686
  }
2535
2687
  search(options) {
2536
- const { query, context, version, language, stack, tag, repo, is_global, limit = 20, offset = 0 } = options;
2688
+ const { query, context, version, language, stack, tag, owner, repo, is_global, limit = 20, offset = 0 } = options;
2537
2689
  const where = [];
2538
2690
  const params = [];
2539
2691
  if (query) {
@@ -2561,8 +2713,13 @@ var StandardEntity = class extends BaseEntity {
2561
2713
  params.push(`%${tag}%`);
2562
2714
  }
2563
2715
  if (repo !== void 0) {
2564
- where.push("(repo = ? OR is_global = 1)");
2565
- params.push(repo);
2716
+ if (owner !== void 0) {
2717
+ where.push("((owner = ? AND repo = ?) OR is_global = 1)");
2718
+ params.push(owner, repo);
2719
+ } else {
2720
+ where.push("(repo = ? OR is_global = 1)");
2721
+ params.push(repo);
2722
+ }
2566
2723
  }
2567
2724
  if (is_global !== void 0) {
2568
2725
  where.push("is_global = ?");
@@ -2611,11 +2768,12 @@ var StandardEntity = class extends BaseEntity {
2611
2768
  *
2612
2769
  * @param content Raw content of the new standard to check.
2613
2770
  * @param incomingVersion Version of the new standard (e.g. "2.0.0").
2771
+ * @param owner Owner filter; pass undefined for global standards.
2614
2772
  * @param repo Repo filter; pass undefined for global standards.
2615
2773
  * @param threshold Cosine-similarity cutoff (default 0.82 — stricter than memory).
2616
2774
  */
2617
- checkConflicts(content, incomingVersion, repo, incomingLanguage, incomingStack, threshold = 0.82) {
2618
- const candidates = this.search({ repo, limit: 80, offset: 0 });
2775
+ checkConflicts(content, incomingVersion, owner, repo, incomingLanguage, incomingStack, threshold = 0.82) {
2776
+ const candidates = this.search({ repo, owner, limit: 80, offset: 0 });
2619
2777
  if (candidates.length === 0) return null;
2620
2778
  const queryVector = this.computeVector(content);
2621
2779
  for (const standard of candidates) {
@@ -2716,6 +2874,7 @@ var StandardEntity = class extends BaseEntity {
2716
2874
  language: row.language ?? null,
2717
2875
  stack: this.safeJSONParse(row.stack, []),
2718
2876
  is_global: row.is_global === 1,
2877
+ owner: row.owner,
2719
2878
  repo: row.repo ?? null,
2720
2879
  tags: this.safeJSONParse(row.tags, []),
2721
2880
  metadata: this.safeJSONParse(row.metadata, {}),
@@ -2735,6 +2894,7 @@ var HandoffEntity = class extends BaseEntity {
2735
2894
  rowToHandoff(row) {
2736
2895
  return {
2737
2896
  id: row.id,
2897
+ owner: row.owner,
2738
2898
  repo: row.repo,
2739
2899
  from_agent: row.from_agent,
2740
2900
  to_agent: row.to_agent ?? null,
@@ -2751,6 +2911,7 @@ var HandoffEntity = class extends BaseEntity {
2751
2911
  rowToClaim(row) {
2752
2912
  return {
2753
2913
  id: row.id,
2914
+ owner: row.owner,
2754
2915
  repo: row.repo,
2755
2916
  task_id: row.task_id,
2756
2917
  task_code: "task_code" in row ? row.task_code ?? null : null,
@@ -2765,10 +2926,11 @@ var HandoffEntity = class extends BaseEntity {
2765
2926
  const now = (/* @__PURE__ */ new Date()).toISOString();
2766
2927
  const id = randomUUID();
2767
2928
  this.run(
2768
- `INSERT INTO handoffs (id, repo, from_agent, to_agent, task_id, summary, context, status, created_at, updated_at, expires_at)
2769
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2929
+ `INSERT INTO handoffs (id, owner, repo, from_agent, to_agent, task_id, summary, context, status, created_at, updated_at, expires_at)
2930
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2770
2931
  [
2771
2932
  id,
2933
+ params.owner,
2772
2934
  params.repo,
2773
2935
  params.from_agent,
2774
2936
  params.to_agent ?? null,
@@ -2784,8 +2946,8 @@ var HandoffEntity = class extends BaseEntity {
2784
2946
  return this.getHandoffById(id);
2785
2947
  }
2786
2948
  listHandoffs(params) {
2787
- const conditions = ["repo = ?"];
2788
- const values = [params.repo];
2949
+ const conditions = ["owner = ?", "repo = ?"];
2950
+ const values = [params.owner, params.repo];
2789
2951
  if (params.status) {
2790
2952
  conditions.push("status = ?");
2791
2953
  values.push(params.status);
@@ -2806,7 +2968,7 @@ var HandoffEntity = class extends BaseEntity {
2806
2968
  FROM handoffs h
2807
2969
  LEFT JOIN tasks t ON h.task_id = t.id
2808
2970
  WHERE ${conditions.map(
2809
- (condition) => condition.replace(/\brepo\b/g, "h.repo").replace(/\bstatus\b/g, "h.status").replace(/\bto_agent\b/g, "h.to_agent").replace(/\bfrom_agent\b/g, "h.from_agent")
2971
+ (condition) => condition.replace(/\bowner\b/g, "h.owner").replace(/\brepo\b/g, "h.repo").replace(/\bstatus\b/g, "h.status").replace(/\bto_agent\b/g, "h.to_agent").replace(/\bfrom_agent\b/g, "h.from_agent")
2810
2972
  ).join(" AND ")}
2811
2973
  ORDER BY h.created_at DESC LIMIT ? OFFSET ?`,
2812
2974
  values
@@ -2844,10 +3006,11 @@ var HandoffEntity = class extends BaseEntity {
2844
3006
  const id = randomUUID();
2845
3007
  this.run("UPDATE claims SET released_at = ? WHERE task_id = ? AND released_at IS NULL", [now, params.task_id]);
2846
3008
  this.run(
2847
- `INSERT INTO claims (id, repo, task_id, agent, role, claimed_at, released_at, metadata)
2848
- VALUES (?, ?, ?, ?, ?, ?, NULL, ?)`,
3009
+ `INSERT INTO claims (id, owner, repo, task_id, agent, role, claimed_at, released_at, metadata)
3010
+ VALUES (?, ?, ?, ?, ?, ?, ?, NULL, ?)`,
2849
3011
  [
2850
3012
  id,
3013
+ params.owner,
2851
3014
  params.repo,
2852
3015
  params.task_id,
2853
3016
  params.agent,
@@ -2896,8 +3059,8 @@ var HandoffEntity = class extends BaseEntity {
2896
3059
  return result.changes;
2897
3060
  }
2898
3061
  listClaims(params) {
2899
- const conditions = ["repo = ?"];
2900
- const values = [params.repo];
3062
+ const conditions = params.owner ? ["owner = ?", "repo = ?"] : ["repo = ?"];
3063
+ const values = params.owner ? [params.owner, params.repo] : [params.repo];
2901
3064
  if (params.agent) {
2902
3065
  conditions.push("agent = ?");
2903
3066
  values.push(params.agent);
@@ -2913,7 +3076,7 @@ var HandoffEntity = class extends BaseEntity {
2913
3076
  FROM claims c
2914
3077
  LEFT JOIN tasks t ON c.task_id = t.id
2915
3078
  WHERE ${conditions.map(
2916
- (condition) => condition.replace(/\brepo\b/g, "c.repo").replace(/\bagent\b/g, "c.agent").replace(/released_at/g, "c.released_at")
3079
+ (condition) => condition.replace(/\bowner\b/g, "c.owner").replace(/\brepo\b/g, "c.repo").replace(/\bagent\b/g, "c.agent").replace(/released_at/g, "c.released_at")
2917
3080
  ).join(" AND ")}
2918
3081
  ORDER BY c.claimed_at DESC LIMIT ? OFFSET ?`,
2919
3082
  values
@@ -3207,7 +3370,7 @@ var RealVectorStore = class {
3207
3370
  const extractor = await this.getExtractor();
3208
3371
  const output = await extractor(query, { pooling: "mean", normalize: true });
3209
3372
  const queryVector = Array.from(output.data);
3210
- const rows = kind === "standard" ? this.db.standards.getVectorCandidates(repo, 100).map((row) => ({ id: row.standard_id, vector: row.vector })) : this.db.memoryVectors.getVectorCandidates(repo, 100).map((row) => ({ id: row.memory_id, vector: row.vector }));
3373
+ const rows = kind === "standard" ? this.db.standards.getVectorCandidates(repo, 100).map((row) => ({ id: row.standard_id, vector: row.vector })) : this.db.memoryVectors.getVectorCandidates("", repo, 100).map((row) => ({ id: row.memory_id, vector: row.vector }));
3211
3374
  const results = rows.map((row) => {
3212
3375
  const memoryVector = JSON.parse(row.vector);
3213
3376
  return {
@@ -3324,10 +3487,21 @@ function inferRepoFromSession(session) {
3324
3487
  }
3325
3488
  return void 0;
3326
3489
  }
3490
+ function inferOwnerFromSession(session) {
3491
+ const roots = getFilesystemRoots(session);
3492
+ if (roots.length === 1) {
3493
+ const parts = roots[0].split(path5.sep).filter(Boolean);
3494
+ if (parts.length >= 2) {
3495
+ return parts[parts.length - 2];
3496
+ }
3497
+ }
3498
+ return void 0;
3499
+ }
3327
3500
 
3328
3501
  // src/mcp/tools/schemas.ts
3329
3502
  import { z } from "zod";
3330
3503
  var MemoryScopeSchema = z.object({
3504
+ owner: z.string().min(1),
3331
3505
  repo: z.string().min(1).transform(normalizeRepo),
3332
3506
  branch: z.string().optional(),
3333
3507
  folder: z.string().optional(),
@@ -3417,6 +3591,7 @@ var MemoryUpdateSchema = z.object({
3417
3591
  var MemorySearchSchema = z.object({
3418
3592
  query: z.string().min(3),
3419
3593
  prompt: z.string().optional(),
3594
+ owner: z.string().min(1),
3420
3595
  repo: z.string().min(1).transform(normalizeRepo),
3421
3596
  types: z.array(MemoryTypeSchema).optional(),
3422
3597
  minImportance: z.number().min(1).max(5).optional(),
@@ -3439,12 +3614,14 @@ var MemoryAcknowledgeSchema = z.object({
3439
3614
  message: "Either memory_id or code must be provided"
3440
3615
  });
3441
3616
  var MemoryRecapSchema = z.object({
3617
+ owner: z.string().min(1),
3442
3618
  repo: z.string().min(1).transform(normalizeRepo),
3443
3619
  limit: z.number().min(1).max(50).default(20),
3444
3620
  offset: z.number().min(0).default(0),
3445
3621
  structured: z.boolean().default(false)
3446
3622
  });
3447
3623
  var MemoryDeleteSchema = z.object({
3624
+ owner: z.string().optional().default(""),
3448
3625
  repo: z.string().min(1).transform(normalizeRepo).optional(),
3449
3626
  id: z.string().uuid().optional(),
3450
3627
  ids: z.array(z.string().uuid()).min(1).optional(),
@@ -3458,11 +3635,13 @@ var MemoryDeleteSchema = z.object({
3458
3635
  }
3459
3636
  );
3460
3637
  var MemorySummarizeSchema = z.object({
3638
+ owner: z.string().min(1),
3461
3639
  repo: z.string().min(1).transform(normalizeRepo),
3462
3640
  signals: z.array(z.string().max(200)).min(1),
3463
3641
  structured: z.boolean().default(false)
3464
3642
  });
3465
3643
  var MemorySynthesizeSchema = z.object({
3644
+ owner: z.string().min(1),
3466
3645
  repo: z.string().min(1).transform(normalizeRepo).optional(),
3467
3646
  objective: z.string().min(5),
3468
3647
  current_file_path: z.string().optional(),
@@ -3479,20 +3658,44 @@ var TaskMetadataSchema = z.record(z.string(), z.any()).optional().superRefine((m
3479
3658
  if (!metadata) return;
3480
3659
  if (metadata.required_skills !== void 0) {
3481
3660
  if (!Array.isArray(metadata.required_skills)) {
3482
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.required_skills must be an array of strings", path: ["metadata", "required_skills"] });
3661
+ ctx.addIssue({
3662
+ code: z.ZodIssueCode.custom,
3663
+ message: "metadata.required_skills must be an array of strings",
3664
+ path: ["metadata", "required_skills"]
3665
+ });
3483
3666
  } else if (metadata.required_skills.length === 0) {
3484
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.required_skills must not be empty when present", path: ["metadata", "required_skills"] });
3667
+ ctx.addIssue({
3668
+ code: z.ZodIssueCode.custom,
3669
+ message: "metadata.required_skills must not be empty when present",
3670
+ path: ["metadata", "required_skills"]
3671
+ });
3485
3672
  } else if (!metadata.required_skills.every((s) => typeof s === "string" && s.length > 0)) {
3486
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.required_skills must be an array of non-empty strings", path: ["metadata", "required_skills"] });
3673
+ ctx.addIssue({
3674
+ code: z.ZodIssueCode.custom,
3675
+ message: "metadata.required_skills must be an array of non-empty strings",
3676
+ path: ["metadata", "required_skills"]
3677
+ });
3487
3678
  }
3488
3679
  }
3489
3680
  if (metadata.fsm_gates !== void 0) {
3490
3681
  if (!Array.isArray(metadata.fsm_gates)) {
3491
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.fsm_gates must be an array of strings", path: ["metadata", "fsm_gates"] });
3682
+ ctx.addIssue({
3683
+ code: z.ZodIssueCode.custom,
3684
+ message: "metadata.fsm_gates must be an array of strings",
3685
+ path: ["metadata", "fsm_gates"]
3686
+ });
3492
3687
  } else if (metadata.fsm_gates.length === 0) {
3493
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.fsm_gates must not be empty when present", path: ["metadata", "fsm_gates"] });
3688
+ ctx.addIssue({
3689
+ code: z.ZodIssueCode.custom,
3690
+ message: "metadata.fsm_gates must not be empty when present",
3691
+ path: ["metadata", "fsm_gates"]
3692
+ });
3494
3693
  } else if (!metadata.fsm_gates.every((s) => typeof s === "string" && s.length > 0)) {
3495
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "metadata.fsm_gates must be an array of non-empty strings", path: ["metadata", "fsm_gates"] });
3694
+ ctx.addIssue({
3695
+ code: z.ZodIssueCode.custom,
3696
+ message: "metadata.fsm_gates must be an array of non-empty strings",
3697
+ path: ["metadata", "fsm_gates"]
3698
+ });
3496
3699
  }
3497
3700
  }
3498
3701
  });
@@ -3514,6 +3717,7 @@ var SingleTaskCreateSchema = z.object({
3514
3717
  est_tokens: z.number().int().min(0).optional()
3515
3718
  });
3516
3719
  var TaskCreateSchema = z.object({
3720
+ owner: z.string().min(1),
3517
3721
  repo: z.string().min(1).transform(normalizeRepo),
3518
3722
  // Allow single task fields at top level (backward compatibility & single use)
3519
3723
  task_code: z.string().min(1).optional(),
@@ -3542,10 +3746,12 @@ var TaskCreateSchema = z.object({
3542
3746
  { message: "Either 'tasks' array or single task fields (phase, title, description) must be provided" }
3543
3747
  );
3544
3748
  var TaskCreateInteractiveSchema = SingleTaskCreateSchema.partial().extend({
3749
+ owner: z.string().optional().default(""),
3545
3750
  repo: z.string().min(1).transform(normalizeRepo).optional(),
3546
3751
  structured: z.boolean().default(false)
3547
3752
  });
3548
3753
  var TaskUpdateSchema = z.object({
3754
+ owner: z.string().optional().default(""),
3549
3755
  repo: z.string().min(1).transform(normalizeRepo),
3550
3756
  id: z.string().uuid().optional(),
3551
3757
  ids: z.array(z.string().uuid()).min(1).optional(),
@@ -3576,6 +3782,7 @@ var TaskUpdateSchema = z.object({
3576
3782
  message: "At least one field besides repo and id/ids must be provided for update"
3577
3783
  });
3578
3784
  var TaskListSchema = z.object({
3785
+ owner: z.string().min(1),
3579
3786
  repo: z.string().min(1).transform(normalizeRepo),
3580
3787
  status: z.string().optional(),
3581
3788
  phase: z.string().optional(),
@@ -3585,6 +3792,7 @@ var TaskListSchema = z.object({
3585
3792
  structured: z.boolean().default(false)
3586
3793
  });
3587
3794
  var TaskSearchSchema = z.object({
3795
+ owner: z.string().min(1),
3588
3796
  repo: z.string().min(1).transform(normalizeRepo),
3589
3797
  query: z.string().min(1),
3590
3798
  status: z.string().optional(),
@@ -3595,6 +3803,7 @@ var TaskSearchSchema = z.object({
3595
3803
  structured: z.boolean().default(false)
3596
3804
  });
3597
3805
  var TaskDeleteSchema = z.object({
3806
+ owner: z.string().optional().default(""),
3598
3807
  repo: z.string().min(1).transform(normalizeRepo),
3599
3808
  id: z.string().uuid().optional(),
3600
3809
  ids: z.array(z.string().uuid()).min(1).optional(),
@@ -3618,6 +3827,7 @@ var StandardDetailSchema = z.object({
3618
3827
  message: "Either id or code must be provided"
3619
3828
  });
3620
3829
  var StandardDeleteSchema = z.object({
3830
+ owner: z.string().optional().default(""),
3621
3831
  repo: z.string().min(1).transform(normalizeRepo).optional(),
3622
3832
  id: z.string().uuid().optional(),
3623
3833
  ids: z.array(z.string().uuid()).min(1).optional(),
@@ -3631,6 +3841,7 @@ var StandardDeleteSchema = z.object({
3631
3841
  }
3632
3842
  );
3633
3843
  var TaskGetSchema = z.object({
3844
+ owner: z.string().optional().default(""),
3634
3845
  repo: z.string().min(1).transform(normalizeRepo),
3635
3846
  id: z.string().uuid().optional(),
3636
3847
  task_code: z.string().optional(),
@@ -3640,6 +3851,7 @@ var TaskGetSchema = z.object({
3640
3851
  });
3641
3852
  var HandoffStatusSchema = z.enum(["pending", "accepted", "rejected", "expired"]);
3642
3853
  var HandoffCreateSchema = z.object({
3854
+ owner: z.string().min(1),
3643
3855
  repo: z.string().min(1).transform(normalizeRepo),
3644
3856
  from_agent: z.string().min(1),
3645
3857
  to_agent: z.string().min(1).optional(),
@@ -3663,6 +3875,7 @@ var HandoffUpdateSchema = z.object({
3663
3875
  structured: z.boolean().default(false)
3664
3876
  });
3665
3877
  var HandoffListSchema = z.object({
3878
+ owner: z.string().min(1),
3666
3879
  repo: z.string().min(1).transform(normalizeRepo),
3667
3880
  status: HandoffStatusSchema.optional(),
3668
3881
  from_agent: z.string().min(1).optional(),
@@ -3672,6 +3885,7 @@ var HandoffListSchema = z.object({
3672
3885
  structured: z.boolean().default(false)
3673
3886
  });
3674
3887
  var TaskClaimSchema = z.object({
3888
+ owner: z.string().min(1),
3675
3889
  repo: z.string().min(1).transform(normalizeRepo),
3676
3890
  task_id: z.string().uuid().optional(),
3677
3891
  task_code: z.string().optional(),
@@ -3685,6 +3899,7 @@ var TaskClaimSchema = z.object({
3685
3899
  message: "Provide either task_id or task_code, not both"
3686
3900
  });
3687
3901
  var ClaimListSchema = z.object({
3902
+ owner: z.string().min(1),
3688
3903
  repo: z.string().min(1).transform(normalizeRepo),
3689
3904
  agent: z.string().min(1).optional(),
3690
3905
  active_only: z.boolean().default(true),
@@ -3693,6 +3908,7 @@ var ClaimListSchema = z.object({
3693
3908
  structured: z.boolean().default(false)
3694
3909
  });
3695
3910
  var ClaimReleaseSchema = z.object({
3911
+ owner: z.string().optional().default(""),
3696
3912
  repo: z.string().min(1).transform(normalizeRepo),
3697
3913
  task_id: z.string().uuid().optional(),
3698
3914
  task_code: z.string().optional(),
@@ -3711,6 +3927,7 @@ var StandardStoreSchema = z.object({
3711
3927
  version: z.string().optional(),
3712
3928
  language: z.string().optional(),
3713
3929
  stack: z.array(z.string()).optional(),
3930
+ owner: z.string().optional().default(""),
3714
3931
  repo: z.string().transform(normalizeRepo).optional(),
3715
3932
  is_global: z.boolean().optional(),
3716
3933
  tags: z.array(z.string().min(1)).min(1).optional(),
@@ -3738,6 +3955,7 @@ var StandardUpdateSchema = z.object({
3738
3955
  version: z.string().optional(),
3739
3956
  language: z.string().optional(),
3740
3957
  stack: z.array(z.string().min(1)).min(1).optional(),
3958
+ owner: z.string().optional().default(""),
3741
3959
  repo: z.string().transform(normalizeRepo).optional(),
3742
3960
  is_global: z.boolean().optional(),
3743
3961
  tags: z.array(z.string().min(1)).min(1).optional(),
@@ -3760,6 +3978,7 @@ var StandardSearchSchema = z.object({
3760
3978
  language: z.string().optional(),
3761
3979
  context: z.string().optional(),
3762
3980
  version: z.string().optional(),
3981
+ owner: z.string().optional().default(""),
3763
3982
  repo: z.string().transform(normalizeRepo).optional(),
3764
3983
  is_global: z.boolean().optional(),
3765
3984
  limit: z.number().min(1).max(100).default(20),
@@ -3782,7 +4001,8 @@ var TOOL_DEFINITIONS = [
3782
4001
  inputSchema: {
3783
4002
  type: "object",
3784
4003
  properties: {
3785
- repo: { type: "string", description: "Repository name. Optional when a single MCP root is active." },
4004
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4005
+ repo: { type: "string", description: "Repository/project name. Optional when a single MCP root is active." },
3786
4006
  objective: { type: "string", minLength: 5, description: "Question or synthesis objective." },
3787
4007
  current_file_path: {
3788
4008
  type: "string",
@@ -3799,7 +4019,7 @@ var TOOL_DEFINITIONS = [
3799
4019
  max_tokens: { type: "number", minimum: 128, maximum: 4e3, default: 1200 },
3800
4020
  structured: { type: "boolean", default: false, description: "If true, returns structured JSON results." }
3801
4021
  },
3802
- required: ["objective"]
4022
+ required: ["owner", "objective"]
3803
4023
  },
3804
4024
  outputSchema: {
3805
4025
  type: "object",
@@ -3828,6 +4048,10 @@ var TOOL_DEFINITIONS = [
3828
4048
  inputSchema: {
3829
4049
  type: "object",
3830
4050
  properties: {
4051
+ owner: {
4052
+ type: "string",
4053
+ description: "Organization/namespace (e.g., GitHub org or username)"
4054
+ },
3831
4055
  repo: {
3832
4056
  type: "string",
3833
4057
  description: "Repository name. Optional when it can be inferred from MCP roots or elicited from the user."
@@ -3962,12 +4186,13 @@ var TOOL_DEFINITIONS = [
3962
4186
  scope: {
3963
4187
  type: "object",
3964
4188
  properties: {
3965
- repo: { type: "string", description: "Repository name" },
3966
- branch: { type: "string" },
3967
- folder: { type: "string" },
3968
- language: { type: "string" }
4189
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4190
+ repo: { type: "string", description: "Repository/project name" },
4191
+ branch: { type: "string", description: "Git branch this memory relates to" },
4192
+ folder: { type: "string", description: "Subdirectory within the repo" },
4193
+ language: { type: "string", description: "Programming language (e.g., 'typescript', 'python')" }
3969
4194
  },
3970
- required: ["repo"]
4195
+ required: ["owner", "repo"]
3971
4196
  },
3972
4197
  tags: {
3973
4198
  type: "array",
@@ -3982,7 +4207,11 @@ var TOOL_DEFINITIONS = [
3982
4207
  type: "boolean",
3983
4208
  description: "If true, this memory is shared across all repositories"
3984
4209
  },
3985
- ttlDays: { type: "number", minimum: 1 },
4210
+ ttlDays: {
4211
+ type: "number",
4212
+ minimum: 1,
4213
+ description: "Time-to-live in days. After this period, the memory expires."
4214
+ },
3986
4215
  supersedes: {
3987
4216
  type: "string",
3988
4217
  description: "Optional memory ID (UUID) or memory code to supersede. Resolved before storing."
@@ -3992,29 +4221,34 @@ var TOOL_DEFINITIONS = [
3992
4221
  items: {
3993
4222
  type: "object",
3994
4223
  properties: {
3995
- type: { type: "string", enum: ["code_fact", "decision", "mistake", "pattern", "task_archive"] },
3996
- title: { type: "string", minLength: 3, maxLength: 100 },
3997
- content: { type: "string", minLength: 10 },
3998
- importance: { type: "number", minimum: 1, maximum: 5 },
3999
- agent: { type: "string" },
4000
- role: { type: "string", default: "unknown" },
4001
- model: { type: "string" },
4224
+ type: {
4225
+ type: "string",
4226
+ enum: ["code_fact", "decision", "mistake", "pattern", "task_archive"],
4227
+ description: "Type of durable knowledge being stored"
4228
+ },
4229
+ title: { type: "string", minLength: 3, maxLength: 100, description: "Short human-readable title" },
4230
+ content: { type: "string", minLength: 10, description: "The memory content" },
4231
+ importance: { type: "number", minimum: 1, maximum: 5, description: "Importance score (1-5)" },
4232
+ agent: { type: "string", description: "Name of the agent creating this memory" },
4233
+ role: { type: "string", default: "unknown", description: "Role of the agent creating this memory" },
4234
+ model: { type: "string", description: "AI model used by the agent" },
4002
4235
  scope: {
4003
4236
  type: "object",
4004
4237
  properties: {
4005
- repo: { type: "string" },
4006
- branch: { type: "string" },
4007
- folder: { type: "string" },
4008
- language: { type: "string" }
4238
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4239
+ repo: { type: "string", description: "Repository/project name" },
4240
+ branch: { type: "string", description: "Git branch this memory relates to" },
4241
+ folder: { type: "string", description: "Subdirectory within the repo" },
4242
+ language: { type: "string", description: "Programming language" }
4009
4243
  },
4010
- required: ["repo"]
4244
+ required: ["owner", "repo"]
4011
4245
  },
4012
- code: { type: "string" },
4013
- ttlDays: { type: "number", minimum: 1 },
4014
- supersedes: { type: "string" },
4015
- tags: { type: "array", items: { type: "string" } },
4016
- metadata: { type: "object" },
4017
- is_global: { type: "boolean", default: false }
4246
+ code: { type: "string", description: "Optional custom code. Auto-generated if omitted." },
4247
+ ttlDays: { type: "number", minimum: 1, description: "Time-to-live in days" },
4248
+ supersedes: { type: "string", description: "UUID or code of a memory this entry replaces" },
4249
+ tags: { type: "array", items: { type: "string" }, description: "Technology stack tags" },
4250
+ metadata: { type: "object", description: "Structured metadata for non-title context" },
4251
+ is_global: { type: "boolean", default: false, description: "If true, shared across all repositories" }
4018
4252
  },
4019
4253
  required: ["type", "title", "content", "importance", "agent", "model", "scope"]
4020
4254
  },
@@ -4136,9 +4370,14 @@ var TOOL_DEFINITIONS = [
4136
4370
  inputSchema: {
4137
4371
  type: "object",
4138
4372
  properties: {
4139
- query: { type: "string", minLength: 3 },
4140
- prompt: { type: "string" },
4141
- repo: { type: "string" },
4373
+ query: {
4374
+ type: "string",
4375
+ minLength: 3,
4376
+ description: "Search keyword to match against memory titles and content"
4377
+ },
4378
+ prompt: { type: "string", description: "Natural language prompt for semantic search" },
4379
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4380
+ repo: { type: "string", description: "Repository/project name" },
4142
4381
  current_tags: {
4143
4382
  type: "array",
4144
4383
  items: { type: "string" },
@@ -4149,21 +4388,27 @@ var TOOL_DEFINITIONS = [
4149
4388
  items: {
4150
4389
  type: "string",
4151
4390
  enum: ["code_fact", "decision", "mistake", "pattern", "task_archive"]
4152
- }
4391
+ },
4392
+ description: "Filter by memory type(s)"
4153
4393
  },
4154
- minImportance: { type: "number", minimum: 1, maximum: 5 },
4394
+ minImportance: { type: "number", minimum: 1, maximum: 5, description: "Minimum importance threshold (1-5)" },
4155
4395
  limit: { type: "number", minimum: 1, maximum: 100, default: 5 },
4156
4396
  offset: { type: "number", minimum: 0, default: 0 },
4157
4397
  includeRecap: { type: "boolean", default: false },
4158
- current_file_path: { type: "string" },
4159
- include_archived: { type: "boolean", default: false },
4398
+ current_file_path: { type: "string", description: "Absolute file path for workspace-local grounding" },
4399
+ include_archived: {
4400
+ type: "boolean",
4401
+ default: false,
4402
+ description: "Include archived/expired memories in results"
4403
+ },
4160
4404
  scope: {
4161
4405
  type: "object",
4162
4406
  properties: {
4163
- repo: { type: "string" },
4164
- branch: { type: "string" },
4165
- folder: { type: "string" },
4166
- language: { type: "string" }
4407
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4408
+ repo: { type: "string", description: "Repository/project name" },
4409
+ branch: { type: "string", description: "Git branch filter" },
4410
+ folder: { type: "string", description: "Subdirectory filter" },
4411
+ language: { type: "string", description: "Programming language filter" }
4167
4412
  }
4168
4413
  },
4169
4414
  structured: {
@@ -4172,7 +4417,7 @@ var TOOL_DEFINITIONS = [
4172
4417
  description: "If true, returns structured JSON without the text content summary."
4173
4418
  }
4174
4419
  },
4175
- required: ["query", "repo"]
4420
+ required: ["owner", "query", "repo"]
4176
4421
  },
4177
4422
  outputSchema: {
4178
4423
  type: "object",
@@ -4215,7 +4460,8 @@ var TOOL_DEFINITIONS = [
4215
4460
  inputSchema: {
4216
4461
  type: "object",
4217
4462
  properties: {
4218
- repo: { type: "string", description: "Repository name" },
4463
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4464
+ repo: { type: "string", description: "Repository/project name" },
4219
4465
  signals: {
4220
4466
  type: "array",
4221
4467
  items: { type: "string", maxLength: 200 },
@@ -4224,7 +4470,7 @@ var TOOL_DEFINITIONS = [
4224
4470
  },
4225
4471
  structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the summary." }
4226
4472
  },
4227
- required: ["repo", "signals"]
4473
+ required: ["owner", "repo", "signals"]
4228
4474
  },
4229
4475
  outputSchema: {
4230
4476
  type: "object",
@@ -4343,7 +4589,8 @@ var TOOL_DEFINITIONS = [
4343
4589
  inputSchema: {
4344
4590
  type: "object",
4345
4591
  properties: {
4346
- repo: { type: "string", description: "Repository name (required)" },
4592
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4593
+ repo: { type: "string", description: "Repository/project name (required)" },
4347
4594
  limit: {
4348
4595
  type: "number",
4349
4596
  minimum: 1,
@@ -4363,7 +4610,7 @@ var TOOL_DEFINITIONS = [
4363
4610
  description: "If true, returns structured JSON without the text content summary."
4364
4611
  }
4365
4612
  },
4366
- required: ["repo"]
4613
+ required: ["owner", "repo"]
4367
4614
  },
4368
4615
  outputSchema: {
4369
4616
  type: "object",
@@ -4416,7 +4663,8 @@ var TOOL_DEFINITIONS = [
4416
4663
  inputSchema: {
4417
4664
  type: "object",
4418
4665
  properties: {
4419
- repo: { type: "string", description: "Repository name" },
4666
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4667
+ repo: { type: "string", description: "Repository/project name" },
4420
4668
  task_code: { type: "string", description: "Unique task code (e.g. TASK-001) (Required for single task)" },
4421
4669
  phase: { type: "string", description: "Project phase (Required for single task)" },
4422
4670
  title: {
@@ -4442,11 +4690,11 @@ var TOOL_DEFINITIONS = [
4442
4690
  default: 3,
4443
4691
  description: "Task priority where 1=Low, 2=Normal, 3=Medium, 4=High, 5=Critical."
4444
4692
  },
4445
- agent: { type: "string" },
4446
- role: { type: "string" },
4447
- doc_path: { type: "string" },
4448
- tags: { type: "array", items: { type: "string" } },
4449
- metadata: { type: "object" },
4693
+ agent: { type: "string", description: "Agent assigned to this task" },
4694
+ role: { type: "string", description: "Role of the assigned agent" },
4695
+ doc_path: { type: "string", description: "Path to related documentation file" },
4696
+ tags: { type: "array", items: { type: "string" }, description: "Tags for categorization" },
4697
+ metadata: { type: "object", description: "Structured metadata for additional context" },
4450
4698
  parent_id: {
4451
4699
  type: "string",
4452
4700
  description: "Optional parent task ID (UUID) or parent task code (e.g. TASK-001). Resolved to UUID before storing."
@@ -4461,14 +4709,14 @@ var TOOL_DEFINITIONS = [
4461
4709
  items: {
4462
4710
  type: "object",
4463
4711
  properties: {
4464
- task_code: { type: "string" },
4465
- phase: { type: "string" },
4466
- title: { type: "string", minLength: 3, maxLength: 100 },
4712
+ task_code: { type: "string", description: "Unique task code (e.g. TASK-001)" },
4713
+ phase: { type: "string", description: "Project phase" },
4714
+ title: { type: "string", minLength: 3, maxLength: 100, description: "Task objective" },
4467
4715
  description: {
4468
4716
  type: "string",
4469
4717
  description: "Detailed description. MUST follow format: 1. Context & Analysis, 2. Step & Implementation, 3. Acceptance & Verification"
4470
4718
  },
4471
- status: { type: "string", enum: ["backlog", "pending"], default: "backlog" },
4719
+ status: { type: "string", enum: ["backlog", "pending"], default: "backlog", description: "Task status" },
4472
4720
  priority: {
4473
4721
  type: "number",
4474
4722
  minimum: 1,
@@ -4476,11 +4724,11 @@ var TOOL_DEFINITIONS = [
4476
4724
  default: 3,
4477
4725
  description: "Task priority where 1=Low, 2=Normal, 3=Medium, 4=High, 5=Critical."
4478
4726
  },
4479
- agent: { type: "string" },
4480
- role: { type: "string" },
4481
- doc_path: { type: "string" },
4482
- tags: { type: "array", items: { type: "string" } },
4483
- metadata: { type: "object" },
4727
+ agent: { type: "string", description: "Agent assigned to this task" },
4728
+ role: { type: "string", description: "Role of the assigned agent" },
4729
+ doc_path: { type: "string", description: "Path to related documentation file" },
4730
+ tags: { type: "array", items: { type: "string" }, description: "Tags for categorization" },
4731
+ metadata: { type: "object", description: "Structured metadata for additional context" },
4484
4732
  parent_id: {
4485
4733
  type: "string",
4486
4734
  description: "Optional parent task ID (UUID) or parent task code (e.g. TASK-001). Resolved to UUID before storing."
@@ -4497,7 +4745,7 @@ var TOOL_DEFINITIONS = [
4497
4745
  },
4498
4746
  structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
4499
4747
  },
4500
- required: ["repo"]
4748
+ required: ["owner", "repo"]
4501
4749
  },
4502
4750
  outputSchema: {
4503
4751
  type: "object",
@@ -4657,9 +4905,10 @@ var TOOL_DEFINITIONS = [
4657
4905
  inputSchema: {
4658
4906
  type: "object",
4659
4907
  properties: {
4908
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4660
4909
  repo: {
4661
4910
  type: "string",
4662
- description: "Repository name (required)"
4911
+ description: "Repository/project name (required)"
4663
4912
  },
4664
4913
  status: {
4665
4914
  type: "string",
@@ -4693,7 +4942,7 @@ var TOOL_DEFINITIONS = [
4693
4942
  description: "If true, returns structured JSON without the text content summary."
4694
4943
  }
4695
4944
  },
4696
- required: ["repo"]
4945
+ required: ["owner", "repo"]
4697
4946
  },
4698
4947
  outputSchema: {
4699
4948
  type: "object",
@@ -4733,7 +4982,8 @@ var TOOL_DEFINITIONS = [
4733
4982
  inputSchema: {
4734
4983
  type: "object",
4735
4984
  properties: {
4736
- repo: { type: "string", description: "Repository name" },
4985
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
4986
+ repo: { type: "string", description: "Repository/project name" },
4737
4987
  query: {
4738
4988
  type: "string",
4739
4989
  minLength: 1,
@@ -4746,7 +4996,7 @@ var TOOL_DEFINITIONS = [
4746
4996
  offset: { type: "number", minimum: 0, default: 0 },
4747
4997
  structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
4748
4998
  },
4749
- required: ["repo", "query"]
4999
+ required: ["owner", "repo", "query"]
4750
5000
  },
4751
5001
  outputSchema: {
4752
5002
  type: "object",
@@ -4790,7 +5040,8 @@ var TOOL_DEFINITIONS = [
4790
5040
  inputSchema: {
4791
5041
  type: "object",
4792
5042
  properties: {
4793
- repo: { type: "string", description: "Repository name" },
5043
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
5044
+ repo: { type: "string", description: "Repository/project name" },
4794
5045
  from_agent: { type: "string", description: "Agent creating the handoff" },
4795
5046
  to_agent: { type: "string", description: "Optional target agent" },
4796
5047
  task_id: { type: "string", format: "uuid", description: "Optional task id to associate" },
@@ -4803,7 +5054,7 @@ var TOOL_DEFINITIONS = [
4803
5054
  expires_at: { type: "string", description: "Optional expiration timestamp" },
4804
5055
  structured: { type: "boolean", default: false }
4805
5056
  },
4806
- required: ["repo", "from_agent", "summary"]
5057
+ required: ["owner", "repo", "from_agent", "summary"]
4807
5058
  },
4808
5059
  outputSchema: {
4809
5060
  type: "object",
@@ -4864,7 +5115,8 @@ var TOOL_DEFINITIONS = [
4864
5115
  inputSchema: {
4865
5116
  type: "object",
4866
5117
  properties: {
4867
- repo: { type: "string", description: "Repository name" },
5118
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
5119
+ repo: { type: "string", description: "Repository/project name" },
4868
5120
  status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
4869
5121
  from_agent: { type: "string" },
4870
5122
  to_agent: { type: "string" },
@@ -4872,7 +5124,7 @@ var TOOL_DEFINITIONS = [
4872
5124
  offset: { type: "number", minimum: 0, default: 0 },
4873
5125
  structured: { type: "boolean", default: false }
4874
5126
  },
4875
- required: ["repo"]
5127
+ required: ["owner", "repo"]
4876
5128
  },
4877
5129
  outputSchema: {
4878
5130
  type: "object",
@@ -4913,7 +5165,8 @@ var TOOL_DEFINITIONS = [
4913
5165
  inputSchema: {
4914
5166
  type: "object",
4915
5167
  properties: {
4916
- repo: { type: "string", description: "Repository name" },
5168
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
5169
+ repo: { type: "string", description: "Repository/project name" },
4917
5170
  task_id: {
4918
5171
  type: "string",
4919
5172
  format: "uuid",
@@ -4925,7 +5178,7 @@ var TOOL_DEFINITIONS = [
4925
5178
  metadata: { type: "object", description: "Optional claim metadata" },
4926
5179
  structured: { type: "boolean", default: false }
4927
5180
  },
4928
- required: ["repo", "agent"]
5181
+ required: ["owner", "repo", "agent"]
4929
5182
  },
4930
5183
  outputSchema: {
4931
5184
  type: "object",
@@ -4956,14 +5209,15 @@ var TOOL_DEFINITIONS = [
4956
5209
  inputSchema: {
4957
5210
  type: "object",
4958
5211
  properties: {
4959
- repo: { type: "string", description: "Repository name" },
5212
+ owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
5213
+ repo: { type: "string", description: "Repository/project name" },
4960
5214
  agent: { type: "string", description: "Optional agent filter" },
4961
5215
  active_only: { type: "boolean", description: "When true, return only unreleased claims" },
4962
5216
  limit: { type: "number", minimum: 1, maximum: 100, default: 20 },
4963
5217
  offset: { type: "number", minimum: 0, default: 0 },
4964
5218
  structured: { type: "boolean", default: false }
4965
5219
  },
4966
- required: ["repo"]
5220
+ required: ["owner", "repo"]
4967
5221
  },
4968
5222
  outputSchema: {
4969
5223
  type: "object",
@@ -5518,7 +5772,7 @@ function readResource(uri, db, session) {
5518
5772
  if (repoBase) {
5519
5773
  const { name, path: repoPath, query } = repoBase;
5520
5774
  if (repoPath === "summary") {
5521
- const summary = db.summaries.getSummary(name);
5775
+ const summary = db.summaries.getSummary("", name);
5522
5776
  const text = summary?.summary || `No summary available for repository: ${name}`;
5523
5777
  return {
5524
5778
  contents: [
@@ -5570,12 +5824,13 @@ function readResource(uri, db, session) {
5570
5824
  if (repoPath === "tasks") {
5571
5825
  const status = query.get("status");
5572
5826
  const priority = query.get("priority");
5827
+ const owner = parseRepoInput(name).owner;
5573
5828
  let tasks;
5574
5829
  if (status && status !== "all") {
5575
5830
  const statuses = status.split(",").map((s) => s.trim());
5576
- tasks = db.tasks.getTasksByMultipleStatuses(name, statuses);
5831
+ tasks = db.tasks.getTasksByMultipleStatuses(owner, name, statuses);
5577
5832
  } else {
5578
- tasks = db.tasks.getTasksByMultipleStatuses(name, ["backlog", "pending", "in_progress", "blocked"]);
5833
+ tasks = db.tasks.getTasksByMultipleStatuses(owner, name, ["backlog", "pending", "in_progress", "blocked"]);
5579
5834
  }
5580
5835
  if (priority) {
5581
5836
  const p = Number(priority);
@@ -5601,7 +5856,7 @@ function readResource(uri, db, session) {
5601
5856
  };
5602
5857
  }
5603
5858
  if (repoPath === "actions") {
5604
- const actions = db.actions.getRecentActions(name, 100);
5859
+ const actions = db.actions.getRecentActions("", name, 100);
5605
5860
  const payload = JSON.stringify(actions, null, 2);
5606
5861
  return {
5607
5862
  contents: [
@@ -5740,12 +5995,14 @@ async function getPrompt(name, args = {}, db, session) {
5740
5995
  throw new Error(`Prompt not found: ${name}`);
5741
5996
  }
5742
5997
  const inferredRepo = inferRepoFromSession(session);
5998
+ const inferredOwner = inferOwnerFromSession(session);
5743
5999
  const messages = prompt.messages.map((m) => {
5744
6000
  let text = m.content.text;
5745
6001
  for (const [key, value] of Object.entries(args)) {
5746
6002
  text = text.replace(new RegExp(`\\{{${key}\\}}`, "g"), value);
5747
6003
  }
5748
6004
  text = text.replace(/{{current_repo}}/g, inferredRepo || "unknown-repo");
6005
+ text = text.replace(/{{current_owner}}/g, inferredOwner || "unknown-owner");
5749
6006
  return {
5750
6007
  ...m,
5751
6008
  content: {
@@ -5905,16 +6162,17 @@ function buildClaimListSummary(repo, count, agent, activeOnly) {
5905
6162
  }
5906
6163
  async function handleHandoffCreate(args, storage) {
5907
6164
  const validated = HandoffCreateSchema.parse(args);
5908
- const { repo, from_agent, to_agent, task_id, task_code, summary, context, expires_at, structured } = validated;
6165
+ const { owner, repo, from_agent, to_agent, task_id, task_code, summary, context, expires_at, structured } = validated;
5909
6166
  let resolvedTaskId = task_id ?? null;
5910
6167
  if (!resolvedTaskId && task_code) {
5911
- const task = storage.tasks.getTaskByCode(repo, task_code);
6168
+ const task = storage.tasks.getTaskByCode(owner, repo, task_code);
5912
6169
  if (!task) {
5913
6170
  throw new Error(`Task not found: ${task_code} in repo ${repo}`);
5914
6171
  }
5915
6172
  resolvedTaskId = task.id;
5916
6173
  }
5917
6174
  const handoff = storage.handoffs.createHandoff({
6175
+ owner,
5918
6176
  repo,
5919
6177
  from_agent,
5920
6178
  to_agent,
@@ -5939,8 +6197,9 @@ async function handleHandoffCreate(args, storage) {
5939
6197
  }
5940
6198
  async function handleHandoffList(args, storage) {
5941
6199
  const validated = HandoffListSchema.parse(args);
5942
- const { repo, status, from_agent, to_agent, limit, offset, structured } = validated;
6200
+ const { owner, repo, status, from_agent, to_agent, limit, offset, structured } = validated;
5943
6201
  const handoffs = storage.handoffs.listHandoffs({
6202
+ owner,
5944
6203
  repo,
5945
6204
  status,
5946
6205
  from_agent,
@@ -6015,7 +6274,7 @@ async function handleHandoffUpdate(args, storage) {
6015
6274
  }
6016
6275
  async function handleTaskClaim(args, storage) {
6017
6276
  const validated = TaskClaimSchema.parse(args);
6018
- const { repo, task_id, task_code, agent, role, metadata, structured } = validated;
6277
+ const { owner, repo, task_id, task_code, agent, role, metadata, structured } = validated;
6019
6278
  let taskId = task_id;
6020
6279
  let resolvedTaskCode;
6021
6280
  let task = null;
@@ -6026,7 +6285,7 @@ async function handleTaskClaim(args, storage) {
6026
6285
  }
6027
6286
  resolvedTaskCode = task.task_code;
6028
6287
  } else if (task_code) {
6029
- task = storage.tasks.getTaskByCode(repo, task_code);
6288
+ task = storage.tasks.getTaskByCode(owner, repo, task_code);
6030
6289
  if (!task) {
6031
6290
  throw new Error(`Task not found: ${task_code} in repo ${repo}`);
6032
6291
  }
@@ -6036,6 +6295,7 @@ async function handleTaskClaim(args, storage) {
6036
6295
  throw new Error("Either task_id or task_code must be provided");
6037
6296
  }
6038
6297
  const claim = storage.handoffs.claimTask({
6298
+ owner,
6039
6299
  repo,
6040
6300
  task_id: taskId,
6041
6301
  agent,
@@ -6048,6 +6308,7 @@ async function handleTaskClaim(args, storage) {
6048
6308
  storage.taskComments.insertTaskComment({
6049
6309
  id: randomUUID2(),
6050
6310
  task_id: task.id,
6311
+ owner: repo,
6051
6312
  repo,
6052
6313
  comment: `Claimed by ${agent} \u2014 auto-promoted to in_progress`,
6053
6314
  agent,
@@ -6081,8 +6342,9 @@ async function handleTaskClaim(args, storage) {
6081
6342
  }
6082
6343
  async function handleClaimList(args, storage) {
6083
6344
  const validated = ClaimListSchema.parse(args);
6084
- const { repo, agent, active_only, limit, offset, structured } = validated;
6345
+ const { owner, repo, agent, active_only, limit, offset, structured } = validated;
6085
6346
  const claims = storage.handoffs.listClaims({
6347
+ owner,
6086
6348
  repo,
6087
6349
  agent,
6088
6350
  active_only,
@@ -6117,7 +6379,7 @@ async function handleClaimList(args, storage) {
6117
6379
  }
6118
6380
  async function handleClaimRelease(args, storage) {
6119
6381
  const validated = ClaimReleaseSchema.parse(args);
6120
- const { repo, task_id, task_code, agent, structured } = validated;
6382
+ const { owner, repo, task_id, task_code, agent, structured } = validated;
6121
6383
  let resolvedTaskId = task_id;
6122
6384
  let resolvedTaskCode = task_code ?? null;
6123
6385
  if (resolvedTaskId) {
@@ -6127,7 +6389,7 @@ async function handleClaimRelease(args, storage) {
6127
6389
  }
6128
6390
  resolvedTaskCode = task.task_code;
6129
6391
  } else if (task_code) {
6130
- const task = storage.tasks.getTaskByCode(repo, task_code);
6392
+ const task = storage.tasks.getTaskByCode(owner, repo, task_code);
6131
6393
  if (!task) {
6132
6394
  throw new Error(`Task not found: ${task_code} in repo ${repo}`);
6133
6395
  }
@@ -6182,6 +6444,7 @@ export {
6182
6444
  addLogSink,
6183
6445
  LOG_LEVEL_VALUES,
6184
6446
  createFileSink,
6447
+ parseRepoInput,
6185
6448
  normalizeRepo,
6186
6449
  SQLiteStore,
6187
6450
  RealVectorStore,
@@ -6221,6 +6484,7 @@ export {
6221
6484
  isPathWithinRoots,
6222
6485
  findContainingRoot,
6223
6486
  inferRepoFromSession,
6487
+ inferOwnerFromSession,
6224
6488
  PROMPTS,
6225
6489
  listPrompts,
6226
6490
  getPrompt,