@nebutra/cofounder-match 0.1.1 → 0.1.2
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/.nebutra/debug/cofounder-match.jsonl +6 -6
- package/.nebutra/debug/content-store.jsonl +7 -7
- package/.nebutra/debug/event-log.jsonl +1 -1
- package/.turbo/turbo-build.log +5 -5
- package/.turbo/turbo-test.log +4 -6
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +13 -0
- package/dist/{chunk-ZXTCDLEE.js → chunk-3HNHQK4D.js} +9 -11
- package/dist/chunk-3HNHQK4D.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/src/index.ts +9 -11
- package/dist/chunk-ZXTCDLEE.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
{"at":"2026-05-
|
|
2
|
-
{"at":"2026-05-
|
|
3
|
-
{"at":"2026-05-
|
|
4
|
-
{"at":"2026-05-
|
|
5
|
-
{"at":"2026-05-
|
|
6
|
-
{"at":"2026-05-
|
|
1
|
+
{"at":"2026-05-19T08:15:20.302Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
2
|
+
{"at":"2026-05-19T08:15:20.368Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
3
|
+
{"at":"2026-05-19T08:15:20.375Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
4
|
+
{"at":"2026-05-19T08:15:20.425Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
5
|
+
{"at":"2026-05-19T08:15:20.446Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
6
|
+
{"at":"2026-05-19T08:15:20.463Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
{"at":"2026-05-
|
|
2
|
-
{"at":"2026-05-
|
|
3
|
-
{"at":"2026-05-
|
|
4
|
-
{"at":"2026-05-
|
|
5
|
-
{"at":"2026-05-
|
|
6
|
-
{"at":"2026-05-
|
|
7
|
-
{"at":"2026-05-
|
|
1
|
+
{"at":"2026-05-19T08:15:20.280Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
2
|
+
{"at":"2026-05-19T08:15:20.301Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
3
|
+
{"at":"2026-05-19T08:15:20.350Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
4
|
+
{"at":"2026-05-19T08:15:20.364Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
5
|
+
{"at":"2026-05-19T08:15:20.375Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
6
|
+
{"at":"2026-05-19T08:15:20.413Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
7
|
+
{"at":"2026-05-19T08:15:20.448Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpccycfz.json"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"traceId":"
|
|
1
|
+
{"at":"2026-05-19T08:15:20.458Z","traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpccycfz_mpccycg1","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpccycfz.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpccycfz.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpccycfz\",\n \"threadKind\": \"mutual-consent-intro\",\n \"founders\": [\n \"alice\",\n \"sarah\"\n ],\n \"icebreaker\": \"alice, start with the specific work you admired in sarah's profile.\"\n}\n"},"id":"9c798745c9ea33a4832a0649383fc7142eb43e3d87088e0242e0e09ff43103d6","tenantId":"tenant_a","summary":"content_write touched 1 path(s)","objectHashes":["8442dd125ab3300610ea189cc71b3baee335a5c542ba4006560d2bffc88a9a35"]}
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @nebutra/cofounder-match@0.1.
|
|
2
|
+
> @nebutra/cofounder-match@0.1.2 build /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[32mESM[39m [1mdist/cli.js [22m[32m1.27 KB[39m
|
|
13
13
|
[32mESM[39m [1mdist/index.js [22m[32m172.00 B[39m
|
|
14
|
-
[32mESM[39m [1mdist/chunk-
|
|
14
|
+
[32mESM[39m [1mdist/chunk-3HNHQK4D.js [22m[32m7.10 KB[39m
|
|
15
15
|
[32mESM[39m [1mdist/cli.js.map [22m[32m2.27 KB[39m
|
|
16
16
|
[32mESM[39m [1mdist/index.js.map [22m[32m71.00 B[39m
|
|
17
|
-
[32mESM[39m [1mdist/chunk-
|
|
18
|
-
[32mESM[39m ⚡️ Build success in
|
|
17
|
+
[32mESM[39m [1mdist/chunk-3HNHQK4D.js.map [22m[32m14.51 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 74ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 14147ms
|
|
21
21
|
[32mDTS[39m [1mdist/cli.d.ts [22m[32m13.00 B[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.45 KB[39m
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
> @nebutra/cofounder-match@0.1.
|
|
2
|
+
> @nebutra/cofounder-match@0.1.2 test /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.4 [39m[90m/home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match[39m
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
(Use `node --trace-warnings ...` to show where the warning was created)
|
|
10
|
-
[32m✓[39m src/index.test.ts [2m([22m[2m3 tests[22m[2m)[22m[33m 479[2mms[22m[39m
|
|
8
|
+
[32m✓[39m src/index.test.ts [2m([22m[2m3 tests[22m[2m)[22m[33m 408[2mms[22m[39m
|
|
11
9
|
|
|
12
10
|
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
13
11
|
[2m Tests [22m [1m[32m3 passed[39m[22m[90m (3)[39m
|
|
14
|
-
[2m Start at [22m
|
|
15
|
-
[2m Duration [22m
|
|
12
|
+
[2m Start at [22m 08:15:18
|
|
13
|
+
[2m Duration [22m 1.61s[2m (transform 642ms, setup 0ms, import 793ms, tests 408ms, environment 6ms)[22m
|
|
16
14
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @nebutra/cofounder-match
|
|
2
2
|
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Publish registry package metadata under the MIT license.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies []:
|
|
10
|
+
- @nebutra/capability-kit@0.2.1
|
|
11
|
+
- @nebutra/content-store@0.1.1
|
|
12
|
+
- @nebutra/errors@0.1.1
|
|
13
|
+
- @nebutra/event-log@0.1.1
|
|
14
|
+
- @nebutra/generation-context@0.1.1
|
|
15
|
+
|
|
3
16
|
## 0.1.1
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { mkdir } from "fs/promises";
|
|
3
3
|
import { join } from "path";
|
|
4
|
+
import { requireCapabilityTenant } from "@nebutra/capability-kit";
|
|
4
5
|
import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
|
|
5
6
|
import { ContentStore } from "@nebutra/content-store";
|
|
6
7
|
import { CapabilityError } from "@nebutra/errors";
|
|
7
8
|
import { EventLog } from "@nebutra/event-log";
|
|
8
9
|
import { assetId } from "@nebutra/generation-context";
|
|
9
|
-
function requireTenant(value) {
|
|
10
|
-
if (!value?.trim()) {
|
|
11
|
-
throw new CapabilityError("cofounder-match", "Cofounder Match requires tenant context", {
|
|
12
|
-
suggestion: "Pass tenantId so profile and consent artifacts stay tenant-scoped.",
|
|
13
|
-
statusCode: 400
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return value;
|
|
17
|
-
}
|
|
18
10
|
function skillVector(input) {
|
|
19
11
|
return {
|
|
20
12
|
code: input.code ?? 0,
|
|
@@ -48,7 +40,13 @@ var CofounderMatch = class _CofounderMatch {
|
|
|
48
40
|
#profiles = /* @__PURE__ */ new Map();
|
|
49
41
|
#interests = /* @__PURE__ */ new Set();
|
|
50
42
|
constructor(options) {
|
|
51
|
-
this.#tenantId =
|
|
43
|
+
this.#tenantId = requireCapabilityTenant({
|
|
44
|
+
explicit: options.tenantId,
|
|
45
|
+
onMissing: () => new CapabilityError("cofounder-match", "Cofounder Match requires tenant context", {
|
|
46
|
+
suggestion: "Pass tenantId so profile and consent artifacts stay tenant-scoped.",
|
|
47
|
+
statusCode: 400
|
|
48
|
+
})
|
|
49
|
+
});
|
|
52
50
|
this.#debugRoot = options.debugRoot ?? process.cwd();
|
|
53
51
|
this.#contentStore = options.contentStore;
|
|
54
52
|
this.#eventLog = options.eventLog;
|
|
@@ -176,4 +174,4 @@ export {
|
|
|
176
174
|
CofounderMatch,
|
|
177
175
|
readCofounderMatchDebug
|
|
178
176
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
177
|
+
//# sourceMappingURL=chunk-3HNHQK4D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { requireCapabilityTenant } from \"@nebutra/capability-kit\";\nimport { appendCapabilityDebug, readCapabilityDebug } from \"@nebutra/capability-kit/debug\";\nimport { ContentStore } from \"@nebutra/content-store\";\nimport { CapabilityError } from \"@nebutra/errors\";\nimport { EventLog } from \"@nebutra/event-log\";\nimport { assetId } from \"@nebutra/generation-context\";\n\nexport type SkillArea = \"code\" | \"growth\" | \"brand\" | \"support\";\n\nexport interface ActivityProfileInput {\n readonly founderId: string;\n readonly activeDays: number;\n readonly playCounts: Partial<Record<SkillArea, number>>;\n readonly domainTags: readonly string[];\n readonly communicationSamples: readonly string[];\n}\n\nexport interface FounderProfile {\n readonly founderId: string;\n readonly activityVerified: boolean;\n readonly lockedReason?: string;\n readonly activeDays: number;\n readonly skillVector: Record<SkillArea, number>;\n readonly domainTags: readonly string[];\n readonly communicationStyle: readonly string[];\n}\n\nexport interface MatchScore {\n readonly leftFounderId: string;\n readonly rightFounderId: string;\n readonly overall: number;\n readonly skillComplementarity: number;\n readonly domainAdjacency: number;\n readonly paceCompatibility: number;\n readonly why: readonly string[];\n}\n\nexport interface ChatThread {\n readonly threadId: string;\n readonly threadKind: \"mutual-consent-intro\";\n readonly founders: readonly [string, string];\n readonly icebreaker: string;\n}\n\nexport interface CofounderMatchDoctorReport {\n readonly capability: \"cofounder-match\";\n readonly ok: boolean;\n readonly checkedAt: string;\n readonly features: readonly string[];\n readonly suggestion?: string;\n}\n\nexport interface CofounderMatchOptions {\n readonly tenantId?: string;\n readonly debugRoot?: string;\n readonly contentStore?: ContentStore;\n readonly eventLog?: EventLog;\n}\n\nfunction skillVector(input: Partial<Record<SkillArea, number>>): Record<SkillArea, number> {\n return {\n code: input.code ?? 0,\n growth: input.growth ?? 0,\n brand: input.brand ?? 0,\n support: input.support ?? 0,\n };\n}\n\nfunction strongestSkill(vector: Record<SkillArea, number>): SkillArea {\n return (\n (Object.entries(vector) as Array<[SkillArea, number]>).sort(\n ([leftKey, left], [rightKey, right]) => right - left || leftKey.localeCompare(rightKey),\n )[0]?.[0] ?? \"code\"\n );\n}\n\nfunction weakestSkill(vector: Record<SkillArea, number>): SkillArea {\n return (\n (Object.entries(vector) as Array<[SkillArea, number]>).sort(\n ([leftKey, left], [rightKey, right]) => left - right || leftKey.localeCompare(rightKey),\n )[0]?.[0] ?? \"growth\"\n );\n}\n\nfunction sharedCount(left: readonly string[], right: readonly string[]): number {\n const rightSet = new Set(right.map((item) => item.toLowerCase()));\n return left.filter((item) => rightSet.has(item.toLowerCase())).length;\n}\n\nfunction consentKey(from: string, to: string): string {\n return `${from}->${to}`;\n}\n\nexport class CofounderMatch {\n readonly #tenantId: string;\n readonly #debugRoot: string;\n readonly #contentStore: ContentStore;\n readonly #eventLog: EventLog;\n readonly #profiles = new Map<string, FounderProfile>();\n readonly #interests = new Set<string>();\n\n private constructor(\n options: Required<Pick<CofounderMatchOptions, \"tenantId\" | \"contentStore\" | \"eventLog\">> &\n Pick<CofounderMatchOptions, \"debugRoot\">,\n ) {\n this.#tenantId = requireCapabilityTenant({\n explicit: options.tenantId,\n onMissing: () =>\n new CapabilityError(\"cofounder-match\", \"Cofounder Match requires tenant context\", {\n suggestion: \"Pass tenantId so profile and consent artifacts stay tenant-scoped.\",\n statusCode: 400,\n }),\n });\n this.#debugRoot = options.debugRoot ?? process.cwd();\n this.#contentStore = options.contentStore;\n this.#eventLog = options.eventLog;\n }\n\n static async open(\n root = \".nebutra/cofounder-match\",\n options: Omit<CofounderMatchOptions, \"contentStore\" | \"eventLog\"> = {},\n ): Promise<CofounderMatch> {\n const tenantId = options.tenantId ?? \"local\";\n await mkdir(root, { recursive: true });\n const contentStore = await ContentStore.open(join(root, \"content\"), { tenantId });\n const eventLog = await EventLog.open(join(root, \"event-log\"), { tenantId });\n return new CofounderMatch({ ...options, tenantId, contentStore, eventLog });\n }\n\n async buildProfileFromActivity(input: ActivityProfileInput): Promise<FounderProfile> {\n const profile: FounderProfile = {\n founderId: input.founderId,\n activeDays: input.activeDays,\n activityVerified: input.activeDays >= 30,\n ...(input.activeDays < 30\n ? { lockedReason: \"Cofounder matching unlocks after 30 days of real activity.\" }\n : {}),\n skillVector: skillVector(input.playCounts),\n domainTags: input.domainTags,\n communicationStyle: input.communicationSamples,\n };\n const path = `cofounder-match/profiles/${input.founderId}.json`;\n const snapshot = `${JSON.stringify(profile, null, 2)}\\n`;\n await this.#contentStore.write(path, snapshot);\n this.#profiles.set(input.founderId, profile);\n await this.#debug({\n type: \"profile\",\n tenantId: this.#tenantId,\n founderId: input.founderId,\n activityVerified: profile.activityVerified,\n });\n return profile;\n }\n\n scoreMatch(left: FounderProfile, right: FounderProfile): MatchScore {\n const leftWeak = weakestSkill(left.skillVector);\n const rightStrong = strongestSkill(right.skillVector);\n const rightWeak = weakestSkill(right.skillVector);\n const leftStrong = strongestSkill(left.skillVector);\n const growthFill = left.skillVector.growth <= 10 && right.skillVector.growth >= 30 ? 45 : 0;\n const codeFill = right.skillVector.code <= 10 && left.skillVector.code >= 30 ? 25 : 0;\n const supportFill = left.skillVector.support <= 5 && right.skillVector.support >= 15 ? 10 : 0;\n const brandFill = right.skillVector.brand <= 5 && left.skillVector.brand >= 10 ? 10 : 0;\n const complements = Math.min(100, 20 + growthFill + codeFill + supportFill + brandFill);\n const domainAdjacency = Math.min(100, 55 + sharedCount(left.domainTags, right.domainTags) * 20);\n const paceCompatibility = Math.max(40, 100 - Math.abs(left.activeDays - right.activeDays));\n const overall = Math.round(\n Math.min(100, complements * 0.55 + domainAdjacency * 0.25 + paceCompatibility * 0.2),\n );\n const why = [\n `${right.founderId} is strong in ${rightStrong[0]?.toUpperCase()}${rightStrong.slice(\n 1,\n )}, which complements ${left.founderId}'s ${leftWeak} gap.`,\n `${left.founderId} is strong in ${leftStrong}, which balances ${right.founderId}'s ${rightWeak} gap.`,\n `Shared domains: ${sharedCount(left.domainTags, right.domainTags)}.`,\n ];\n return {\n leftFounderId: left.founderId,\n rightFounderId: right.founderId,\n overall,\n skillComplementarity: Math.min(100, complements),\n domainAdjacency,\n paceCompatibility,\n why,\n };\n }\n\n async expressInterest(fromFounderId: string, toFounderId: string): Promise<void> {\n this.#interests.add(consentKey(fromFounderId, toFounderId));\n await this.#debug({ type: \"interest\", tenantId: this.#tenantId, fromFounderId, toFounderId });\n }\n\n async startChat(leftFounderId: string, rightFounderId: string): Promise<ChatThread> {\n if (\n !this.#interests.has(consentKey(leftFounderId, rightFounderId)) ||\n !this.#interests.has(consentKey(rightFounderId, leftFounderId))\n ) {\n throw new CapabilityError(\"cofounder-match\", \"Mutual consent is required before chat\", {\n suggestion: \"Wait for mutual interest before opening a cofounder intro thread.\",\n statusCode: 403,\n });\n }\n const thread: ChatThread = {\n threadId: assetId(\"cofounder_chat\", `${leftFounderId}_${rightFounderId}`),\n threadKind: \"mutual-consent-intro\",\n founders: [leftFounderId, rightFounderId],\n icebreaker: `${leftFounderId}, start with the specific work you admired in ${rightFounderId}'s profile.`,\n };\n const path = `cofounder-match/chats/${thread.threadId}.json`;\n const snapshot = `${JSON.stringify(thread, null, 2)}\\n`;\n await this.#contentStore.write(path, snapshot);\n await this.#eventLog.commit({\n traceId: assetId(\"cofounder_match_chat\", thread.threadId),\n kind: \"content_write\",\n affected: [path],\n parent: null,\n snapshot: { [path]: snapshot },\n });\n await this.#debug({\n type: \"start_chat\",\n tenantId: this.#tenantId,\n founders: thread.founders,\n });\n return thread;\n }\n\n async doctor(): Promise<CofounderMatchDoctorReport> {\n const report: CofounderMatchDoctorReport = {\n capability: \"cofounder-match\",\n ok: true,\n checkedAt: new Date().toISOString(),\n features: [\"activity-verified-profile\", \"explainable-score\", \"mutual-consent-intro\"],\n suggestion:\n \"Local matching contracts are ready; encrypted chat and identity providers remain adapter handoffs.\",\n };\n await this.#debug({ type: \"doctor\", tenantId: this.#tenantId, profiles: this.#profiles.size });\n return report;\n }\n\n async close(): Promise<void> {\n await this.#contentStore.close();\n }\n\n async #debug(entry: Record<string, unknown>): Promise<void> {\n await appendCapabilityDebug(\"cofounder-match\", entry, { root: this.#debugRoot });\n }\n}\n\nexport async function readCofounderMatchDebug(\n root = process.cwd(),\n limit = 20,\n): Promise<unknown[]> {\n return readCapabilityDebug(\"cofounder-match\", { root, limit });\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebutra/cofounder-match",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Behavior-verified cofounder profile, matching, and mutual-consent introduction surface",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
".": "./src/index.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@nebutra/capability-kit": "0.2.
|
|
33
|
-
"@nebutra/content-store": "0.1.
|
|
34
|
-
"@nebutra/errors": "0.1.
|
|
35
|
-
"@nebutra/event-log": "0.1.
|
|
36
|
-
"@nebutra/generation-context": "0.1.
|
|
32
|
+
"@nebutra/capability-kit": "0.2.1",
|
|
33
|
+
"@nebutra/content-store": "0.1.1",
|
|
34
|
+
"@nebutra/errors": "0.1.1",
|
|
35
|
+
"@nebutra/event-log": "0.1.1",
|
|
36
|
+
"@nebutra/generation-context": "0.1.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/node": "^22.19.15",
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { requireCapabilityTenant } from "@nebutra/capability-kit";
|
|
3
4
|
import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
|
|
4
5
|
import { ContentStore } from "@nebutra/content-store";
|
|
5
6
|
import { CapabilityError } from "@nebutra/errors";
|
|
@@ -58,16 +59,6 @@ export interface CofounderMatchOptions {
|
|
|
58
59
|
readonly eventLog?: EventLog;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
function requireTenant(value: string | undefined): string {
|
|
62
|
-
if (!value?.trim()) {
|
|
63
|
-
throw new CapabilityError("cofounder-match", "Cofounder Match requires tenant context", {
|
|
64
|
-
suggestion: "Pass tenantId so profile and consent artifacts stay tenant-scoped.",
|
|
65
|
-
statusCode: 400,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return value;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
62
|
function skillVector(input: Partial<Record<SkillArea, number>>): Record<SkillArea, number> {
|
|
72
63
|
return {
|
|
73
64
|
code: input.code ?? 0,
|
|
@@ -114,7 +105,14 @@ export class CofounderMatch {
|
|
|
114
105
|
options: Required<Pick<CofounderMatchOptions, "tenantId" | "contentStore" | "eventLog">> &
|
|
115
106
|
Pick<CofounderMatchOptions, "debugRoot">,
|
|
116
107
|
) {
|
|
117
|
-
this.#tenantId =
|
|
108
|
+
this.#tenantId = requireCapabilityTenant({
|
|
109
|
+
explicit: options.tenantId,
|
|
110
|
+
onMissing: () =>
|
|
111
|
+
new CapabilityError("cofounder-match", "Cofounder Match requires tenant context", {
|
|
112
|
+
suggestion: "Pass tenantId so profile and consent artifacts stay tenant-scoped.",
|
|
113
|
+
statusCode: 400,
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
118
116
|
this.#debugRoot = options.debugRoot ?? process.cwd();
|
|
119
117
|
this.#contentStore = options.contentStore;
|
|
120
118
|
this.#eventLog = options.eventLog;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { appendCapabilityDebug, readCapabilityDebug } from \"@nebutra/capability-kit/debug\";\nimport { ContentStore } from \"@nebutra/content-store\";\nimport { CapabilityError } from \"@nebutra/errors\";\nimport { EventLog } from \"@nebutra/event-log\";\nimport { assetId } from \"@nebutra/generation-context\";\n\nexport type SkillArea = \"code\" | \"growth\" | \"brand\" | \"support\";\n\nexport interface ActivityProfileInput {\n readonly founderId: string;\n readonly activeDays: number;\n readonly playCounts: Partial<Record<SkillArea, number>>;\n readonly domainTags: readonly string[];\n readonly communicationSamples: readonly string[];\n}\n\nexport interface FounderProfile {\n readonly founderId: string;\n readonly activityVerified: boolean;\n readonly lockedReason?: string;\n readonly activeDays: number;\n readonly skillVector: Record<SkillArea, number>;\n readonly domainTags: readonly string[];\n readonly communicationStyle: readonly string[];\n}\n\nexport interface MatchScore {\n readonly leftFounderId: string;\n readonly rightFounderId: string;\n readonly overall: number;\n readonly skillComplementarity: number;\n readonly domainAdjacency: number;\n readonly paceCompatibility: number;\n readonly why: readonly string[];\n}\n\nexport interface ChatThread {\n readonly threadId: string;\n readonly threadKind: \"mutual-consent-intro\";\n readonly founders: readonly [string, string];\n readonly icebreaker: string;\n}\n\nexport interface CofounderMatchDoctorReport {\n readonly capability: \"cofounder-match\";\n readonly ok: boolean;\n readonly checkedAt: string;\n readonly features: readonly string[];\n readonly suggestion?: string;\n}\n\nexport interface CofounderMatchOptions {\n readonly tenantId?: string;\n readonly debugRoot?: string;\n readonly contentStore?: ContentStore;\n readonly eventLog?: EventLog;\n}\n\nfunction requireTenant(value: string | undefined): string {\n if (!value?.trim()) {\n throw new CapabilityError(\"cofounder-match\", \"Cofounder Match requires tenant context\", {\n suggestion: \"Pass tenantId so profile and consent artifacts stay tenant-scoped.\",\n statusCode: 400,\n });\n }\n return value;\n}\n\nfunction skillVector(input: Partial<Record<SkillArea, number>>): Record<SkillArea, number> {\n return {\n code: input.code ?? 0,\n growth: input.growth ?? 0,\n brand: input.brand ?? 0,\n support: input.support ?? 0,\n };\n}\n\nfunction strongestSkill(vector: Record<SkillArea, number>): SkillArea {\n return (\n (Object.entries(vector) as Array<[SkillArea, number]>).sort(\n ([leftKey, left], [rightKey, right]) => right - left || leftKey.localeCompare(rightKey),\n )[0]?.[0] ?? \"code\"\n );\n}\n\nfunction weakestSkill(vector: Record<SkillArea, number>): SkillArea {\n return (\n (Object.entries(vector) as Array<[SkillArea, number]>).sort(\n ([leftKey, left], [rightKey, right]) => left - right || leftKey.localeCompare(rightKey),\n )[0]?.[0] ?? \"growth\"\n );\n}\n\nfunction sharedCount(left: readonly string[], right: readonly string[]): number {\n const rightSet = new Set(right.map((item) => item.toLowerCase()));\n return left.filter((item) => rightSet.has(item.toLowerCase())).length;\n}\n\nfunction consentKey(from: string, to: string): string {\n return `${from}->${to}`;\n}\n\nexport class CofounderMatch {\n readonly #tenantId: string;\n readonly #debugRoot: string;\n readonly #contentStore: ContentStore;\n readonly #eventLog: EventLog;\n readonly #profiles = new Map<string, FounderProfile>();\n readonly #interests = new Set<string>();\n\n private constructor(\n options: Required<Pick<CofounderMatchOptions, \"tenantId\" | \"contentStore\" | \"eventLog\">> &\n Pick<CofounderMatchOptions, \"debugRoot\">,\n ) {\n this.#tenantId = requireTenant(options.tenantId);\n this.#debugRoot = options.debugRoot ?? process.cwd();\n this.#contentStore = options.contentStore;\n this.#eventLog = options.eventLog;\n }\n\n static async open(\n root = \".nebutra/cofounder-match\",\n options: Omit<CofounderMatchOptions, \"contentStore\" | \"eventLog\"> = {},\n ): Promise<CofounderMatch> {\n const tenantId = options.tenantId ?? \"local\";\n await mkdir(root, { recursive: true });\n const contentStore = await ContentStore.open(join(root, \"content\"), { tenantId });\n const eventLog = await EventLog.open(join(root, \"event-log\"), { tenantId });\n return new CofounderMatch({ ...options, tenantId, contentStore, eventLog });\n }\n\n async buildProfileFromActivity(input: ActivityProfileInput): Promise<FounderProfile> {\n const profile: FounderProfile = {\n founderId: input.founderId,\n activeDays: input.activeDays,\n activityVerified: input.activeDays >= 30,\n ...(input.activeDays < 30\n ? { lockedReason: \"Cofounder matching unlocks after 30 days of real activity.\" }\n : {}),\n skillVector: skillVector(input.playCounts),\n domainTags: input.domainTags,\n communicationStyle: input.communicationSamples,\n };\n const path = `cofounder-match/profiles/${input.founderId}.json`;\n const snapshot = `${JSON.stringify(profile, null, 2)}\\n`;\n await this.#contentStore.write(path, snapshot);\n this.#profiles.set(input.founderId, profile);\n await this.#debug({\n type: \"profile\",\n tenantId: this.#tenantId,\n founderId: input.founderId,\n activityVerified: profile.activityVerified,\n });\n return profile;\n }\n\n scoreMatch(left: FounderProfile, right: FounderProfile): MatchScore {\n const leftWeak = weakestSkill(left.skillVector);\n const rightStrong = strongestSkill(right.skillVector);\n const rightWeak = weakestSkill(right.skillVector);\n const leftStrong = strongestSkill(left.skillVector);\n const growthFill = left.skillVector.growth <= 10 && right.skillVector.growth >= 30 ? 45 : 0;\n const codeFill = right.skillVector.code <= 10 && left.skillVector.code >= 30 ? 25 : 0;\n const supportFill = left.skillVector.support <= 5 && right.skillVector.support >= 15 ? 10 : 0;\n const brandFill = right.skillVector.brand <= 5 && left.skillVector.brand >= 10 ? 10 : 0;\n const complements = Math.min(100, 20 + growthFill + codeFill + supportFill + brandFill);\n const domainAdjacency = Math.min(100, 55 + sharedCount(left.domainTags, right.domainTags) * 20);\n const paceCompatibility = Math.max(40, 100 - Math.abs(left.activeDays - right.activeDays));\n const overall = Math.round(\n Math.min(100, complements * 0.55 + domainAdjacency * 0.25 + paceCompatibility * 0.2),\n );\n const why = [\n `${right.founderId} is strong in ${rightStrong[0]?.toUpperCase()}${rightStrong.slice(\n 1,\n )}, which complements ${left.founderId}'s ${leftWeak} gap.`,\n `${left.founderId} is strong in ${leftStrong}, which balances ${right.founderId}'s ${rightWeak} gap.`,\n `Shared domains: ${sharedCount(left.domainTags, right.domainTags)}.`,\n ];\n return {\n leftFounderId: left.founderId,\n rightFounderId: right.founderId,\n overall,\n skillComplementarity: Math.min(100, complements),\n domainAdjacency,\n paceCompatibility,\n why,\n };\n }\n\n async expressInterest(fromFounderId: string, toFounderId: string): Promise<void> {\n this.#interests.add(consentKey(fromFounderId, toFounderId));\n await this.#debug({ type: \"interest\", tenantId: this.#tenantId, fromFounderId, toFounderId });\n }\n\n async startChat(leftFounderId: string, rightFounderId: string): Promise<ChatThread> {\n if (\n !this.#interests.has(consentKey(leftFounderId, rightFounderId)) ||\n !this.#interests.has(consentKey(rightFounderId, leftFounderId))\n ) {\n throw new CapabilityError(\"cofounder-match\", \"Mutual consent is required before chat\", {\n suggestion: \"Wait for mutual interest before opening a cofounder intro thread.\",\n statusCode: 403,\n });\n }\n const thread: ChatThread = {\n threadId: assetId(\"cofounder_chat\", `${leftFounderId}_${rightFounderId}`),\n threadKind: \"mutual-consent-intro\",\n founders: [leftFounderId, rightFounderId],\n icebreaker: `${leftFounderId}, start with the specific work you admired in ${rightFounderId}'s profile.`,\n };\n const path = `cofounder-match/chats/${thread.threadId}.json`;\n const snapshot = `${JSON.stringify(thread, null, 2)}\\n`;\n await this.#contentStore.write(path, snapshot);\n await this.#eventLog.commit({\n traceId: assetId(\"cofounder_match_chat\", thread.threadId),\n kind: \"content_write\",\n affected: [path],\n parent: null,\n snapshot: { [path]: snapshot },\n });\n await this.#debug({\n type: \"start_chat\",\n tenantId: this.#tenantId,\n founders: thread.founders,\n });\n return thread;\n }\n\n async doctor(): Promise<CofounderMatchDoctorReport> {\n const report: CofounderMatchDoctorReport = {\n capability: \"cofounder-match\",\n ok: true,\n checkedAt: new Date().toISOString(),\n features: [\"activity-verified-profile\", \"explainable-score\", \"mutual-consent-intro\"],\n suggestion:\n \"Local matching contracts are ready; encrypted chat and identity providers remain adapter handoffs.\",\n };\n await this.#debug({ type: \"doctor\", tenantId: this.#tenantId, profiles: this.#profiles.size });\n return report;\n }\n\n async close(): Promise<void> {\n await this.#contentStore.close();\n }\n\n async #debug(entry: Record<string, unknown>): Promise<void> {\n await appendCapabilityDebug(\"cofounder-match\", entry, { root: this.#debugRoot });\n }\n}\n\nexport async function readCofounderMatchDebug(\n root = process.cwd(),\n limit = 20,\n): Promise<unknown[]> {\n return readCapabilityDebug(\"cofounder-match\", { root, limit });\n}\n"],"mappings":"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","names":[]}
|