memorix 1.8.4 → 1.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/CLAUDE.md +3 -0
  3. package/README.md +8 -6
  4. package/README.zh-CN.md +5 -3
  5. package/assets/star-history-dark.svg +5 -5
  6. package/assets/star-history-light.svg +5 -5
  7. package/assets/star-history.json +35 -5
  8. package/dist/cli/index.js +1848 -754
  9. package/dist/dashboard/static/app.js +29 -885
  10. package/dist/dashboard/static/index.html +1 -5
  11. package/dist/dashboard/static/style.css +36 -503
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +286 -79
  14. package/dist/memcode/index.js +28035 -169
  15. package/dist/memcode-runtime/CHANGELOG.md +52 -0
  16. package/dist/sdk.js +103 -21
  17. package/dist/types.d.ts +1 -1
  18. package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +22 -16
  19. package/docs/AGENT_OPERATOR_PLAYBOOK.md +2 -2
  20. package/docs/API_REFERENCE.md +10 -8
  21. package/docs/DASHBOARD.md +23 -0
  22. package/docs/DEVELOPMENT.md +2 -2
  23. package/docs/DOCKER.md +6 -3
  24. package/docs/INTEGRATIONS.md +2 -1
  25. package/docs/MODULES.md +46 -20
  26. package/docs/PERFORMANCE.md +1 -1
  27. package/docs/README.md +8 -7
  28. package/docs/SETUP.md +4 -3
  29. package/package.json +11 -11
  30. package/plugins/antigravity/memorix/plugin.json +1 -1
  31. package/plugins/antigravity/memorix/rules/memorix.md +5 -0
  32. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  33. package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +3 -0
  34. package/plugins/claude/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  35. package/plugins/claude/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  36. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  37. package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +3 -0
  38. package/plugins/codebuddy/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  39. package/plugins/codebuddy/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  40. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  41. package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +3 -0
  42. package/plugins/codex/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  43. package/plugins/codex/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  44. package/plugins/copilot/memorix/plugin.json +1 -1
  45. package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +3 -0
  46. package/plugins/copilot/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  47. package/plugins/copilot/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  48. package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +3 -0
  49. package/plugins/cursor/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  50. package/plugins/cursor/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  51. package/plugins/gemini/memorix/GEMINI.md +5 -0
  52. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  53. package/plugins/hermes/memorix/plugin.yaml +7 -1
  54. package/plugins/omp/memorix/package.json +1 -1
  55. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  56. package/plugins/pi/memorix/package.json +1 -1
  57. package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +3 -0
  58. package/plugins/pi/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
  59. package/plugins/pi/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
  60. package/server.json +2 -2
  61. package/src/cli/command-guide.ts +52 -1
  62. package/src/cli/commands/agent-integrations.ts +1 -0
  63. package/src/cli/commands/background.ts +166 -6
  64. package/src/cli/commands/hooks-install.ts +9 -2
  65. package/src/cli/commands/hooks-preview.ts +5 -0
  66. package/src/cli/commands/integrate.ts +2 -0
  67. package/src/cli/commands/serve-http.ts +73 -80
  68. package/src/cli/commands/serve.ts +95 -93
  69. package/src/cli/commands/setup.ts +11 -1
  70. package/src/cli/commands/uninstall.ts +24 -2
  71. package/src/cli/index.ts +1 -1
  72. package/src/codegraph/task-lens.ts +72 -7
  73. package/src/dashboard/static/index.html +1 -5
  74. package/src/dashboard/static/style.css +36 -503
  75. package/src/hooks/installers/index.ts +58 -0
  76. package/src/hooks/official-skills.ts +13 -6
  77. package/src/hooks/types.ts +2 -0
  78. package/src/integrations/registry.ts +9 -0
  79. package/src/memory/graph.ts +2 -2
  80. package/src/server/mcp-diagnostics.ts +9 -7
  81. package/src/server/modern-mcp-bridge.ts +108 -0
  82. package/src/server/stdio-startup-gate.ts +41 -2
  83. package/src/server/tool-profile.ts +7 -6
  84. package/src/server.ts +1 -1
  85. package/src/store/orama-store.ts +2 -2
  86. package/src/types.ts +1 -1
  87. package/src/wiki/types.ts +2 -2
  88. package/src/workspace/mcp-adapters/workbuddy.ts +71 -0
@@ -800,56 +800,6 @@ body {
800
800
  gap: 2px;
801
801
  }
802
802
 
803
- .gfp-radio {
804
- display: flex;
805
- align-items: center;
806
- gap: 8px;
807
- padding: 6px 8px;
808
- border-radius: var(--radius-sm);
809
- cursor: pointer;
810
- font-size: 12px;
811
- color: var(--text-secondary);
812
- transition: background var(--transition-fast);
813
- border: none;
814
- background: none;
815
- width: 100%;
816
- font-family: var(--font-sans);
817
- text-align: left;
818
- }
819
-
820
- .gfp-radio:hover {
821
- background: rgba(255,255,255,0.04);
822
- }
823
-
824
- .gfp-radio.active {
825
- background: rgba(208, 188, 255, 0.08);
826
- color: var(--text-primary);
827
- font-weight: 500;
828
- }
829
-
830
- .gfp-radio-dot {
831
- width: 14px;
832
- height: 14px;
833
- border-radius: 50%;
834
- border: 2px solid var(--border-medium);
835
- flex-shrink: 0;
836
- display: flex;
837
- align-items: center;
838
- justify-content: center;
839
- }
840
-
841
- .gfp-radio.active .gfp-radio-dot {
842
- border-color: var(--accent-purple);
843
- }
844
-
845
- .gfp-radio.active .gfp-radio-dot::after {
846
- content: '';
847
- width: 6px;
848
- height: 6px;
849
- border-radius: 50%;
850
- background: var(--accent-purple);
851
- }
852
-
853
803
  .gfp-check {
854
804
  display: flex;
855
805
  align-items: center;
@@ -955,7 +905,7 @@ body {
955
905
  color: var(--text-muted);
956
906
  }
957
907
 
958
- /* ── Center: Graph Container (Cytoscape.js) ───────────────── */
908
+ /* ── Center: Graph Container (Apache ECharts) ─────────────── */
959
909
  #graph-container {
960
910
  flex: 1;
961
911
  min-width: 0;
@@ -966,13 +916,6 @@ body {
966
916
  flex-direction: column;
967
917
  }
968
918
 
969
- #cytoscape-mount {
970
- flex: 1;
971
- min-height: 0;
972
- height: 100%;
973
- overflow: hidden;
974
- }
975
-
976
919
  .graph-status-bar {
977
920
  height: 28px;
978
921
  flex-shrink: 0;
@@ -1031,6 +974,16 @@ body {
1031
974
  flex-direction: column;
1032
975
  }
1033
976
 
977
+ @media (max-width: 1100px) and (min-width: 769px) {
978
+ .graph-filter-panel {
979
+ width: 180px;
980
+ }
981
+
982
+ .graph-inspector {
983
+ width: 220px;
984
+ }
985
+ }
986
+
1034
987
  .gi-empty {
1035
988
  display: flex;
1036
989
  flex-direction: column;
@@ -1127,19 +1080,6 @@ body {
1127
1080
  color: var(--accent-purple);
1128
1081
  }
1129
1082
 
1130
- .gi-obs-item {
1131
- font-size: 12px;
1132
- color: var(--text-secondary);
1133
- line-height: 1.5;
1134
- padding: 6px 10px;
1135
- margin-bottom: 4px;
1136
- border-radius: var(--radius-sm);
1137
- background: var(--bg-surface);
1138
- border-left: 2px solid var(--accent-purple);
1139
- word-break: break-word;
1140
- overflow-wrap: anywhere;
1141
- }
1142
-
1143
1083
  .gi-rel-item {
1144
1084
  font-size: 12px;
1145
1085
  color: var(--text-secondary);
@@ -1222,438 +1162,6 @@ body {
1222
1162
  }
1223
1163
  }
1224
1164
 
1225
- /* ── Graph Tooltip ────────────────────────────────────────── */
1226
- .graph-tooltip {
1227
- position: absolute;
1228
- background: var(--bg-card);
1229
- border: 1px solid var(--border-medium);
1230
- border-radius: var(--radius-sm);
1231
- padding: 8px 12px;
1232
- font-size: 12px;
1233
- pointer-events: none;
1234
- opacity: 0;
1235
- transition: opacity var(--transition-fast);
1236
- z-index: 100;
1237
- max-width: 260px;
1238
- box-sizing: border-box;
1239
- white-space: normal;
1240
- overflow-wrap: anywhere;
1241
- word-break: break-word;
1242
- box-shadow: var(--elevation-2);
1243
- }
1244
-
1245
- .graph-tooltip.visible {
1246
- opacity: 1;
1247
- }
1248
-
1249
- .graph-tooltip-name {
1250
- font-weight: 600;
1251
- color: var(--text-primary);
1252
- margin-bottom: 2px;
1253
- }
1254
-
1255
- .graph-tooltip-type {
1256
- font-size: 11px;
1257
- color: var(--text-muted);
1258
- }
1259
-
1260
- /* ── Table View ───────────────────────────────────────────── */
1261
- .graph-table-container {
1262
- flex: 1;
1263
- overflow: auto;
1264
- background: var(--bg-base);
1265
- }
1266
-
1267
- .graph-table {
1268
- width: 100%;
1269
- border-collapse: collapse;
1270
- font-size: 12px;
1271
- }
1272
-
1273
- .graph-table th {
1274
- text-align: left;
1275
- font-size: 10px;
1276
- font-weight: 600;
1277
- color: var(--text-muted);
1278
- text-transform: uppercase;
1279
- letter-spacing: 0.5px;
1280
- padding: 10px 14px;
1281
- border-bottom: 1px solid var(--border-subtle);
1282
- background: var(--bg-card);
1283
- position: sticky;
1284
- top: 0;
1285
- z-index: 2;
1286
- }
1287
-
1288
- .graph-table td {
1289
- padding: 8px 14px;
1290
- border-bottom: 1px solid var(--border-subtle);
1291
- color: var(--text-secondary);
1292
- }
1293
-
1294
- .graph-table tr:hover td {
1295
- background: rgba(208, 188, 255, 0.02);
1296
- }
1297
-
1298
- .graph-table tr {
1299
- cursor: pointer;
1300
- transition: background var(--transition-fast);
1301
- }
1302
-
1303
- .graph-table .entity-name {
1304
- font-weight: 500;
1305
- color: var(--text-primary);
1306
- }
1307
-
1308
- .graph-table .entity-type-dot {
1309
- display: inline-block;
1310
- width: 8px;
1311
- height: 8px;
1312
- border-radius: 50%;
1313
- margin-right: 6px;
1314
- vertical-align: middle;
1315
- }
1316
-
1317
- /* Hide old graph elements */
1318
- .graph-panel { display: none; }
1319
- .graph-detail-drawer { display: none; }
1320
- .graph-detail { display: none; }
1321
- .graph-detail-empty { display: none; }
1322
-
1323
- .graph-panel-tabs {
1324
- display: flex;
1325
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
1326
- }
1327
-
1328
- .gp-tab {
1329
- flex: 1;
1330
- padding: 10px 0;
1331
- border: none;
1332
- background: transparent;
1333
- color: var(--text-muted);
1334
- font-family: var(--font-sans);
1335
- font-size: 10px;
1336
- font-weight: 600;
1337
- letter-spacing: 0.8px;
1338
- text-transform: uppercase;
1339
- cursor: pointer;
1340
- transition: all var(--transition-fast);
1341
- position: relative;
1342
- }
1343
-
1344
- .gp-tab:hover {
1345
- color: var(--text-secondary);
1346
- }
1347
-
1348
- .gp-tab.active {
1349
- color: var(--accent-purple);
1350
- }
1351
-
1352
- .gp-tab.active::after {
1353
- content: '';
1354
- position: absolute;
1355
- bottom: 0;
1356
- left: 20%;
1357
- right: 20%;
1358
- height: 2px;
1359
- background: var(--accent-purple);
1360
- border-radius: 2px 2px 0 0;
1361
- }
1362
-
1363
- .gp-content {
1364
- padding: 14px;
1365
- max-height: 400px;
1366
- overflow-y: auto;
1367
- }
1368
-
1369
- .gp-content::-webkit-scrollbar {
1370
- width: 4px;
1371
- }
1372
-
1373
- .gp-content::-webkit-scrollbar-thumb {
1374
- background: rgba(255,255,255,0.1);
1375
- border-radius: 2px;
1376
- }
1377
-
1378
- /* Graph panel search */
1379
- .gp-search {
1380
- width: 100%;
1381
- padding: 8px 12px;
1382
- background: rgba(255, 255, 255, 0.04);
1383
- border: 1px solid rgba(255, 255, 255, 0.06);
1384
- border-radius: var(--radius-sm);
1385
- color: var(--text-primary);
1386
- font-family: var(--font-sans);
1387
- font-size: 12px;
1388
- outline: none;
1389
- transition: border-color var(--transition-fast);
1390
- }
1391
-
1392
- .gp-search:focus {
1393
- border-color: var(--accent-purple);
1394
- }
1395
-
1396
- .gp-search::placeholder {
1397
- color: var(--text-muted);
1398
- }
1399
-
1400
- /* Graph panel stats */
1401
- .gp-stat-row {
1402
- display: flex;
1403
- justify-content: space-between;
1404
- align-items: center;
1405
- padding: 6px 0;
1406
- }
1407
-
1408
- .gp-stat-label {
1409
- font-size: 12px;
1410
- color: var(--text-secondary);
1411
- }
1412
-
1413
- .gp-stat-value {
1414
- font-size: 13px;
1415
- font-weight: 600;
1416
- font-family: var(--font-mono);
1417
- color: var(--text-primary);
1418
- }
1419
-
1420
- /* Graph panel legend items */
1421
- .gp-legend-item {
1422
- display: flex;
1423
- align-items: center;
1424
- gap: 10px;
1425
- padding: 6px 8px;
1426
- border-radius: var(--radius-sm);
1427
- cursor: pointer;
1428
- transition: background var(--transition-fast);
1429
- }
1430
-
1431
- .gp-legend-item:hover {
1432
- background: rgba(255, 255, 255, 0.04);
1433
- }
1434
-
1435
- .gp-legend-dot {
1436
- width: 10px;
1437
- height: 10px;
1438
- border-radius: 50%;
1439
- flex-shrink: 0;
1440
- }
1441
-
1442
- .gp-legend-name {
1443
- flex: 1;
1444
- font-size: 12px;
1445
- color: var(--text-secondary);
1446
- white-space: nowrap;
1447
- overflow: hidden;
1448
- text-overflow: ellipsis;
1449
- }
1450
-
1451
- .gp-legend-count {
1452
- font-size: 10px;
1453
- font-family: var(--font-mono);
1454
- color: var(--text-muted);
1455
- }
1456
-
1457
- /* Graph panel zoom controls */
1458
- .gp-zoom-controls {
1459
- display: flex;
1460
- gap: 4px;
1461
- margin-top: 10px;
1462
- padding-top: 10px;
1463
- border-top: 1px solid rgba(255, 255, 255, 0.04);
1464
- }
1465
-
1466
- .gp-zoom-btn {
1467
- flex: 1;
1468
- padding: 6px;
1469
- border: 1px solid rgba(255, 255, 255, 0.06);
1470
- background: rgba(255, 255, 255, 0.03);
1471
- color: var(--text-secondary);
1472
- border-radius: var(--radius-sm);
1473
- cursor: pointer;
1474
- font-size: 14px;
1475
- font-weight: 600;
1476
- transition: all var(--transition-fast);
1477
- }
1478
-
1479
- .gp-zoom-btn:hover {
1480
- background: rgba(208, 188, 255, 0.1);
1481
- border-color: rgba(208, 188, 255, 0.2);
1482
- color: var(--accent-purple);
1483
- }
1484
-
1485
- /* Node detail drawer (bottom overlay) */
1486
- .graph-detail-drawer {
1487
- position: absolute;
1488
- bottom: 0;
1489
- left: 0;
1490
- right: 0;
1491
- max-height: 45%;
1492
- background: rgba(14, 14, 26, 0.9);
1493
- backdrop-filter: blur(20px);
1494
- -webkit-backdrop-filter: blur(20px);
1495
- border-top: 1px solid rgba(255, 255, 255, 0.08);
1496
- border-radius: var(--radius-lg) var(--radius-lg) 0 0;
1497
- padding: 0;
1498
- overflow-y: auto;
1499
- z-index: 15;
1500
- transform: translateY(100%);
1501
- transition: transform var(--transition-emphasized);
1502
- }
1503
-
1504
- .graph-detail-drawer.open {
1505
- transform: translateY(0);
1506
- }
1507
-
1508
- .graph-detail-drawer .graph-detail-header {
1509
- position: sticky;
1510
- top: 0;
1511
- background: rgba(14, 14, 26, 0.95);
1512
- z-index: 1;
1513
- }
1514
-
1515
- .graph-detail {
1516
- width: 0;
1517
- display: none;
1518
- }
1519
-
1520
- .graph-detail-header {
1521
- display: flex;
1522
- align-items: center;
1523
- gap: 14px;
1524
- padding: 20px 24px;
1525
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
1526
- }
1527
-
1528
- .graph-detail-dot {
1529
- width: 16px;
1530
- height: 16px;
1531
- border-radius: 50%;
1532
- flex-shrink: 0;
1533
- }
1534
-
1535
- .graph-detail-name {
1536
- font-size: 16px;
1537
- font-weight: 600;
1538
- color: #FFFFFF;
1539
- }
1540
-
1541
- .graph-detail-type {
1542
- font-size: 12px;
1543
- color: #CAC4D0;
1544
- font-family: var(--font-mono);
1545
- }
1546
-
1547
- .graph-detail-section {
1548
- padding: 16px 24px;
1549
- border-bottom: 1px solid rgba(255, 255, 255, 0.04);
1550
- }
1551
-
1552
- .graph-detail-section:last-child {
1553
- border-bottom: none;
1554
- }
1555
-
1556
- .graph-detail-section h3 {
1557
- font-size: 11px;
1558
- font-weight: 600;
1559
- color: #CAC4D0;
1560
- text-transform: uppercase;
1561
- letter-spacing: 0.8px;
1562
- margin-bottom: 10px;
1563
- display: flex;
1564
- align-items: center;
1565
- gap: 6px;
1566
- }
1567
-
1568
- .graph-detail-count {
1569
- font-size: 10px;
1570
- font-weight: 500;
1571
- padding: 2px 8px;
1572
- border-radius: var(--radius-sm);
1573
- background: rgba(208, 188, 255, 0.1);
1574
- color: var(--accent-purple);
1575
- }
1576
-
1577
- .graph-obs-item {
1578
- font-size: 12px;
1579
- color: #E6E1E5;
1580
- line-height: 1.6;
1581
- padding: 8px 12px;
1582
- margin-bottom: 6px;
1583
- border-radius: var(--radius-sm);
1584
- background: rgba(255, 255, 255, 0.06);
1585
- border-left: 2px solid var(--accent-purple);
1586
- }
1587
-
1588
- .graph-rel-item {
1589
- font-size: 12px;
1590
- color: #E6E1E5;
1591
- padding: 6px 0;
1592
- display: flex;
1593
- align-items: center;
1594
- gap: 8px;
1595
- }
1596
-
1597
- .graph-rel-arrow {
1598
- color: var(--accent-purple);
1599
- font-weight: 600;
1600
- }
1601
-
1602
- .graph-rel-type {
1603
- font-family: var(--font-mono);
1604
- font-size: 11px;
1605
- color: #D0BCFF;
1606
- padding: 2px 8px;
1607
- background: rgba(255, 255, 255, 0.04);
1608
- border-radius: var(--radius-sm);
1609
- }
1610
-
1611
- .graph-detail-muted {
1612
- font-size: 12px;
1613
- color: var(--text-muted);
1614
- font-style: italic;
1615
- }
1616
-
1617
- .graph-tooltip {
1618
- position: absolute;
1619
- background: rgba(14, 14, 26, 0.92);
1620
- backdrop-filter: blur(12px);
1621
- border: 1px solid rgba(208, 188, 255, 0.15);
1622
- border-radius: var(--radius-md);
1623
- padding: 12px 16px;
1624
- font-size: 13px;
1625
- pointer-events: none;
1626
- opacity: 0;
1627
- transition: opacity var(--transition-fast);
1628
- z-index: 100;
1629
- max-width: 300px;
1630
- box-sizing: border-box;
1631
- white-space: normal;
1632
- overflow-wrap: anywhere;
1633
- word-break: break-word;
1634
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
1635
- }
1636
-
1637
- .graph-tooltip.visible {
1638
- opacity: 1;
1639
- }
1640
-
1641
- .graph-tooltip-name {
1642
- font-weight: 600;
1643
- color: var(--accent-purple);
1644
- margin-bottom: 4px;
1645
- }
1646
-
1647
- .graph-tooltip-type {
1648
- font-size: 11px;
1649
- color: var(--text-muted);
1650
- }
1651
-
1652
- /* Hide text for graph-detail-empty since we use drawer now */
1653
- .graph-detail-empty {
1654
- display: none;
1655
- }
1656
-
1657
1165
  /* ============================================================
1658
1166
  * Observations Page
1659
1167
  * ============================================================ */
@@ -2560,6 +2068,31 @@ body {
2560
2068
  .maintenance-dialog-body {
2561
2069
  padding: 14px;
2562
2070
  }
2071
+
2072
+ .team-header {
2073
+ align-items: stretch;
2074
+ flex-direction: column;
2075
+ gap: 14px;
2076
+ }
2077
+
2078
+ .team-header-left,
2079
+ .team-header-left > div:last-child {
2080
+ min-width: 0;
2081
+ }
2082
+
2083
+ .team-header-right {
2084
+ flex-wrap: wrap;
2085
+ justify-content: flex-start;
2086
+ gap: 8px;
2087
+ }
2088
+
2089
+ .team-header-right > div {
2090
+ margin-right: 0 !important;
2091
+ }
2092
+
2093
+ .team-refresh-time {
2094
+ margin-left: auto;
2095
+ }
2563
2096
  }
2564
2097
 
2565
2098
  /* Low quality indicator */
@@ -652,6 +652,12 @@ export function getProjectConfigPath(agent: AgentName, projectRoot: string): str
652
652
  return path.join(projectRoot, '.agents', 'hooks.json');
653
653
  case 'gemini-cli':
654
654
  return path.join(projectRoot, '.gemini', 'settings.json');
655
+ case 'workbuddy':
656
+ // WorkBuddy has no hook system at all — only MCP config and project
657
+ // AGENTS.md guidance. Return an empty path so install, detection and
658
+ // uninstall all treat hooks as a no-op instead of falling through to the
659
+ // `.memorix/hooks.json` default (which would report a path that never exists).
660
+ return '';
655
661
  default:
656
662
  return path.join(projectRoot, '.memorix', 'hooks.json');
657
663
  }
@@ -697,6 +703,9 @@ export function getGlobalConfigPath(agent: AgentName): string {
697
703
  case 'dsh':
698
704
  // DSH reads the user-global AGENTS.md from its harness home.
699
705
  return path.join(process.env.DSH_HOME?.trim() || path.join(home, '.dsh'), 'AGENTS.md');
706
+ case 'workbuddy':
707
+ // WorkBuddy has no user-global instructions file — guidance is project-only.
708
+ return '';
700
709
  default:
701
710
  return path.join(home, '.memorix', 'hooks.json');
702
711
  }
@@ -725,6 +734,9 @@ export function getAgentRulesPath(agent: AgentName, root: string, global = false
725
734
  case 'dsh':
726
735
  // The user-global AGENTS.md lives in the harness home DSH reads.
727
736
  return path.join(process.env.DSH_HOME?.trim() || path.join(root, '.dsh'), 'AGENTS.md');
737
+ case 'workbuddy':
738
+ // WorkBuddy has no user-global instructions file — guidance is project-only.
739
+ return '';
728
740
  default:
729
741
  return path.join(root, '.agent', 'rules', 'memorix.md');
730
742
  }
@@ -752,6 +764,8 @@ export function getAgentRulesPath(agent: AgentName, root: string, global = false
752
764
  return path.join(root, '.trae', 'rules', 'project_rules.md');
753
765
  case 'dsh':
754
766
  return path.join(root, 'AGENTS.md');
767
+ case 'workbuddy':
768
+ return path.join(root, 'AGENTS.md');
755
769
  default:
756
770
  return path.join(root, '.agent', 'rules', 'memorix.md');
757
771
  }
@@ -867,6 +881,12 @@ export async function detectInstalledAgents(): Promise<AgentName[]> {
867
881
  agents.push('dsh');
868
882
  } catch { /* not installed */ }
869
883
 
884
+ // Check for WorkBuddy (its user-level home dir ~/.workbuddy)
885
+ try {
886
+ await fs.access(path.join(home, '.workbuddy'));
887
+ agents.push('workbuddy');
888
+ } catch { /* not installed */ }
889
+
870
890
  return agents;
871
891
  }
872
892
 
@@ -889,6 +909,19 @@ export async function installHooks(
889
909
  };
890
910
  }
891
911
 
912
+ // WorkBuddy has no hook system and no user-global guidance file. Report an
913
+ // explicit no-op instead of a project path that is never written.
914
+ if (agent === 'workbuddy' && global) {
915
+ return {
916
+ agent,
917
+ configPath: '',
918
+ events: [],
919
+ generated: {
920
+ note: 'WorkBuddy has no hook system and no user-global guidance file — MCP only; no global guidance/hooks. Run `memorix setup --agent workbuddy` (without --global) to install project MCP config and AGENTS.md guidance.',
921
+ },
922
+ };
923
+ }
924
+
892
925
  // Guard: reject global install for agents that don't support it
893
926
  if (global && getGlobalConfigPath(agent) === '') {
894
927
  return {
@@ -988,6 +1021,20 @@ export async function installHooks(
988
1021
  },
989
1022
  };
990
1023
  }
1024
+ case 'workbuddy':
1025
+ // WorkBuddy has no hook system — install AGENTS.md guidance only;
1026
+ // the MCP row is installed by `memorix setup --agent workbuddy`.
1027
+ {
1028
+ const rulesPath = await installAgentRules(agent, projectRoot, global);
1029
+ return {
1030
+ agent,
1031
+ configPath: rulesPath,
1032
+ events: [],
1033
+ generated: {
1034
+ note: 'WorkBuddy has no hook system — installed AGENTS.md guidance only; the MCP row is installed by `memorix setup --agent workbuddy`.',
1035
+ },
1036
+ };
1037
+ }
991
1038
  case 'opencode': {
992
1039
  // OpenCode uses JS plugin files for hooks
993
1040
  const pluginContent = generateOpenCodePlugin();
@@ -1161,6 +1208,8 @@ export async function installHooks(
1161
1208
  * Rules instruct the agent to proactively use memorix for context continuity.
1162
1209
  */
1163
1210
  async function installAgentRules(agent: AgentName, projectRoot: string, global = false): Promise<string> {
1211
+ // WorkBuddy has no user-global instructions file — guidance is project-only.
1212
+ if (agent === 'workbuddy' && global) return '';
1164
1213
  const rulesContent = getAgentRulesContent(agent, global ? 'global' : 'project');
1165
1214
  const rulesRoot = global ? os.homedir() : projectRoot;
1166
1215
  const rulesPath = getAgentRulesPath(agent, rulesRoot, global);
@@ -1331,6 +1380,9 @@ function getAgentRulesContent(agent?: AgentName, scope: 'project' | 'global' = '
1331
1380
  '| \x60memorix_store_reasoning\x60 | Save the "why" behind a decision |',
1332
1381
  '| \x60memorix_resolve\x60 | Mark completed/outdated memories |',
1333
1382
  '| \x60memorix_session_start\x60 | Load session context (handoff, orchestration coordination) |',
1383
+ '| \x60memorix_evidence\x60 | Check a memory source, freshness, and verification state |',
1384
+ '| \x60memorix_feedback\x60 | Record whether a memory helped, conflicted, or was corrected |',
1385
+ '| \x60memorix_media\x60 | Inspect or import controlled local media |',
1334
1386
  ].join('\n');
1335
1387
  }
1336
1388
 
@@ -1352,6 +1404,12 @@ export async function uninstallHooks(
1352
1404
  return false;
1353
1405
  }
1354
1406
 
1407
+ // WorkBuddy has no hook file at either scope — removing hooks is a no-op.
1408
+ // It must not touch the generic `.memorix/hooks.json` default path.
1409
+ if (agent === 'workbuddy') {
1410
+ return false;
1411
+ }
1412
+
1355
1413
  // Guard: reject global uninstall for agents that don't support it
1356
1414
  if (global && getGlobalConfigPath(agent) === '') {
1357
1415
  return false;