@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.
@@ -1,6 +1,6 @@
1
- {"at":"2026-05-18T16:46:03.917Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
2
- {"at":"2026-05-18T16:46:04.061Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
3
- {"at":"2026-05-18T16:46:04.082Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
4
- {"at":"2026-05-18T16:46:04.143Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
5
- {"at":"2026-05-18T16:46:04.149Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
6
- {"at":"2026-05-18T16:46:04.186Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
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-18T16:46:03.884Z","type":"reindex","tenantId":"tenant_a","files":0}
2
- {"at":"2026-05-18T16:46:03.916Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
3
- {"at":"2026-05-18T16:46:03.993Z","type":"reindex","tenantId":"tenant_a","files":0}
4
- {"at":"2026-05-18T16:46:04.006Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
5
- {"at":"2026-05-18T16:46:04.082Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
6
- {"at":"2026-05-18T16:46:04.138Z","type":"reindex","tenantId":"tenant_a","files":0}
7
- {"at":"2026-05-18T16:46:04.167Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpbfralx.json"}
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":"cofounder_match_chat_cofounder_chat_alice_sarah_mpbfralx_mpbframf","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpbfralx.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpbfralx.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpbfralx\",\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":"d54a2a323090913c76ffed537cfe325b639ecfec29c55232353ea0a5ca504378","tenantId":"tenant_a","at":"2026-05-18T16:46:04.175Z","summary":"content_write touched 1 path(s)","objectHashes":["3c774738a169182a5070790ade6e05e82836951dfae329df5d85852bf3d487c6"]}
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"]}
@@ -1,5 +1,5 @@
1
1
 
2
- > @nebutra/cofounder-match@0.1.1 build /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
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
  CLI Building entry: src/cli.ts, src/index.ts
@@ -11,12 +11,12 @@
11
11
  ESM Build start
12
12
  ESM dist/cli.js 1.27 KB
13
13
  ESM dist/index.js 172.00 B
14
- ESM dist/chunk-ZXTCDLEE.js 7.05 KB
14
+ ESM dist/chunk-3HNHQK4D.js 7.10 KB
15
15
  ESM dist/cli.js.map 2.27 KB
16
16
  ESM dist/index.js.map 71.00 B
17
- ESM dist/chunk-ZXTCDLEE.js.map 14.50 KB
18
- ESM ⚡️ Build success in 78ms
17
+ ESM dist/chunk-3HNHQK4D.js.map 14.51 KB
18
+ ESM ⚡️ Build success in 74ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 6823ms
20
+ DTS ⚡️ Build success in 14147ms
21
21
  DTS dist/cli.d.ts 13.00 B
22
22
  DTS dist/index.d.ts 2.45 KB
@@ -1,16 +1,14 @@
1
1
 
2
- > @nebutra/cofounder-match@0.1.1 test /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
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
   RUN  v4.1.4 /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
7
7
 
8
- (node:10937) ExperimentalWarning: SQLite is an experimental feature and might change at any time
9
- (Use `node --trace-warnings ...` to show where the warning was created)
10
- ✓ src/index.test.ts (3 tests) 479ms
8
+ ✓ src/index.test.ts (3 tests) 408ms
11
9
 
12
10
   Test Files  1 passed (1)
13
11
   Tests  3 passed (3)
14
-  Start at  16:46:01
15
-  Duration  2.27s (transform 837ms, setup 0ms, import 981ms, tests 479ms, environment 0ms)
12
+  Start at  08:15:18
13
+  Duration  1.61s (transform 642ms, setup 0ms, import 793ms, tests 408ms, environment 6ms)
16
14
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @nebutra/cofounder-match@0.1.1 typecheck /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
2
+ > @nebutra/cofounder-match@0.1.2 typecheck /home/runner/work/Nebutra-Sailor/Nebutra-Sailor/packages/ai/cofounder-match
3
3
  > tsc --noEmit
4
4
 
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 = requireTenant(options.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-ZXTCDLEE.js.map
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
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CofounderMatch,
3
3
  readCofounderMatchDebug
4
- } from "./chunk-ZXTCDLEE.js";
4
+ } from "./chunk-3HNHQK4D.js";
5
5
 
6
6
  // src/cli.ts
7
7
  var command = process.argv[2] ?? "doctor";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CofounderMatch,
3
3
  readCofounderMatchDebug
4
- } from "./chunk-ZXTCDLEE.js";
4
+ } from "./chunk-3HNHQK4D.js";
5
5
  export {
6
6
  CofounderMatch,
7
7
  readCofounderMatchDebug
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebutra/cofounder-match",
3
- "version": "0.1.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.0",
33
- "@nebutra/content-store": "0.1.0",
34
- "@nebutra/errors": "0.1.0",
35
- "@nebutra/event-log": "0.1.0",
36
- "@nebutra/generation-context": "0.1.0"
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 = requireTenant(options.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":[]}