@nebutra/cofounder-match 0.1.3 → 0.1.4
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/package.json +19 -9
- package/.nebutra/debug/cofounder-match.jsonl +0 -48
- package/.nebutra/debug/content-store.jsonl +0 -56
- package/.nebutra/debug/event-log.jsonl +0 -8
- package/.turbo/turbo-build.log +0 -22
- package/.turbo/turbo-test.log +0 -16
- package/.turbo/turbo-typecheck.log +0 -4
- package/examples/doctor.ts +0 -11
- package/examples/mutual-consent.ts +0 -13
- package/examples/quickstart.ts +0 -18
- package/plays/seek_cofounder/SKILL.md +0 -23
- package/src/cli.ts +0 -35
- package/src/index.test.ts +0 -78
- package/src/index.ts +0 -256
- package/tsconfig.json +0 -9
- package/tsup.config.ts +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebutra/cofounder-match",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Behavior-verified cofounder profile, matching, and mutual-consent introduction surface",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,17 +23,21 @@
|
|
|
23
23
|
"category": "ai",
|
|
24
24
|
"summary": "Real-activity-based founder matching with explainable complementarity"
|
|
25
25
|
},
|
|
26
|
-
"main": "./
|
|
27
|
-
"types": "./
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
28
|
"exports": {
|
|
29
|
-
".":
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
30
34
|
},
|
|
31
35
|
"dependencies": {
|
|
32
|
-
"@nebutra/
|
|
33
|
-
"@nebutra/
|
|
34
|
-
"@nebutra/
|
|
35
|
-
"@nebutra/
|
|
36
|
-
"@nebutra/
|
|
36
|
+
"@nebutra/content-store": "0.1.4",
|
|
37
|
+
"@nebutra/capability-kit": "0.2.4",
|
|
38
|
+
"@nebutra/event-log": "0.1.4",
|
|
39
|
+
"@nebutra/generation-context": "0.1.3",
|
|
40
|
+
"@nebutra/errors": "0.1.2"
|
|
37
41
|
},
|
|
38
42
|
"devDependencies": {
|
|
39
43
|
"@types/node": "^25.9.1",
|
|
@@ -54,6 +58,12 @@
|
|
|
54
58
|
"publishConfig": {
|
|
55
59
|
"access": "public"
|
|
56
60
|
},
|
|
61
|
+
"files": [
|
|
62
|
+
"dist",
|
|
63
|
+
"README.md",
|
|
64
|
+
"LICENSE",
|
|
65
|
+
"CHANGELOG.md"
|
|
66
|
+
],
|
|
57
67
|
"scripts": {
|
|
58
68
|
"build": "tsup",
|
|
59
69
|
"test": "vitest run",
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{"at":"2026-05-18T15:31:08.508Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
2
|
-
{"at":"2026-05-18T15:31:08.521Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
3
|
-
{"at":"2026-05-18T15:31:08.523Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
4
|
-
{"at":"2026-05-18T15:31:08.533Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
5
|
-
{"at":"2026-05-18T15:31:08.534Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
6
|
-
{"at":"2026-05-18T15:31:08.540Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
7
|
-
{"at":"2026-05-18T15:31:44.914Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
8
|
-
{"at":"2026-05-18T15:31:44.920Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
9
|
-
{"at":"2026-05-18T15:31:44.921Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
10
|
-
{"at":"2026-05-18T15:31:44.925Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
11
|
-
{"at":"2026-05-18T15:31:44.926Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
12
|
-
{"at":"2026-05-18T15:31:44.929Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
13
|
-
{"at":"2026-05-18T15:35:24.768Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
14
|
-
{"at":"2026-05-18T15:35:24.785Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
15
|
-
{"at":"2026-05-18T15:35:24.788Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
16
|
-
{"at":"2026-05-18T15:35:24.796Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
17
|
-
{"at":"2026-05-18T15:35:24.798Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
18
|
-
{"at":"2026-05-18T15:35:24.803Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
19
|
-
{"at":"2026-05-18T15:37:13.022Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
20
|
-
{"at":"2026-05-18T15:37:13.036Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
21
|
-
{"at":"2026-05-18T15:37:13.038Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
22
|
-
{"at":"2026-05-18T15:37:13.048Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
23
|
-
{"at":"2026-05-18T15:37:13.050Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
24
|
-
{"at":"2026-05-18T15:37:13.056Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
25
|
-
{"at":"2026-05-19T05:21:59.017Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
26
|
-
{"at":"2026-05-19T05:21:59.023Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
27
|
-
{"at":"2026-05-19T05:21:59.024Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
28
|
-
{"at":"2026-05-19T05:21:59.028Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
29
|
-
{"at":"2026-05-19T05:21:59.029Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
30
|
-
{"at":"2026-05-19T05:21:59.031Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
31
|
-
{"at":"2026-05-19T05:25:38.956Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
32
|
-
{"at":"2026-05-19T05:25:38.966Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
33
|
-
{"at":"2026-05-19T05:25:38.968Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
34
|
-
{"at":"2026-05-19T05:25:38.972Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
35
|
-
{"at":"2026-05-19T05:25:38.973Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
36
|
-
{"at":"2026-05-19T05:25:38.977Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
37
|
-
{"at":"2026-05-30T21:07:14.401Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
38
|
-
{"at":"2026-05-30T21:07:14.462Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
39
|
-
{"at":"2026-05-30T21:07:14.467Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
40
|
-
{"at":"2026-05-30T21:07:14.480Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
41
|
-
{"at":"2026-05-30T21:07:14.484Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
42
|
-
{"at":"2026-05-30T21:07:14.496Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
43
|
-
{"at":"2026-07-01T01:40:41.865Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":false}
|
|
44
|
-
{"at":"2026-07-01T01:40:41.982Z","type":"profile","tenantId":"tenant_a","founderId":"alice","activityVerified":true}
|
|
45
|
-
{"at":"2026-07-01T01:40:41.984Z","type":"profile","tenantId":"tenant_a","founderId":"sarah","activityVerified":true}
|
|
46
|
-
{"at":"2026-07-01T01:40:41.997Z","type":"interest","tenantId":"tenant_a","fromFounderId":"alice","toFounderId":"sarah"}
|
|
47
|
-
{"at":"2026-07-01T01:40:42.000Z","type":"interest","tenantId":"tenant_a","fromFounderId":"sarah","toFounderId":"alice"}
|
|
48
|
-
{"at":"2026-07-01T01:40:42.024Z","type":"start_chat","tenantId":"tenant_a","founders":["alice","sarah"]}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
{"at":"2026-05-18T15:31:08.495Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
2
|
-
{"at":"2026-05-18T15:31:08.507Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
3
|
-
{"at":"2026-05-18T15:31:08.519Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
4
|
-
{"at":"2026-05-18T15:31:08.521Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
5
|
-
{"at":"2026-05-18T15:31:08.523Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
6
|
-
{"at":"2026-05-18T15:31:08.532Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
7
|
-
{"at":"2026-05-18T15:31:08.536Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd2xrq.json"}
|
|
8
|
-
{"at":"2026-05-18T15:31:44.910Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
9
|
-
{"at":"2026-05-18T15:31:44.914Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
10
|
-
{"at":"2026-05-18T15:31:44.919Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
11
|
-
{"at":"2026-05-18T15:31:44.920Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
12
|
-
{"at":"2026-05-18T15:31:44.921Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
13
|
-
{"at":"2026-05-18T15:31:44.925Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
14
|
-
{"at":"2026-05-18T15:31:44.927Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd3pum.json"}
|
|
15
|
-
{"at":"2026-05-18T15:35:24.752Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
16
|
-
{"at":"2026-05-18T15:35:24.767Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
17
|
-
{"at":"2026-05-18T15:35:24.780Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
18
|
-
{"at":"2026-05-18T15:35:24.784Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
19
|
-
{"at":"2026-05-18T15:35:24.788Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
20
|
-
{"at":"2026-05-18T15:35:24.795Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
21
|
-
{"at":"2026-05-18T15:35:24.800Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd8fi6.json"}
|
|
22
|
-
{"at":"2026-05-18T15:37:13.013Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
23
|
-
{"at":"2026-05-18T15:37:13.021Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
24
|
-
{"at":"2026-05-18T15:37:13.033Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
25
|
-
{"at":"2026-05-18T15:37:13.036Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
26
|
-
{"at":"2026-05-18T15:37:13.038Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
27
|
-
{"at":"2026-05-18T15:37:13.047Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
28
|
-
{"at":"2026-05-18T15:37:13.052Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpbdar16.json"}
|
|
29
|
-
{"at":"2026-05-19T05:21:59.012Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
30
|
-
{"at":"2026-05-19T05:21:59.017Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
31
|
-
{"at":"2026-05-19T05:21:59.022Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
32
|
-
{"at":"2026-05-19T05:21:59.023Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
33
|
-
{"at":"2026-05-19T05:21:59.024Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
34
|
-
{"at":"2026-05-19T05:21:59.028Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
35
|
-
{"at":"2026-05-19T05:21:59.030Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpc6renp.json"}
|
|
36
|
-
{"at":"2026-05-19T05:25:38.951Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
37
|
-
{"at":"2026-05-19T05:25:38.955Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
38
|
-
{"at":"2026-05-19T05:25:38.964Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
39
|
-
{"at":"2026-05-19T05:25:38.966Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
40
|
-
{"at":"2026-05-19T05:25:38.968Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
41
|
-
{"at":"2026-05-19T05:25:38.972Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
42
|
-
{"at":"2026-05-19T05:25:38.974Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpc6w4d9.json"}
|
|
43
|
-
{"at":"2026-05-30T21:07:14.388Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
44
|
-
{"at":"2026-05-30T21:07:14.399Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
45
|
-
{"at":"2026-05-30T21:07:14.414Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
46
|
-
{"at":"2026-05-30T21:07:14.460Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
47
|
-
{"at":"2026-05-30T21:07:14.465Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
48
|
-
{"at":"2026-05-30T21:07:14.478Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
49
|
-
{"at":"2026-05-30T21:07:14.490Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mpsuddx1.json"}
|
|
50
|
-
{"at":"2026-07-01T01:40:41.859Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
51
|
-
{"at":"2026-07-01T01:40:41.865Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
52
|
-
{"at":"2026-07-01T01:40:41.979Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
53
|
-
{"at":"2026-07-01T01:40:41.982Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/alice.json"}
|
|
54
|
-
{"at":"2026-07-01T01:40:41.984Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/profiles/sarah.json"}
|
|
55
|
-
{"at":"2026-07-01T01:40:41.996Z","type":"reindex","tenantId":"tenant_a","files":0}
|
|
56
|
-
{"at":"2026-07-01T01:40:42.006Z","type":"write","tenantId":"tenant_a","path":"cofounder-match/chats/cofounder_chat_alice_sarah_mr1esgpd.json"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpbd2xrq_mpbd2xrt","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpbd2xrq.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd2xrq.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpbd2xrq\",\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":"0ca60253f3a86ee606b67c835a96ca7a2d62c1171f8c16db727eb8ad855f8567","tenantId":"tenant_a","at":"2026-05-18T15:31:08.539Z","summary":"content_write touched 1 path(s)","objectHashes":["8d4679ff44d1ad722648bb0342948dd4104e47efbb182c193e0dd1f1f45ececc"]}
|
|
2
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpbd3pum_mpbd3pun","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpbd3pum.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd3pum.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpbd3pum\",\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":"1c45e168ba879d71c4bb0261a14b647105044e4a4e8fe4dbfa614318c24d9a9d","tenantId":"tenant_a","at":"2026-05-18T15:31:44.928Z","summary":"content_write touched 1 path(s)","objectHashes":["8140cb18789cd09ef293e141ca734f6cbb46861f5bc3d3b2b10e7bec0db96d07"]}
|
|
3
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpbd8fi6_mpbd8fi8","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpbd8fi6.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpbd8fi6.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpbd8fi6\",\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":"bd5149640ffc264d9d9490eff7ff405df2a6a2995f4fba17f3b70b650af82e43","tenantId":"tenant_a","at":"2026-05-18T15:35:24.802Z","summary":"content_write touched 1 path(s)","objectHashes":["4c37ad33297a210ddbd29cdf3111f9361c268841be7ea69d336f27da6c0d7125"]}
|
|
4
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpbdar16_mpbdar19","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpbdar16.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpbdar16.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpbdar16\",\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":"076695d47909fa5dd6c52c6540ae0861f0834193e40f9bfd3d97ea6dd8925890","tenantId":"tenant_a","at":"2026-05-18T15:37:13.055Z","summary":"content_write touched 1 path(s)","objectHashes":["2cfbc85f0c66043b478ff568b5c0f6cd59c62321b079e35cf283890722e4102e"]}
|
|
5
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpc6renp_mpc6renq","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpc6renp.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpc6renp.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpc6renp\",\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":"9ac2a23793f9ab0e5f7da467350ba39cd3a81de59a1abc09bf05e28362871434","tenantId":"tenant_a","at":"2026-05-19T05:21:59.031Z","summary":"content_write touched 1 path(s)","objectHashes":["cd0ee77d053e8c51e21e586488e1ee7e13cc957975e1c6b8e15afd9bb478969c"]}
|
|
6
|
-
{"traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpc6w4d9_mpc6w4db","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpc6w4d9.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpc6w4d9.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpc6w4d9\",\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":"e1b0556ff916cb046e140fde18d5b3a390d284abf06dd3741313b3d39c0df67f","tenantId":"tenant_a","at":"2026-05-19T05:25:38.976Z","summary":"content_write touched 1 path(s)","objectHashes":["0c3ab2d6d27f174a8c43b2ac645531e75ad2d4c373ae7c2adaf4899de1be90cd"]}
|
|
7
|
-
{"at":"2026-05-30T21:07:14.494Z","traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mpsuddx1_mpsuddx7","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mpsuddx1.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mpsuddx1.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mpsuddx1\",\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":"ca23f6b78397de98bc5b974e43920d64926b2921d3e4dbdf44cee4de78e4e34d","tenantId":"tenant_a","summary":"content_write touched 1 path(s)","objectHashes":["f6618414aa63fe367a7c7ec060cdc00e0bfe78cc90a0bf774870d0d4cf6c4c8f"]}
|
|
8
|
-
{"at":"2026-07-01T01:40:42.017Z","traceId":"cofounder_match_chat_cofounder_chat_alice_sarah_mr1esgpd_mr1esgpl","kind":"content_write","affected":["cofounder-match/chats/cofounder_chat_alice_sarah_mr1esgpd.json"],"parent":null,"snapshot":{"cofounder-match/chats/cofounder_chat_alice_sarah_mr1esgpd.json":"{\n \"threadId\": \"cofounder_chat_alice_sarah_mr1esgpd\",\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":"2981ebfbad69e52d3dab960d1f71622fb4f10fa13f2a6396e80a60a076fcb749","tenantId":"tenant_a","summary":"content_write touched 1 path(s)","objectHashes":["b3762142d444664b982e7150a2bd7d712e577efc140018abcee24539e7470225"]}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @nebutra/cofounder-match@0.1.3 build /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cofounder-match
|
|
3
|
-
> tsup
|
|
4
|
-
|
|
5
|
-
CLI Building entry: src/cli.ts, src/index.ts
|
|
6
|
-
CLI Using tsconfig: tsconfig.json
|
|
7
|
-
CLI tsup v8.5.1
|
|
8
|
-
CLI Using tsup config: /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cofounder-match/tsup.config.ts
|
|
9
|
-
CLI Target: es2022
|
|
10
|
-
CLI Cleaning output folder
|
|
11
|
-
ESM Build start
|
|
12
|
-
ESM dist/cli.js 1.27 KB
|
|
13
|
-
ESM dist/index.js 172.00 B
|
|
14
|
-
ESM dist/chunk-3HNHQK4D.js 7.10 KB
|
|
15
|
-
ESM dist/cli.js.map 2.27 KB
|
|
16
|
-
ESM dist/index.js.map 71.00 B
|
|
17
|
-
ESM dist/chunk-3HNHQK4D.js.map 14.51 KB
|
|
18
|
-
ESM ⚡️ Build success in 14ms
|
|
19
|
-
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in 3074ms
|
|
21
|
-
DTS dist/cli.d.ts 13.00 B
|
|
22
|
-
DTS dist/index.d.ts 2.45 KB
|
package/.turbo/turbo-test.log
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @nebutra/cofounder-match@0.1.2 test /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cofounder-match
|
|
3
|
-
> vitest run
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
RUN v4.1.4 /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cofounder-match
|
|
7
|
-
|
|
8
|
-
(node:57157) 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) 200ms
|
|
11
|
-
|
|
12
|
-
Test Files 1 passed (1)
|
|
13
|
-
Tests 3 passed (3)
|
|
14
|
-
Start at 09:40:38
|
|
15
|
-
Duration 3.09s (transform 989ms, setup 0ms, import 1.30s, tests 200ms, environment 0ms)
|
|
16
|
-
|
package/examples/doctor.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { CofounderMatch } from "../src/index";
|
|
2
|
-
|
|
3
|
-
const match = await CofounderMatch.open(".nebutra/cofounder-match-example", {
|
|
4
|
-
tenantId: "local",
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
process.stdout.write(`${JSON.stringify(await match.doctor(), null, 2)}\n`);
|
|
9
|
-
} finally {
|
|
10
|
-
await match.close();
|
|
11
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { CofounderMatch } from "../src/index";
|
|
2
|
-
|
|
3
|
-
const match = await CofounderMatch.open(".nebutra/cofounder-match-consent-example", {
|
|
4
|
-
tenantId: "local",
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
await match.expressInterest("alice", "sarah");
|
|
9
|
-
await match.expressInterest("sarah", "alice");
|
|
10
|
-
process.stdout.write(`${JSON.stringify(await match.startChat("alice", "sarah"), null, 2)}\n`);
|
|
11
|
-
} finally {
|
|
12
|
-
await match.close();
|
|
13
|
-
}
|
package/examples/quickstart.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { CofounderMatch } from "../src/index";
|
|
2
|
-
|
|
3
|
-
const match = await CofounderMatch.open(".nebutra/cofounder-match-example", {
|
|
4
|
-
tenantId: "local",
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
const profile = await match.buildProfileFromActivity({
|
|
9
|
-
founderId: "alice",
|
|
10
|
-
activeDays: 31,
|
|
11
|
-
playCounts: { code: 40, growth: 3, brand: 8, support: 2 },
|
|
12
|
-
domainTags: ["developer-tools"],
|
|
13
|
-
communicationSamples: ["direct technical updates"],
|
|
14
|
-
});
|
|
15
|
-
process.stdout.write(`${JSON.stringify(profile, null, 2)}\n`);
|
|
16
|
-
} finally {
|
|
17
|
-
await match.close();
|
|
18
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: seek_cofounder
|
|
3
|
-
kind: play
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
description: Build an activity-verified profile and surface explainable cofounder matches
|
|
6
|
-
required_skills:
|
|
7
|
-
- content_store.write
|
|
8
|
-
- event_log.commit
|
|
9
|
-
sub_agents:
|
|
10
|
-
- role: match_explainer
|
|
11
|
-
allowed_skills: [content_store.write]
|
|
12
|
-
depends_on_plays: []
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## What this play does
|
|
16
|
-
|
|
17
|
-
Builds a behavior-derived founder profile and explains complementary matches.
|
|
18
|
-
|
|
19
|
-
## Boundaries
|
|
20
|
-
|
|
21
|
-
- Matching is locked until the founder has at least 30 days of real activity.
|
|
22
|
-
- Chat opens only after mutual consent.
|
|
23
|
-
- Match explanations must be visible; hidden algorithmic matching is not allowed.
|
package/src/cli.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { CofounderMatch, readCofounderMatchDebug } from "./index";
|
|
2
|
-
|
|
3
|
-
const command = process.argv[2] ?? "doctor";
|
|
4
|
-
const root = process.env.COFOUNDER_MATCH_ROOT ?? ".nebutra/cofounder-match";
|
|
5
|
-
const tenantId = process.env.NEBUTRA_TENANT_ID ?? "local";
|
|
6
|
-
|
|
7
|
-
if (command === "doctor") {
|
|
8
|
-
const match = await CofounderMatch.open(root, { tenantId });
|
|
9
|
-
try {
|
|
10
|
-
process.stdout.write(`${JSON.stringify(await match.doctor(), null, 2)}\n`);
|
|
11
|
-
} finally {
|
|
12
|
-
await match.close();
|
|
13
|
-
}
|
|
14
|
-
} else if (command === "quickstart") {
|
|
15
|
-
const match = await CofounderMatch.open(root, { tenantId });
|
|
16
|
-
try {
|
|
17
|
-
const profile = await match.buildProfileFromActivity({
|
|
18
|
-
founderId: "alice",
|
|
19
|
-
activeDays: 31,
|
|
20
|
-
playCounts: { code: 20, growth: 2, brand: 4, support: 1 },
|
|
21
|
-
domainTags: ["developer-tools"],
|
|
22
|
-
communicationSamples: ["direct technical updates"],
|
|
23
|
-
});
|
|
24
|
-
process.stdout.write(`${JSON.stringify(profile, null, 2)}\n`);
|
|
25
|
-
} finally {
|
|
26
|
-
await match.close();
|
|
27
|
-
}
|
|
28
|
-
} else if (command === "debug") {
|
|
29
|
-
process.stdout.write(
|
|
30
|
-
`${JSON.stringify({ capability: "cofounder-match", entries: await readCofounderMatchDebug() }, null, 2)}\n`,
|
|
31
|
-
);
|
|
32
|
-
} else {
|
|
33
|
-
process.stderr.write(`Unknown cofounder-match command: ${command}\n`);
|
|
34
|
-
process.exitCode = 1;
|
|
35
|
-
}
|
package/src/index.test.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { CofounderMatch, readCofounderMatchDebug } from "./index";
|
|
6
|
-
|
|
7
|
-
let root: string | undefined;
|
|
8
|
-
let matcher: CofounderMatch | undefined;
|
|
9
|
-
|
|
10
|
-
afterEach(async () => {
|
|
11
|
-
if (matcher) await matcher.close();
|
|
12
|
-
if (root) await rm(root, { recursive: true, force: true });
|
|
13
|
-
root = undefined;
|
|
14
|
-
matcher = undefined;
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
async function open(): Promise<CofounderMatch> {
|
|
18
|
-
root = await mkdtemp(join(tmpdir(), "cofounder-match-"));
|
|
19
|
-
matcher = await CofounderMatch.open(root, { tenantId: "tenant_a" });
|
|
20
|
-
return matcher;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe("cofounder-match", () => {
|
|
24
|
-
it("requires real activity before a founder can enter matching", async () => {
|
|
25
|
-
const runtime = await open();
|
|
26
|
-
|
|
27
|
-
const profile = await runtime.buildProfileFromActivity({
|
|
28
|
-
founderId: "alice",
|
|
29
|
-
activeDays: 12,
|
|
30
|
-
playCounts: { code: 12, growth: 0, brand: 3, support: 0 },
|
|
31
|
-
domainTags: ["developer-tools"],
|
|
32
|
-
communicationSamples: ["direct and technical"],
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
expect(profile.activityVerified).toBe(false);
|
|
36
|
-
expect(profile.lockedReason).toContain("30 days");
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("scores complementary founders with a transparent why explanation", async () => {
|
|
40
|
-
const runtime = await open();
|
|
41
|
-
const builder = await runtime.buildProfileFromActivity({
|
|
42
|
-
founderId: "alice",
|
|
43
|
-
activeDays: 45,
|
|
44
|
-
playCounts: { code: 120, growth: 4, brand: 12, support: 3 },
|
|
45
|
-
domainTags: ["developer-tools", "debugging"],
|
|
46
|
-
communicationSamples: ["short technical updates"],
|
|
47
|
-
});
|
|
48
|
-
const seller = await runtime.buildProfileFromActivity({
|
|
49
|
-
founderId: "sarah",
|
|
50
|
-
activeDays: 60,
|
|
51
|
-
playCounts: { code: 3, growth: 90, brand: 6, support: 18 },
|
|
52
|
-
domainTags: ["developer-tools", "sales"],
|
|
53
|
-
communicationSamples: ["warm customer notes"],
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const score = runtime.scoreMatch(builder, seller);
|
|
57
|
-
|
|
58
|
-
expect(builder.activityVerified).toBe(true);
|
|
59
|
-
expect(score.overall).toBeGreaterThan(70);
|
|
60
|
-
expect(score.why.some((reason) => reason.includes("Growth"))).toBe(true);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("opens chat only after mutual consent", async () => {
|
|
64
|
-
const runtime = await open();
|
|
65
|
-
|
|
66
|
-
await runtime.expressInterest("alice", "sarah");
|
|
67
|
-
await expect(runtime.startChat("alice", "sarah")).rejects.toMatchObject({
|
|
68
|
-
capability: "cofounder-match",
|
|
69
|
-
suggestion: expect.stringContaining("mutual"),
|
|
70
|
-
});
|
|
71
|
-
await runtime.expressInterest("sarah", "alice");
|
|
72
|
-
const chat = await runtime.startChat("alice", "sarah");
|
|
73
|
-
|
|
74
|
-
expect(chat.threadKind).toBe("mutual-consent-intro");
|
|
75
|
-
expect(chat.icebreaker).toContain("alice");
|
|
76
|
-
await expect(readCofounderMatchDebug(root)).resolves.toEqual(expect.any(Array));
|
|
77
|
-
});
|
|
78
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { mkdir } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { requireCapabilityTenant } from "@nebutra/capability-kit";
|
|
4
|
-
import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
|
|
5
|
-
import { ContentStore } from "@nebutra/content-store";
|
|
6
|
-
import { CapabilityError } from "@nebutra/errors";
|
|
7
|
-
import { EventLog } from "@nebutra/event-log";
|
|
8
|
-
import { assetId } from "@nebutra/generation-context";
|
|
9
|
-
|
|
10
|
-
export type SkillArea = "code" | "growth" | "brand" | "support";
|
|
11
|
-
|
|
12
|
-
export interface ActivityProfileInput {
|
|
13
|
-
readonly founderId: string;
|
|
14
|
-
readonly activeDays: number;
|
|
15
|
-
readonly playCounts: Partial<Record<SkillArea, number>>;
|
|
16
|
-
readonly domainTags: readonly string[];
|
|
17
|
-
readonly communicationSamples: readonly string[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface FounderProfile {
|
|
21
|
-
readonly founderId: string;
|
|
22
|
-
readonly activityVerified: boolean;
|
|
23
|
-
readonly lockedReason?: string;
|
|
24
|
-
readonly activeDays: number;
|
|
25
|
-
readonly skillVector: Record<SkillArea, number>;
|
|
26
|
-
readonly domainTags: readonly string[];
|
|
27
|
-
readonly communicationStyle: readonly string[];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface MatchScore {
|
|
31
|
-
readonly leftFounderId: string;
|
|
32
|
-
readonly rightFounderId: string;
|
|
33
|
-
readonly overall: number;
|
|
34
|
-
readonly skillComplementarity: number;
|
|
35
|
-
readonly domainAdjacency: number;
|
|
36
|
-
readonly paceCompatibility: number;
|
|
37
|
-
readonly why: readonly string[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface ChatThread {
|
|
41
|
-
readonly threadId: string;
|
|
42
|
-
readonly threadKind: "mutual-consent-intro";
|
|
43
|
-
readonly founders: readonly [string, string];
|
|
44
|
-
readonly icebreaker: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface CofounderMatchDoctorReport {
|
|
48
|
-
readonly capability: "cofounder-match";
|
|
49
|
-
readonly ok: boolean;
|
|
50
|
-
readonly checkedAt: string;
|
|
51
|
-
readonly features: readonly string[];
|
|
52
|
-
readonly suggestion?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface CofounderMatchOptions {
|
|
56
|
-
readonly tenantId?: string;
|
|
57
|
-
readonly debugRoot?: string;
|
|
58
|
-
readonly contentStore?: ContentStore;
|
|
59
|
-
readonly eventLog?: EventLog;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function skillVector(input: Partial<Record<SkillArea, number>>): Record<SkillArea, number> {
|
|
63
|
-
return {
|
|
64
|
-
code: input.code ?? 0,
|
|
65
|
-
growth: input.growth ?? 0,
|
|
66
|
-
brand: input.brand ?? 0,
|
|
67
|
-
support: input.support ?? 0,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function strongestSkill(vector: Record<SkillArea, number>): SkillArea {
|
|
72
|
-
return (
|
|
73
|
-
(Object.entries(vector) as Array<[SkillArea, number]>).sort(
|
|
74
|
-
([leftKey, left], [rightKey, right]) => right - left || leftKey.localeCompare(rightKey),
|
|
75
|
-
)[0]?.[0] ?? "code"
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function weakestSkill(vector: Record<SkillArea, number>): SkillArea {
|
|
80
|
-
return (
|
|
81
|
-
(Object.entries(vector) as Array<[SkillArea, number]>).sort(
|
|
82
|
-
([leftKey, left], [rightKey, right]) => left - right || leftKey.localeCompare(rightKey),
|
|
83
|
-
)[0]?.[0] ?? "growth"
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function sharedCount(left: readonly string[], right: readonly string[]): number {
|
|
88
|
-
const rightSet = new Set(right.map((item) => item.toLowerCase()));
|
|
89
|
-
return left.filter((item) => rightSet.has(item.toLowerCase())).length;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function consentKey(from: string, to: string): string {
|
|
93
|
-
return `${from}->${to}`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export class CofounderMatch {
|
|
97
|
-
readonly #tenantId: string;
|
|
98
|
-
readonly #debugRoot: string;
|
|
99
|
-
readonly #contentStore: ContentStore;
|
|
100
|
-
readonly #eventLog: EventLog;
|
|
101
|
-
readonly #profiles = new Map<string, FounderProfile>();
|
|
102
|
-
readonly #interests = new Set<string>();
|
|
103
|
-
|
|
104
|
-
private constructor(
|
|
105
|
-
options: Required<Pick<CofounderMatchOptions, "tenantId" | "contentStore" | "eventLog">> &
|
|
106
|
-
Pick<CofounderMatchOptions, "debugRoot">,
|
|
107
|
-
) {
|
|
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
|
-
});
|
|
116
|
-
this.#debugRoot = options.debugRoot ?? process.cwd();
|
|
117
|
-
this.#contentStore = options.contentStore;
|
|
118
|
-
this.#eventLog = options.eventLog;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
static async open(
|
|
122
|
-
root = ".nebutra/cofounder-match",
|
|
123
|
-
options: Omit<CofounderMatchOptions, "contentStore" | "eventLog"> = {},
|
|
124
|
-
): Promise<CofounderMatch> {
|
|
125
|
-
const tenantId = options.tenantId ?? "local";
|
|
126
|
-
await mkdir(root, { recursive: true });
|
|
127
|
-
const contentStore = await ContentStore.open(join(root, "content"), { tenantId });
|
|
128
|
-
const eventLog = await EventLog.open(join(root, "event-log"), { tenantId });
|
|
129
|
-
return new CofounderMatch({ ...options, tenantId, contentStore, eventLog });
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async buildProfileFromActivity(input: ActivityProfileInput): Promise<FounderProfile> {
|
|
133
|
-
const profile: FounderProfile = {
|
|
134
|
-
founderId: input.founderId,
|
|
135
|
-
activeDays: input.activeDays,
|
|
136
|
-
activityVerified: input.activeDays >= 30,
|
|
137
|
-
...(input.activeDays < 30
|
|
138
|
-
? { lockedReason: "Cofounder matching unlocks after 30 days of real activity." }
|
|
139
|
-
: {}),
|
|
140
|
-
skillVector: skillVector(input.playCounts),
|
|
141
|
-
domainTags: input.domainTags,
|
|
142
|
-
communicationStyle: input.communicationSamples,
|
|
143
|
-
};
|
|
144
|
-
const path = `cofounder-match/profiles/${input.founderId}.json`;
|
|
145
|
-
const snapshot = `${JSON.stringify(profile, null, 2)}\n`;
|
|
146
|
-
await this.#contentStore.write(path, snapshot);
|
|
147
|
-
this.#profiles.set(input.founderId, profile);
|
|
148
|
-
await this.#debug({
|
|
149
|
-
type: "profile",
|
|
150
|
-
tenantId: this.#tenantId,
|
|
151
|
-
founderId: input.founderId,
|
|
152
|
-
activityVerified: profile.activityVerified,
|
|
153
|
-
});
|
|
154
|
-
return profile;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
scoreMatch(left: FounderProfile, right: FounderProfile): MatchScore {
|
|
158
|
-
const leftWeak = weakestSkill(left.skillVector);
|
|
159
|
-
const rightStrong = strongestSkill(right.skillVector);
|
|
160
|
-
const rightWeak = weakestSkill(right.skillVector);
|
|
161
|
-
const leftStrong = strongestSkill(left.skillVector);
|
|
162
|
-
const growthFill = left.skillVector.growth <= 10 && right.skillVector.growth >= 30 ? 45 : 0;
|
|
163
|
-
const codeFill = right.skillVector.code <= 10 && left.skillVector.code >= 30 ? 25 : 0;
|
|
164
|
-
const supportFill = left.skillVector.support <= 5 && right.skillVector.support >= 15 ? 10 : 0;
|
|
165
|
-
const brandFill = right.skillVector.brand <= 5 && left.skillVector.brand >= 10 ? 10 : 0;
|
|
166
|
-
const complements = Math.min(100, 20 + growthFill + codeFill + supportFill + brandFill);
|
|
167
|
-
const domainAdjacency = Math.min(100, 55 + sharedCount(left.domainTags, right.domainTags) * 20);
|
|
168
|
-
const paceCompatibility = Math.max(40, 100 - Math.abs(left.activeDays - right.activeDays));
|
|
169
|
-
const overall = Math.round(
|
|
170
|
-
Math.min(100, complements * 0.55 + domainAdjacency * 0.25 + paceCompatibility * 0.2),
|
|
171
|
-
);
|
|
172
|
-
const why = [
|
|
173
|
-
`${right.founderId} is strong in ${rightStrong[0]?.toUpperCase()}${rightStrong.slice(
|
|
174
|
-
1,
|
|
175
|
-
)}, which complements ${left.founderId}'s ${leftWeak} gap.`,
|
|
176
|
-
`${left.founderId} is strong in ${leftStrong}, which balances ${right.founderId}'s ${rightWeak} gap.`,
|
|
177
|
-
`Shared domains: ${sharedCount(left.domainTags, right.domainTags)}.`,
|
|
178
|
-
];
|
|
179
|
-
return {
|
|
180
|
-
leftFounderId: left.founderId,
|
|
181
|
-
rightFounderId: right.founderId,
|
|
182
|
-
overall,
|
|
183
|
-
skillComplementarity: Math.min(100, complements),
|
|
184
|
-
domainAdjacency,
|
|
185
|
-
paceCompatibility,
|
|
186
|
-
why,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async expressInterest(fromFounderId: string, toFounderId: string): Promise<void> {
|
|
191
|
-
this.#interests.add(consentKey(fromFounderId, toFounderId));
|
|
192
|
-
await this.#debug({ type: "interest", tenantId: this.#tenantId, fromFounderId, toFounderId });
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
async startChat(leftFounderId: string, rightFounderId: string): Promise<ChatThread> {
|
|
196
|
-
if (
|
|
197
|
-
!this.#interests.has(consentKey(leftFounderId, rightFounderId)) ||
|
|
198
|
-
!this.#interests.has(consentKey(rightFounderId, leftFounderId))
|
|
199
|
-
) {
|
|
200
|
-
throw new CapabilityError("cofounder-match", "Mutual consent is required before chat", {
|
|
201
|
-
suggestion: "Wait for mutual interest before opening a cofounder intro thread.",
|
|
202
|
-
statusCode: 403,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
const thread: ChatThread = {
|
|
206
|
-
threadId: assetId("cofounder_chat", `${leftFounderId}_${rightFounderId}`),
|
|
207
|
-
threadKind: "mutual-consent-intro",
|
|
208
|
-
founders: [leftFounderId, rightFounderId],
|
|
209
|
-
icebreaker: `${leftFounderId}, start with the specific work you admired in ${rightFounderId}'s profile.`,
|
|
210
|
-
};
|
|
211
|
-
const path = `cofounder-match/chats/${thread.threadId}.json`;
|
|
212
|
-
const snapshot = `${JSON.stringify(thread, null, 2)}\n`;
|
|
213
|
-
await this.#contentStore.write(path, snapshot);
|
|
214
|
-
await this.#eventLog.commit({
|
|
215
|
-
traceId: assetId("cofounder_match_chat", thread.threadId),
|
|
216
|
-
kind: "content_write",
|
|
217
|
-
affected: [path],
|
|
218
|
-
parent: null,
|
|
219
|
-
snapshot: { [path]: snapshot },
|
|
220
|
-
});
|
|
221
|
-
await this.#debug({
|
|
222
|
-
type: "start_chat",
|
|
223
|
-
tenantId: this.#tenantId,
|
|
224
|
-
founders: thread.founders,
|
|
225
|
-
});
|
|
226
|
-
return thread;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async doctor(): Promise<CofounderMatchDoctorReport> {
|
|
230
|
-
const report: CofounderMatchDoctorReport = {
|
|
231
|
-
capability: "cofounder-match",
|
|
232
|
-
ok: true,
|
|
233
|
-
checkedAt: new Date().toISOString(),
|
|
234
|
-
features: ["activity-verified-profile", "explainable-score", "mutual-consent-intro"],
|
|
235
|
-
suggestion:
|
|
236
|
-
"Local matching contracts are ready; encrypted chat and identity providers remain adapter handoffs.",
|
|
237
|
-
};
|
|
238
|
-
await this.#debug({ type: "doctor", tenantId: this.#tenantId, profiles: this.#profiles.size });
|
|
239
|
-
return report;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
async close(): Promise<void> {
|
|
243
|
-
await this.#contentStore.close();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async #debug(entry: Record<string, unknown>): Promise<void> {
|
|
247
|
-
await appendCapabilityDebug("cofounder-match", entry, { root: this.#debugRoot });
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export async function readCofounderMatchDebug(
|
|
252
|
-
root = process.cwd(),
|
|
253
|
-
limit = 20,
|
|
254
|
-
): Promise<unknown[]> {
|
|
255
|
-
return readCapabilityDebug("cofounder-match", { root, limit });
|
|
256
|
-
}
|
package/tsconfig.json
DELETED