oceanbus 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/roster/auto-discovery.d.ts +18 -0
- package/dist/roster/auto-discovery.d.ts.map +1 -0
- package/dist/roster/auto-discovery.js +109 -0
- package/dist/roster/auto-discovery.js.map +1 -0
- package/dist/roster/index.d.ts +44 -0
- package/dist/roster/index.d.ts.map +1 -0
- package/dist/roster/index.js +280 -0
- package/dist/roster/index.js.map +1 -0
- package/dist/roster/indexes.d.ts +6 -0
- package/dist/roster/indexes.d.ts.map +1 -0
- package/dist/roster/indexes.js +72 -0
- package/dist/roster/indexes.js.map +1 -0
- package/dist/roster/search.d.ts +34 -0
- package/dist/roster/search.d.ts.map +1 -0
- package/dist/roster/search.js +282 -0
- package/dist/roster/search.js.map +1 -0
- package/dist/roster/store.d.ts +14 -0
- package/dist/roster/store.d.ts.map +1 -0
- package/dist/roster/store.js +154 -0
- package/dist/roster/store.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/roster.d.ts +123 -0
- package/dist/types/roster.d.ts.map +1 -0
- package/dist/types/roster.js +4 -0
- package/dist/types/roster.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -296,9 +296,15 @@ MIT
|
|
|
296
296
|
|
|
297
297
|
| 项目 | 说明 |
|
|
298
298
|
|------|------|
|
|
299
|
-
| [oceanbus-mcp-server](https://www.npmjs.com/package/oceanbus-mcp-server) | MCP
|
|
300
|
-
| [oceanbus-langchain](https://www.npmjs.com/package/oceanbus-langchain) | LangChain
|
|
301
|
-
| [Ocean Chat](https://clawhub.ai/skills/ocean-chat) |
|
|
302
|
-
| [Captain Lobster](https://clawhub.ai/skills/captain-lobster) |
|
|
299
|
+
| [oceanbus-mcp-server](https://www.npmjs.com/package/oceanbus-mcp-server) | MCP Server — Claude Desktop/Cursor/百炼通用 |
|
|
300
|
+
| [oceanbus-langchain](https://www.npmjs.com/package/oceanbus-langchain) | LangChain / CrewAI 集成 |
|
|
301
|
+
| [Ocean Chat](https://clawhub.ai/skills/ocean-chat) | 入门灯塔 — P2P 消息,5 分钟跑通 |
|
|
302
|
+
| [Captain Lobster](https://clawhub.ai/skills/captain-lobster) | 进阶灯塔 — Zero-Player AI 交易游戏 |
|
|
303
|
+
| [Guess AI](https://clawhub.ai/skills/guess-ai) | 高阶灯塔 — 多人社交推理游戏 |
|
|
303
304
|
| [Ocean Agent](https://clawhub.ai/skills/ocean-agent) | 保险代理人 AI 工作台 |
|
|
304
305
|
| [ClawHub OceanBus 集合](https://clawhub.ai/skills?search=oceanbus) | 更多 OceanBus Skills |
|
|
306
|
+
| **平台集成** |
|
|
307
|
+
| [Dify 插件](https://github.com/ryanbihai/oceanbus-dify-plugin) | Dify 平台 OceanBus 插件 |
|
|
308
|
+
| [Coze 插件](https://www.coze.cn) | Coze 平台 OceanBus 插件(已上架) |
|
|
309
|
+
| [百炼接入](https://github.com/ryanbihai/oceanbus-dify-plugin) | 阿里云百炼 MCP 接入指南 |
|
|
310
|
+
| [MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=oceanbus) | 官方 MCP 注册表 |
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type { OceanBusConfig, PartialConfig } from './types/config';
|
|
|
9
9
|
import type { RegistrationData } from './types/agent';
|
|
10
10
|
import type { Message } from './types/messaging';
|
|
11
11
|
import type { ListenOptions, SendOptions } from './types/messaging';
|
|
12
|
+
import { RosterService } from './roster/index';
|
|
12
13
|
import type { Ed25519KeyPair, Certificate, CertVerifyResult, TrustAnchor } from './types/crypto';
|
|
13
14
|
import { YellowPagesClient } from './l1/yellow-pages';
|
|
14
15
|
import type { PayloadSigner } from './l1/yellow-pages';
|
|
@@ -50,6 +51,7 @@ export declare class OceanBus {
|
|
|
50
51
|
reputation: ReputationClient;
|
|
51
52
|
};
|
|
52
53
|
interceptors: InterceptorChain;
|
|
54
|
+
roster: RosterService;
|
|
53
55
|
private constructor();
|
|
54
56
|
static create(userConfig?: PartialConfig): Promise<OceanBus>;
|
|
55
57
|
register(): Promise<RegistrationData>;
|
|
@@ -112,4 +114,6 @@ export declare class OceanBus {
|
|
|
112
114
|
export declare function createOceanBus(config?: PartialConfig): Promise<OceanBus>;
|
|
113
115
|
export * from './types';
|
|
114
116
|
export * from './client/errors';
|
|
117
|
+
export { RosterService } from './roster/index';
|
|
118
|
+
export { RosterStore } from './roster/store';
|
|
115
119
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.OceanBus = void 0;
|
|
17
|
+
exports.RosterStore = exports.RosterService = exports.OceanBus = void 0;
|
|
18
18
|
exports.createOceanBus = createOceanBus;
|
|
19
19
|
const http_client_1 = require("./client/http-client");
|
|
20
20
|
const store_1 = require("./agent/store");
|
|
@@ -27,6 +27,7 @@ const poller_1 = require("./mailbox/poller");
|
|
|
27
27
|
const cursor_1 = require("./mailbox/cursor");
|
|
28
28
|
const loader_1 = require("./config/loader");
|
|
29
29
|
const errors_1 = require("./client/errors");
|
|
30
|
+
const index_1 = require("./roster/index");
|
|
30
31
|
// Crypto
|
|
31
32
|
const ed25519_1 = require("./crypto/ed25519");
|
|
32
33
|
const canonical_json_1 = require("./crypto/canonical-json");
|
|
@@ -56,6 +57,8 @@ class OceanBus {
|
|
|
56
57
|
l1;
|
|
57
58
|
// Interceptors
|
|
58
59
|
interceptors;
|
|
60
|
+
// Roster
|
|
61
|
+
roster;
|
|
59
62
|
constructor(config, keyStore) {
|
|
60
63
|
this.config = config;
|
|
61
64
|
this.keyStore = keyStore;
|
|
@@ -79,6 +82,8 @@ class OceanBus {
|
|
|
79
82
|
// via ob.interceptors.register(new LLMInterceptor(yourEvaluator))
|
|
80
83
|
this.interceptors.register(new llm_1.LLMInterceptor(llm_1.noopEvaluator));
|
|
81
84
|
}
|
|
85
|
+
// Roster
|
|
86
|
+
this.roster = new index_1.RosterService();
|
|
82
87
|
// Crypto
|
|
83
88
|
this.crypto = {
|
|
84
89
|
generateKeypair: ed25519_1.generateKeypair,
|
|
@@ -285,4 +290,9 @@ async function createOceanBus(config) {
|
|
|
285
290
|
// Re-export all types
|
|
286
291
|
__exportStar(require("./types"), exports);
|
|
287
292
|
__exportStar(require("./client/errors"), exports);
|
|
293
|
+
// Re-export Roster for standalone use (without full OceanBus instance)
|
|
294
|
+
var index_2 = require("./roster/index");
|
|
295
|
+
Object.defineProperty(exports, "RosterService", { enumerable: true, get: function () { return index_2.RosterService; } });
|
|
296
|
+
var store_2 = require("./roster/store");
|
|
297
|
+
Object.defineProperty(exports, "RosterStore", { enumerable: true, get: function () { return store_2.RosterStore; } });
|
|
288
298
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PendingEntry, AutoDiscoveryConfig, Contact } from '../types/roster';
|
|
2
|
+
/**
|
|
3
|
+
* Extract potential Chinese person names from a block of text.
|
|
4
|
+
* Returns unique names sorted by occurrence count.
|
|
5
|
+
*/
|
|
6
|
+
export declare function extractNames(text: string, ignoreList: string[], existingContacts: Contact[]): Map<string, {
|
|
7
|
+
count: number;
|
|
8
|
+
contexts: string[];
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Process scan results against autoDiscovery config.
|
|
12
|
+
* Returns new pending entries that met the minMentions threshold.
|
|
13
|
+
*/
|
|
14
|
+
export declare function processPending(config: AutoDiscoveryConfig, newNames: Map<string, {
|
|
15
|
+
count: number;
|
|
16
|
+
contexts: string[];
|
|
17
|
+
}>, now: string): PendingEntry[];
|
|
18
|
+
//# sourceMappingURL=auto-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-discovery.d.ts","sourceRoot":"","sources":["../../src/roster/auto-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAelF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,gBAAgB,EAAE,OAAO,EAAE,GAC1B,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmCpD;AA6BD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EAC5D,GAAG,EAAE,MAAM,GACV,YAAY,EAAE,CA2BhB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractNames = extractNames;
|
|
4
|
+
exports.processPending = processPending;
|
|
5
|
+
const search_1 = require("./search");
|
|
6
|
+
// Pattern: Chinese surname (1-2 chars) + given name (1-2 chars)
|
|
7
|
+
// Also matches common prefixes like 老X, 小X, 阿X
|
|
8
|
+
const SURNAMES = '赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮下齐康伍余元卜顾孟平黄和穆萧尹姚邵湛汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董梁杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯昝管卢莫经房裘缪干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚程嵇邢滑裴陆荣翁荀羊於惠甄麴家封芮羿储靳汲邴糜松井段富巫乌焦巴弓牧隗山谷车侯宓蓬全郗班仰秋仲伊宫宁仇栾暴甘钭厉戎祖武符刘景詹束龙叶幸司韶郜黎蓟薄印宿白怀蒲邰从鄂索咸籍赖卓蔺屠蒙池乔阴鬱胥能苍双闻莘党翟谭贡劳逄姬申扶堵冉宰郦雍卻璩桑桂濮牛寿通边扈燕冀郏浦尚农温别庄晏柴瞿阎充慕连茹习宦艾鱼容向古易慎戈廖庾终暨居衡步都耿满弘匡国文寇广禄阙东欧殳沃利蔚越夔隆师巩厍聂晁勾敖融冷訾辛阚那简饶空曾毋沙乜养鞠须丰巢关蒯相查后荆红游竺权逯盖益桓公';
|
|
9
|
+
const CJK_CHAR = '[\\u4e00-\\u9fff]';
|
|
10
|
+
// Pattern: optional prefix + surname + 1-2 CJK chars (lazy: prefer shorter match)
|
|
11
|
+
const CHINESE_NAME_RE = new RegExp(`(?:老|小|阿)?[${SURNAMES}]${CJK_CHAR}{1,2}?`, 'g');
|
|
12
|
+
// Match: 2-3 char Chinese-looking words that appear to be names
|
|
13
|
+
const NAME_PREFIXES = ['老', '小', '阿', '大'];
|
|
14
|
+
const NAME_SUFFIXES = ['总', '哥', '姐', '兄', '老师', '经理', '工', '老板', '师傅', '同学'];
|
|
15
|
+
/**
|
|
16
|
+
* Extract potential Chinese person names from a block of text.
|
|
17
|
+
* Returns unique names sorted by occurrence count.
|
|
18
|
+
*/
|
|
19
|
+
function extractNames(text, ignoreList, existingContacts) {
|
|
20
|
+
const results = new Map();
|
|
21
|
+
const ignoreSet = new Set(ignoreList.map(w => w.toLowerCase()));
|
|
22
|
+
const knownNames = new Set(existingContacts.map(c => c.name));
|
|
23
|
+
// Strategy 1: Chinese surname pattern
|
|
24
|
+
let match;
|
|
25
|
+
const re = new RegExp(CHINESE_NAME_RE.source, 'g');
|
|
26
|
+
while ((match = re.exec(text)) !== null) {
|
|
27
|
+
const name = match[0];
|
|
28
|
+
if (ignoreSet.has(name.toLowerCase()) || knownNames.has(name))
|
|
29
|
+
continue;
|
|
30
|
+
addCandidate(results, name, text, match.index);
|
|
31
|
+
}
|
|
32
|
+
// Strategy 2: Prefix + name (老X, 小X, 阿X)
|
|
33
|
+
for (const prefix of NAME_PREFIXES) {
|
|
34
|
+
const prefixRe = new RegExp(`${prefix}[\\u4e00-\\u9fff]{1,2}?`, 'g');
|
|
35
|
+
while ((match = prefixRe.exec(text)) !== null) {
|
|
36
|
+
const name = match[0];
|
|
37
|
+
if (ignoreSet.has(name.toLowerCase()) || knownNames.has(name))
|
|
38
|
+
continue;
|
|
39
|
+
addCandidate(results, name, text, match.index);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Strategy 3: Name + suffix (X总, X哥, etc.)
|
|
43
|
+
for (const suffix of NAME_SUFFIXES) {
|
|
44
|
+
const suffixRe = new RegExp(`([\\u4e00-\\u9fff]{1,3}?)${suffix}`, 'g');
|
|
45
|
+
while ((match = suffixRe.exec(text)) !== null) {
|
|
46
|
+
const fullName = match[0];
|
|
47
|
+
if (ignoreSet.has(fullName.toLowerCase()) || knownNames.has(fullName))
|
|
48
|
+
continue;
|
|
49
|
+
addCandidate(results, fullName, text, match.index);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
function addCandidate(map, name, text, index) {
|
|
55
|
+
const existing = map.get(name);
|
|
56
|
+
const context = extractContext(text, index, name.length);
|
|
57
|
+
if (existing) {
|
|
58
|
+
existing.count++;
|
|
59
|
+
if (existing.contexts.length < 3 && !existing.contexts.includes(context)) {
|
|
60
|
+
existing.contexts.push(context);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
map.set(name, { count: 1, contexts: [context] });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function extractContext(text, index, len) {
|
|
68
|
+
const start = Math.max(0, index - 20);
|
|
69
|
+
const end = Math.min(text.length, index + len + 20);
|
|
70
|
+
let ctx = text.slice(start, end);
|
|
71
|
+
if (start > 0)
|
|
72
|
+
ctx = '…' + ctx;
|
|
73
|
+
if (end < text.length)
|
|
74
|
+
ctx = ctx + '…';
|
|
75
|
+
return ctx;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Process scan results against autoDiscovery config.
|
|
79
|
+
* Returns new pending entries that met the minMentions threshold.
|
|
80
|
+
*/
|
|
81
|
+
function processPending(config, newNames, now) {
|
|
82
|
+
const added = [];
|
|
83
|
+
const existingByName = new Map();
|
|
84
|
+
for (const p of config.pending)
|
|
85
|
+
existingByName.set(p.name, p);
|
|
86
|
+
for (const [name, info] of newNames) {
|
|
87
|
+
const existing = existingByName.get(name);
|
|
88
|
+
if (existing) {
|
|
89
|
+
// Update existing
|
|
90
|
+
existing.mentionCount += info.count;
|
|
91
|
+
existing.lastSeenAt = now;
|
|
92
|
+
existing.contexts = [...new Set([...existing.contexts, ...info.contexts])].slice(0, 5);
|
|
93
|
+
}
|
|
94
|
+
else if (info.count >= config.minMentions) {
|
|
95
|
+
const entry = {
|
|
96
|
+
id: `auto_${(0, search_1.slugFromName)(name)}`,
|
|
97
|
+
name,
|
|
98
|
+
mentionCount: info.count,
|
|
99
|
+
firstSeenAt: now,
|
|
100
|
+
lastSeenAt: now,
|
|
101
|
+
contexts: info.contexts.slice(0, 5),
|
|
102
|
+
};
|
|
103
|
+
config.pending.push(entry);
|
|
104
|
+
added.push(entry);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return added;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=auto-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-discovery.js","sourceRoot":"","sources":["../../src/roster/auto-discovery.ts"],"names":[],"mappings":";;AAmBA,oCAuCC;AAiCD,wCA+BC;AAzHD,qCAAwC;AAExC,gEAAgE;AAChE,+CAA+C;AAC/C,MAAM,QAAQ,GAAG,0ZAA0Z,CAAC;AAC5a,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAErC,kFAAkF;AAClF,MAAM,eAAe,GAAG,IAAI,MAAM,CAAC,cAAc,QAAQ,IAAI,QAAQ,QAAQ,EAAE,GAAG,CAAC,CAAC;AAEpF,gEAAgE;AAChE,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC3C,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAE9E;;;GAGG;AACH,SAAgB,YAAY,CAC1B,IAAY,EACZ,UAAoB,EACpB,gBAA2B;IAE3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiD,CAAC;IACzE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9D,sCAAsC;IACtC,IAAI,KAA6B,CAAC;IAClC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACxE,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,yCAAyC;IACzC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,MAAM,yBAAyB,EAAE,GAAG,CAAC,CAAC;QACrE,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxE,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,4BAA4B,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAChF,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CACnB,GAAuD,EACvD,IAAY,EACZ,IAAY,EACZ,KAAa;IAEb,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACzE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;IACpD,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC;QAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC/B,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM;QAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACvC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAC5B,MAA2B,EAC3B,QAA4D,EAC5D,GAAW;IAEX,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO;QAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAE9D,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,kBAAkB;YAClB,QAAQ,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,QAAQ,CAAC,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAiB;gBAC1B,EAAE,EAAE,QAAQ,IAAA,qBAAY,EAAC,IAAI,CAAC,EAAE;gBAChC,IAAI;gBACJ,YAAY,EAAE,IAAI,CAAC,KAAK;gBACxB,WAAW,EAAE,GAAG;gBAChB,UAAU,EAAE,GAAG;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACpC,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { RosterStore } from './store';
|
|
2
|
+
import type { Contact, NewContact, ContactPatch, SearchResult, RosterFilter, AppData, PendingEntry, RosterData, DuplicateHint, Provenance } from '../types/roster';
|
|
3
|
+
export type { Contact, NewContact, ContactPatch, SearchResult, RosterFilter, AppData, PendingEntry, RosterData, DuplicateHint, Provenance };
|
|
4
|
+
export declare class RosterService {
|
|
5
|
+
private store;
|
|
6
|
+
private data;
|
|
7
|
+
constructor(store?: RosterStore);
|
|
8
|
+
private ensureLoaded;
|
|
9
|
+
private save;
|
|
10
|
+
search(query: string): Promise<SearchResult>;
|
|
11
|
+
get(id: string): Promise<Contact | null>;
|
|
12
|
+
findByAgentId(agentId: string): Promise<Contact | null>;
|
|
13
|
+
findByOpenId(openId: string): Promise<Contact | null>;
|
|
14
|
+
list(filter?: RosterFilter): Promise<Contact[]>;
|
|
15
|
+
add(input: NewContact): Promise<{
|
|
16
|
+
contact: Contact;
|
|
17
|
+
duplicateHints: DuplicateHint[];
|
|
18
|
+
}>;
|
|
19
|
+
update(id: string, patch: ContactPatch): Promise<Contact>;
|
|
20
|
+
updateAppData(id: string, appName: string, data: AppData): Promise<Contact>;
|
|
21
|
+
delete(id: string, soft?: boolean): Promise<void>;
|
|
22
|
+
merge(keepId: string, discardId: string): Promise<Contact>;
|
|
23
|
+
addAlias(id: string, alias: string): Promise<Contact>;
|
|
24
|
+
updateTags(id: string, tags: string[]): Promise<Contact>;
|
|
25
|
+
touch(id: string): Promise<void>;
|
|
26
|
+
scanText(text: string): Promise<{
|
|
27
|
+
newPending: PendingEntry[];
|
|
28
|
+
totalPending: number;
|
|
29
|
+
}>;
|
|
30
|
+
getPending(): Promise<PendingEntry[]>;
|
|
31
|
+
approvePending(pendingId: string): Promise<Contact>;
|
|
32
|
+
rejectPending(pendingId: string): Promise<void>;
|
|
33
|
+
getIdentities(): Promise<import("../types/roster").UserIdentity[]>;
|
|
34
|
+
getDuplicateHints(): Promise<DuplicateHint[]>;
|
|
35
|
+
/** Dismiss a single hint (user chose "keep separate"). */
|
|
36
|
+
dismissDuplicateHint(contactA: string, contactB: string): Promise<void>;
|
|
37
|
+
stats(): Promise<{
|
|
38
|
+
total: number;
|
|
39
|
+
active: number;
|
|
40
|
+
pending: number;
|
|
41
|
+
archived: number;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/roster/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAkBtC,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,UAAU,EACV,aAAa,EACb,UAAU,EAEX,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AAE5I,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,IAAI,CAA2B;gBAE3B,KAAK,CAAC,EAAE,WAAW;YAIjB,YAAY;YAOZ,IAAI;IAOZ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAK5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAKxC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAKvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAKrD,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO/C,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAyCtF,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCzD,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAY3E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4C1D,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOrD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAIxD,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,YAAY,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IASrF,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAKrC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBnD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa/C,aAAa;IAOb,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKnD,0DAA0D;IACpD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvE,KAAK,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAS7F"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RosterService = void 0;
|
|
4
|
+
const store_1 = require("./store");
|
|
5
|
+
const search_1 = require("./search");
|
|
6
|
+
const indexes_1 = require("./indexes");
|
|
7
|
+
const auto_discovery_1 = require("./auto-discovery");
|
|
8
|
+
class RosterService {
|
|
9
|
+
store;
|
|
10
|
+
data = null;
|
|
11
|
+
constructor(store) {
|
|
12
|
+
this.store = store || new store_1.RosterStore();
|
|
13
|
+
}
|
|
14
|
+
async ensureLoaded() {
|
|
15
|
+
if (!this.data) {
|
|
16
|
+
this.data = await this.store.load();
|
|
17
|
+
}
|
|
18
|
+
return this.data;
|
|
19
|
+
}
|
|
20
|
+
async save() {
|
|
21
|
+
if (!this.data)
|
|
22
|
+
return;
|
|
23
|
+
await this.store.save(this.data);
|
|
24
|
+
}
|
|
25
|
+
// ── Query ──
|
|
26
|
+
async search(query) {
|
|
27
|
+
const d = await this.ensureLoaded();
|
|
28
|
+
return (0, search_1.search)(d.contacts, query);
|
|
29
|
+
}
|
|
30
|
+
async get(id) {
|
|
31
|
+
const d = await this.ensureLoaded();
|
|
32
|
+
return (0, search_1.getById)(d.contacts, id);
|
|
33
|
+
}
|
|
34
|
+
async findByAgentId(agentId) {
|
|
35
|
+
const d = await this.ensureLoaded();
|
|
36
|
+
return (0, search_1.findByAgentId)(d.contacts, d.indexes, agentId);
|
|
37
|
+
}
|
|
38
|
+
async findByOpenId(openId) {
|
|
39
|
+
const d = await this.ensureLoaded();
|
|
40
|
+
return (0, search_1.findByOpenId)(d.contacts, d.indexes, openId);
|
|
41
|
+
}
|
|
42
|
+
async list(filter) {
|
|
43
|
+
const d = await this.ensureLoaded();
|
|
44
|
+
return (0, search_1.list)(d.contacts, filter);
|
|
45
|
+
}
|
|
46
|
+
// ── Write ──
|
|
47
|
+
async add(input) {
|
|
48
|
+
const d = await this.ensureLoaded();
|
|
49
|
+
const now = new Date().toISOString();
|
|
50
|
+
const id = input.id || (0, search_1.slugFromName)(input.name);
|
|
51
|
+
// Check uniqueness
|
|
52
|
+
if (d.contacts.some(c => c.id === id && c.status !== 'archived')) {
|
|
53
|
+
throw new Error(`Contact with id "${id}" already exists`);
|
|
54
|
+
}
|
|
55
|
+
const provenance = buildProvenance(input.source, null, now);
|
|
56
|
+
const contact = {
|
|
57
|
+
id,
|
|
58
|
+
name: input.name,
|
|
59
|
+
agents: input.agents || [],
|
|
60
|
+
tags: input.tags || [],
|
|
61
|
+
aliases: input.aliases || [],
|
|
62
|
+
notes: input.notes || '',
|
|
63
|
+
source: input.source,
|
|
64
|
+
provenance,
|
|
65
|
+
status: input.status || 'active',
|
|
66
|
+
lastContactAt: now,
|
|
67
|
+
createdAt: now,
|
|
68
|
+
updatedAt: now,
|
|
69
|
+
apps: {},
|
|
70
|
+
};
|
|
71
|
+
d.contacts.push(contact);
|
|
72
|
+
(0, indexes_1.addToIndexes)(d.indexes, contact);
|
|
73
|
+
// Auto-detect duplicates
|
|
74
|
+
const newHints = (0, search_1.findDuplicates)(contact, d.contacts, d.duplicateHints, now);
|
|
75
|
+
if (newHints.length > 0) {
|
|
76
|
+
d.duplicateHints.push(...newHints);
|
|
77
|
+
}
|
|
78
|
+
await this.save();
|
|
79
|
+
return { contact, duplicateHints: newHints };
|
|
80
|
+
}
|
|
81
|
+
async update(id, patch) {
|
|
82
|
+
const d = await this.ensureLoaded();
|
|
83
|
+
const contact = (0, search_1.getById)(d.contacts, id);
|
|
84
|
+
if (!contact)
|
|
85
|
+
throw new Error(`Contact "${id}" not found`);
|
|
86
|
+
const oldTags = [...contact.tags];
|
|
87
|
+
const oldAgentIds = contact.agents.map(a => a.agentId);
|
|
88
|
+
const oldOpenIds = contact.agents.map(a => a.openId);
|
|
89
|
+
if (patch.name !== undefined)
|
|
90
|
+
contact.name = patch.name;
|
|
91
|
+
if (patch.agents !== undefined)
|
|
92
|
+
contact.agents = patch.agents;
|
|
93
|
+
if (patch.tags !== undefined)
|
|
94
|
+
contact.tags = patch.tags;
|
|
95
|
+
if (patch.aliases !== undefined)
|
|
96
|
+
contact.aliases = patch.aliases;
|
|
97
|
+
if (patch.notes !== undefined)
|
|
98
|
+
contact.notes = patch.notes;
|
|
99
|
+
if (patch.source !== undefined)
|
|
100
|
+
contact.source = patch.source;
|
|
101
|
+
if (patch.status !== undefined)
|
|
102
|
+
contact.status = patch.status;
|
|
103
|
+
if (patch.lastContactAt !== undefined)
|
|
104
|
+
contact.lastContactAt = patch.lastContactAt;
|
|
105
|
+
contact.updatedAt = new Date().toISOString();
|
|
106
|
+
if (contact.provenance)
|
|
107
|
+
contact.provenance.lastVerifiedAt = contact.updatedAt;
|
|
108
|
+
// Update indexes
|
|
109
|
+
if (patch.tags) {
|
|
110
|
+
(0, indexes_1.updateTagsInIndexes)(d.indexes, contact, oldTags, patch.tags);
|
|
111
|
+
}
|
|
112
|
+
if (patch.agents) {
|
|
113
|
+
(0, indexes_1.updateAgentsInIndexes)(d.indexes, contact.id, oldAgentIds, oldOpenIds, contact.agents.map(a => a.agentId), contact.agents.map(a => a.openId));
|
|
114
|
+
}
|
|
115
|
+
await this.save();
|
|
116
|
+
return contact;
|
|
117
|
+
}
|
|
118
|
+
async updateAppData(id, appName, data) {
|
|
119
|
+
const d = await this.ensureLoaded();
|
|
120
|
+
const contact = (0, search_1.getById)(d.contacts, id);
|
|
121
|
+
if (!contact)
|
|
122
|
+
throw new Error(`Contact "${id}" not found`);
|
|
123
|
+
contact.apps[appName] = data;
|
|
124
|
+
contact.updatedAt = new Date().toISOString();
|
|
125
|
+
if (contact.provenance)
|
|
126
|
+
contact.provenance.lastVerifiedAt = contact.updatedAt;
|
|
127
|
+
await this.save();
|
|
128
|
+
return contact;
|
|
129
|
+
}
|
|
130
|
+
async delete(id, soft = true) {
|
|
131
|
+
const d = await this.ensureLoaded();
|
|
132
|
+
const contact = (0, search_1.getById)(d.contacts, id);
|
|
133
|
+
if (!contact)
|
|
134
|
+
throw new Error(`Contact "${id}" not found`);
|
|
135
|
+
if (soft) {
|
|
136
|
+
contact.status = 'archived';
|
|
137
|
+
contact.updatedAt = new Date().toISOString();
|
|
138
|
+
(0, indexes_1.removeFromIndexes)(d.indexes, contact);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
(0, indexes_1.removeFromIndexes)(d.indexes, contact);
|
|
142
|
+
d.contacts = d.contacts.filter(c => c.id !== id);
|
|
143
|
+
}
|
|
144
|
+
await this.save();
|
|
145
|
+
}
|
|
146
|
+
async merge(keepId, discardId) {
|
|
147
|
+
const d = await this.ensureLoaded();
|
|
148
|
+
const keep = (0, search_1.getById)(d.contacts, keepId);
|
|
149
|
+
const discard = (0, search_1.getById)(d.contacts, discardId);
|
|
150
|
+
if (!keep)
|
|
151
|
+
throw new Error(`Contact "${keepId}" not found`);
|
|
152
|
+
if (!discard)
|
|
153
|
+
throw new Error(`Contact "${discardId}" not found`);
|
|
154
|
+
// Merge agents (dedup by openId — the one identifier we always have)
|
|
155
|
+
const seenOpenIds = new Set(keep.agents.map(a => a.openId));
|
|
156
|
+
for (const a of discard.agents) {
|
|
157
|
+
if (!seenOpenIds.has(a.openId)) {
|
|
158
|
+
keep.agents.push(a);
|
|
159
|
+
seenOpenIds.add(a.openId);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
keep.aliases = [...new Set([...keep.aliases, ...discard.aliases, discard.name])];
|
|
163
|
+
keep.tags = [...new Set([...keep.tags, ...discard.tags])];
|
|
164
|
+
if (discard.notes)
|
|
165
|
+
keep.notes = keep.notes ? `${keep.notes}; ${discard.notes}` : discard.notes;
|
|
166
|
+
keep.lastContactAt = keep.lastContactAt > discard.lastContactAt ? keep.lastContactAt : discard.lastContactAt;
|
|
167
|
+
keep.updatedAt = new Date().toISOString();
|
|
168
|
+
if (keep.provenance)
|
|
169
|
+
keep.provenance.lastVerifiedAt = keep.updatedAt;
|
|
170
|
+
// Merge app data (keep wins on conflict)
|
|
171
|
+
for (const [app, appData] of Object.entries(discard.apps)) {
|
|
172
|
+
if (!keep.apps[app])
|
|
173
|
+
keep.apps[app] = appData;
|
|
174
|
+
}
|
|
175
|
+
// Dismiss duplicate hints involving either contact
|
|
176
|
+
d.duplicateHints = (0, search_1.dismissHintsForContact)(d.duplicateHints, keepId);
|
|
177
|
+
d.duplicateHints = (0, search_1.dismissHintsForContact)(d.duplicateHints, discardId);
|
|
178
|
+
// Soft-delete discard
|
|
179
|
+
(0, indexes_1.removeFromIndexes)(d.indexes, discard);
|
|
180
|
+
discard.status = 'archived';
|
|
181
|
+
discard.updatedAt = new Date().toISOString();
|
|
182
|
+
// Rebuild indexes for keep
|
|
183
|
+
(0, indexes_1.removeFromIndexes)(d.indexes, keep);
|
|
184
|
+
(0, indexes_1.addToIndexes)(d.indexes, keep);
|
|
185
|
+
await this.save();
|
|
186
|
+
return keep;
|
|
187
|
+
}
|
|
188
|
+
async addAlias(id, alias) {
|
|
189
|
+
const contact = await this.get(id);
|
|
190
|
+
if (!contact)
|
|
191
|
+
throw new Error(`Contact "${id}" not found`);
|
|
192
|
+
if (contact.aliases.includes(alias))
|
|
193
|
+
return contact;
|
|
194
|
+
return this.update(id, { aliases: [...contact.aliases, alias] });
|
|
195
|
+
}
|
|
196
|
+
async updateTags(id, tags) {
|
|
197
|
+
return this.update(id, { tags });
|
|
198
|
+
}
|
|
199
|
+
async touch(id) {
|
|
200
|
+
await this.update(id, { lastContactAt: new Date().toISOString() });
|
|
201
|
+
}
|
|
202
|
+
// ── Auto-discovery ──
|
|
203
|
+
async scanText(text) {
|
|
204
|
+
const d = await this.ensureLoaded();
|
|
205
|
+
const names = (0, auto_discovery_1.extractNames)(text, d.autoDiscovery.ignoreList, d.contacts);
|
|
206
|
+
const now = new Date().toISOString();
|
|
207
|
+
const added = (0, auto_discovery_1.processPending)(d.autoDiscovery, names, now);
|
|
208
|
+
if (added.length > 0)
|
|
209
|
+
await this.save();
|
|
210
|
+
return { newPending: added, totalPending: d.autoDiscovery.pending.length };
|
|
211
|
+
}
|
|
212
|
+
async getPending() {
|
|
213
|
+
const d = await this.ensureLoaded();
|
|
214
|
+
return d.autoDiscovery.pending;
|
|
215
|
+
}
|
|
216
|
+
async approvePending(pendingId) {
|
|
217
|
+
const d = await this.ensureLoaded();
|
|
218
|
+
const idx = d.autoDiscovery.pending.findIndex(p => p.id === pendingId);
|
|
219
|
+
if (idx === -1)
|
|
220
|
+
throw new Error(`Pending entry "${pendingId}" not found`);
|
|
221
|
+
const entry = d.autoDiscovery.pending[idx];
|
|
222
|
+
d.autoDiscovery.pending.splice(idx, 1);
|
|
223
|
+
const { contact } = await this.add({
|
|
224
|
+
name: entry.name,
|
|
225
|
+
source: 'auto-discovery',
|
|
226
|
+
notes: `Auto-discovered from: ${entry.contexts.join(' | ')}`,
|
|
227
|
+
});
|
|
228
|
+
await this.save();
|
|
229
|
+
return contact;
|
|
230
|
+
}
|
|
231
|
+
async rejectPending(pendingId) {
|
|
232
|
+
const d = await this.ensureLoaded();
|
|
233
|
+
const entry = d.autoDiscovery.pending.find(p => p.id === pendingId);
|
|
234
|
+
if (!entry)
|
|
235
|
+
throw new Error(`Pending entry "${pendingId}" not found`);
|
|
236
|
+
d.autoDiscovery.pending = d.autoDiscovery.pending.filter(p => p.id !== pendingId);
|
|
237
|
+
if (!d.autoDiscovery.ignoreList.includes(entry.name)) {
|
|
238
|
+
d.autoDiscovery.ignoreList.push(entry.name);
|
|
239
|
+
}
|
|
240
|
+
await this.save();
|
|
241
|
+
}
|
|
242
|
+
// ── Identities (self) ──
|
|
243
|
+
async getIdentities() {
|
|
244
|
+
const d = await this.ensureLoaded();
|
|
245
|
+
return d.identities;
|
|
246
|
+
}
|
|
247
|
+
// ── Duplicate hints ──
|
|
248
|
+
async getDuplicateHints() {
|
|
249
|
+
const d = await this.ensureLoaded();
|
|
250
|
+
return d.duplicateHints;
|
|
251
|
+
}
|
|
252
|
+
/** Dismiss a single hint (user chose "keep separate"). */
|
|
253
|
+
async dismissDuplicateHint(contactA, contactB) {
|
|
254
|
+
const d = await this.ensureLoaded();
|
|
255
|
+
d.duplicateHints = d.duplicateHints.filter(h => !(h.contactA === contactA && h.contactB === contactB) &&
|
|
256
|
+
!(h.contactA === contactB && h.contactB === contactA));
|
|
257
|
+
await this.save();
|
|
258
|
+
}
|
|
259
|
+
// ── Stats ──
|
|
260
|
+
async stats() {
|
|
261
|
+
const d = await this.ensureLoaded();
|
|
262
|
+
return {
|
|
263
|
+
total: d.contacts.length,
|
|
264
|
+
active: d.contacts.filter(c => c.status === 'active').length,
|
|
265
|
+
pending: d.contacts.filter(c => c.status === 'pending').length,
|
|
266
|
+
archived: d.contacts.filter(c => c.status === 'archived').length,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exports.RosterService = RosterService;
|
|
271
|
+
// ── Helpers ──
|
|
272
|
+
function buildProvenance(source, sourceId, now) {
|
|
273
|
+
return {
|
|
274
|
+
account: source,
|
|
275
|
+
sourceId,
|
|
276
|
+
firstSeenAt: now,
|
|
277
|
+
lastVerifiedAt: now,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=index.js.map
|