xuym-codex-collab 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -110
- package/apps/onboarding/bundle.mjs +24 -0
- package/apps/onboarding/discovery.mjs +44 -0
- package/apps/onboarding/errors.mjs +1 -0
- package/apps/onboarding/main.mjs +32 -0
- package/apps/onboarding/manager.mjs +405 -0
- package/apps/onboarding/server.mjs +56 -0
- package/apps/onboarding/web/app.js +128 -0
- package/apps/onboarding/web/index.html +13 -0
- package/apps/onboarding/web/style.css +3 -0
- package/apps/peer/desktop.mjs +8 -6
- package/apps/peer/mcp.mjs +1 -1
- package/apps/peer/runner.mjs +5 -5
- package/apps/peer/runtime.mjs +4 -1
- package/apps/peer/wecom.mjs +70 -21
- package/bin/codex-collab.mjs +10 -7
- package/docs/architecture.md +3 -1
- package/docs/desktop-poll.md +15 -7
- package/docs/legacy-center.md +109 -0
- package/docs/onboarding.md +74 -72
- package/docs/peer.md +12 -6
- package/docs/protocol.md +2 -0
- package/docs/team-registry.md +55 -0
- package/docs/terminal-onboarding.md +98 -0
- package/package.json +6 -3
- package/packages/codex-kit/templates/.agents/skills/team-collab-desktop/SKILL.md +3 -3
- package/packages/peer/config.mjs +4 -1
- package/packages/peer/protocol.mjs +22 -7
- package/packages/peer/registry.mjs +130 -0
- package/packages/peer/review.mjs +51 -0
- package/packages/peer/service.mjs +24 -16
- package/packages/peer/store.mjs +50 -5
- package/schemas/encrypted-invite.schema.json +42 -0
- package/schemas/event.schema.json +51 -0
- package/schemas/peer-event.schema.json +44 -0
- package/schemas/peer-task.schema.json +21 -0
- package/schemas/task.schema.json +18 -0
- package/schemas/team-enrollment.schema.json +61 -0
- package/schemas/team-invitation.schema.json +86 -0
- package/schemas/team-policy.schema.json +182 -0
- package/schemas/team-version.schema.json +70 -0
- package/scripts/peer/cli.mjs +5 -2
- package/scripts/peer/onboarding.mjs +1 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:codex-collab:team-enrollment:v1",
|
|
4
|
+
"title": "Codex Collab Dual-Signed Enrollment Request v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"request_id",
|
|
10
|
+
"invite_id",
|
|
11
|
+
"agent_id",
|
|
12
|
+
"public_key",
|
|
13
|
+
"wecom_userid",
|
|
14
|
+
"chat_id",
|
|
15
|
+
"signature",
|
|
16
|
+
"invitation_signature"
|
|
17
|
+
],
|
|
18
|
+
"properties": {
|
|
19
|
+
"schema_version": {
|
|
20
|
+
"const": 1
|
|
21
|
+
},
|
|
22
|
+
"request_id": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
|
25
|
+
},
|
|
26
|
+
"invite_id": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
|
29
|
+
},
|
|
30
|
+
"agent_id": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
33
|
+
},
|
|
34
|
+
"public_key": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"minLength": 1
|
|
37
|
+
},
|
|
38
|
+
"wecom_userid": {
|
|
39
|
+
"type": [
|
|
40
|
+
"string",
|
|
41
|
+
"null"
|
|
42
|
+
],
|
|
43
|
+
"minLength": 1,
|
|
44
|
+
"maxLength": 200
|
|
45
|
+
},
|
|
46
|
+
"chat_id": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"minLength": 1,
|
|
49
|
+
"maxLength": 200
|
|
50
|
+
},
|
|
51
|
+
"signature": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"minLength": 1
|
|
54
|
+
},
|
|
55
|
+
"invitation_signature": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"minLength": 1
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"$comment": "Runtime checks both member and invitation claim signatures, invite identity, allowed chat, expiry and userid semantics. Admin approval consumes invite_id once in a team version."
|
|
61
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:codex-collab:team-invitation:v1",
|
|
4
|
+
"title": "Codex Collab Signed Member Invitation v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"invite_id",
|
|
10
|
+
"agent_id",
|
|
11
|
+
"capabilities",
|
|
12
|
+
"bot_id",
|
|
13
|
+
"chat_ids",
|
|
14
|
+
"commands_enabled",
|
|
15
|
+
"prefer",
|
|
16
|
+
"claim_public_key",
|
|
17
|
+
"expires_at",
|
|
18
|
+
"team_hash",
|
|
19
|
+
"actor_id",
|
|
20
|
+
"signature"
|
|
21
|
+
],
|
|
22
|
+
"properties": {
|
|
23
|
+
"schema_version": {
|
|
24
|
+
"const": 1
|
|
25
|
+
},
|
|
26
|
+
"invite_id": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
|
29
|
+
},
|
|
30
|
+
"agent_id": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
33
|
+
},
|
|
34
|
+
"capabilities": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"minItems": 1,
|
|
37
|
+
"maxItems": 16,
|
|
38
|
+
"uniqueItems": true,
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"bot_id": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1,
|
|
47
|
+
"maxLength": 200
|
|
48
|
+
},
|
|
49
|
+
"chat_ids": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"minItems": 1,
|
|
52
|
+
"items": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"minLength": 1,
|
|
55
|
+
"maxLength": 200
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"commands_enabled": {
|
|
59
|
+
"type": "boolean"
|
|
60
|
+
},
|
|
61
|
+
"prefer": {
|
|
62
|
+
"type": "boolean"
|
|
63
|
+
},
|
|
64
|
+
"claim_public_key": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"minLength": 1
|
|
67
|
+
},
|
|
68
|
+
"expires_at": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"format": "date-time"
|
|
71
|
+
},
|
|
72
|
+
"team_hash": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
75
|
+
},
|
|
76
|
+
"actor_id": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
79
|
+
},
|
|
80
|
+
"signature": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"minLength": 1
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"$comment": "Runtime verifies administrator signature under team_hash, Ed25519 claim key, expiry, and conflicts with existing members or assignments. No bot Secret or private keys are allowed here."
|
|
86
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:codex-collab:team-policy:v3",
|
|
4
|
+
"title": "Codex Collab Peer Team Policy v2/v3",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"repo",
|
|
10
|
+
"default_route",
|
|
11
|
+
"reviewer",
|
|
12
|
+
"agents",
|
|
13
|
+
"routes",
|
|
14
|
+
"policy"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"schema_version": {
|
|
18
|
+
"enum": [
|
|
19
|
+
2,
|
|
20
|
+
3
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"repo": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"minLength": 1
|
|
26
|
+
},
|
|
27
|
+
"default_route": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
30
|
+
},
|
|
31
|
+
"reviewer": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
34
|
+
},
|
|
35
|
+
"agents": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"minProperties": 1,
|
|
38
|
+
"propertyNames": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
41
|
+
},
|
|
42
|
+
"additionalProperties": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"additionalProperties": true,
|
|
45
|
+
"required": [
|
|
46
|
+
"role",
|
|
47
|
+
"capabilities",
|
|
48
|
+
"max_concurrent_tasks",
|
|
49
|
+
"public_key"
|
|
50
|
+
],
|
|
51
|
+
"properties": {
|
|
52
|
+
"role": {
|
|
53
|
+
"enum": [
|
|
54
|
+
"admin",
|
|
55
|
+
"member"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"capabilities": {
|
|
59
|
+
"type": "array",
|
|
60
|
+
"items": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"max_concurrent_tasks": {
|
|
66
|
+
"type": "integer",
|
|
67
|
+
"minimum": 1,
|
|
68
|
+
"maximum": 16
|
|
69
|
+
},
|
|
70
|
+
"public_key": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"minLength": 1
|
|
73
|
+
},
|
|
74
|
+
"wecom_userid": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"minLength": 1
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"routes": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"propertyNames": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
86
|
+
},
|
|
87
|
+
"additionalProperties": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"minItems": 1,
|
|
90
|
+
"uniqueItems": true,
|
|
91
|
+
"items": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"policy": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"additionalProperties": true,
|
|
100
|
+
"required": [
|
|
101
|
+
"claim_timeout_ms",
|
|
102
|
+
"lease_ms",
|
|
103
|
+
"clock_skew_ms",
|
|
104
|
+
"max_attempts"
|
|
105
|
+
],
|
|
106
|
+
"properties": {
|
|
107
|
+
"claim_timeout_ms": {
|
|
108
|
+
"type": "integer",
|
|
109
|
+
"minimum": 10,
|
|
110
|
+
"maximum": 3600000
|
|
111
|
+
},
|
|
112
|
+
"lease_ms": {
|
|
113
|
+
"type": "integer",
|
|
114
|
+
"minimum": 100,
|
|
115
|
+
"maximum": 3600000
|
|
116
|
+
},
|
|
117
|
+
"clock_skew_ms": {
|
|
118
|
+
"type": "integer",
|
|
119
|
+
"minimum": 0,
|
|
120
|
+
"maximum": 60000
|
|
121
|
+
},
|
|
122
|
+
"max_attempts": {
|
|
123
|
+
"type": "integer",
|
|
124
|
+
"minimum": 1,
|
|
125
|
+
"maximum": 20
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"review_rules": {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"propertyNames": {
|
|
132
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
133
|
+
},
|
|
134
|
+
"additionalProperties": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"additionalProperties": false,
|
|
137
|
+
"required": [
|
|
138
|
+
"required",
|
|
139
|
+
"reviewer",
|
|
140
|
+
"notify"
|
|
141
|
+
],
|
|
142
|
+
"properties": {
|
|
143
|
+
"required": {
|
|
144
|
+
"type": "boolean"
|
|
145
|
+
},
|
|
146
|
+
"reviewer": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"pattern": "^(owner|admin|member:[a-zA-Z0-9_-]{1,64})$"
|
|
149
|
+
},
|
|
150
|
+
"notify": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"pattern": "^(owner|reviewer|none|member:[a-zA-Z0-9_-]{1,64})$"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"$comment": "Runtime verifies distinct Ed25519 keys and owner IDs, valid reviewer and route capabilities, and clock skew below half the lease. v3 requires a review rule for every route; specific members require a verified owner. v2 forbids review_rules so old clients cannot silently bypass gates.",
|
|
159
|
+
"allOf": [
|
|
160
|
+
{
|
|
161
|
+
"if": {
|
|
162
|
+
"properties": {
|
|
163
|
+
"schema_version": {
|
|
164
|
+
"const": 3
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"then": {
|
|
169
|
+
"required": [
|
|
170
|
+
"review_rules"
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
"else": {
|
|
174
|
+
"not": {
|
|
175
|
+
"required": [
|
|
176
|
+
"review_rules"
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:codex-collab:team-version:v1",
|
|
4
|
+
"title": "Codex Collab Signed Team Version v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"version",
|
|
10
|
+
"parent_hash",
|
|
11
|
+
"team_hash",
|
|
12
|
+
"team",
|
|
13
|
+
"actor_id",
|
|
14
|
+
"signature"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"schema_version": {
|
|
18
|
+
"const": 1
|
|
19
|
+
},
|
|
20
|
+
"version": {
|
|
21
|
+
"type": "integer",
|
|
22
|
+
"minimum": 1
|
|
23
|
+
},
|
|
24
|
+
"parent_hash": {
|
|
25
|
+
"oneOf": [
|
|
26
|
+
{
|
|
27
|
+
"type": "null"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"type": "string",
|
|
31
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"team_hash": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
38
|
+
},
|
|
39
|
+
"team": {
|
|
40
|
+
"$ref": "urn:codex-collab:team-policy:v2"
|
|
41
|
+
},
|
|
42
|
+
"actor_id": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"pattern": "^[a-zA-Z0-9_-]{1,64}$"
|
|
45
|
+
},
|
|
46
|
+
"enrollment": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"additionalProperties": false,
|
|
49
|
+
"required": [
|
|
50
|
+
"invite_id",
|
|
51
|
+
"request_id"
|
|
52
|
+
],
|
|
53
|
+
"properties": {
|
|
54
|
+
"invite_id": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
|
57
|
+
},
|
|
58
|
+
"request_id": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"signature": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"minLength": 1
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"$comment": "Runtime verifies pinned root hash, contiguous version and parent chain, canonical team_hash, previous-admin signature, immutable existing identities and local anti-rollback checkpoint."
|
|
70
|
+
}
|
package/scripts/peer/cli.mjs
CHANGED
|
@@ -102,8 +102,11 @@ switch (command) {
|
|
|
102
102
|
if (command === 'list') task = await service.list();
|
|
103
103
|
if (command === 'read') task = await service.read(args[0]);
|
|
104
104
|
if (command === 'review') {
|
|
105
|
-
if (!['approved', 'changes_requested'].includes(args[1])) throw new Error('review task-id approved|changes_requested');
|
|
106
|
-
|
|
105
|
+
if (!['approved', 'changes_requested'].includes(args[1])) throw new Error('review task-id approved|changes_requested [R-<seq>] [feedback]');
|
|
106
|
+
const revision = /^R-([1-9][0-9]*)$/.exec(args[2] || '');
|
|
107
|
+
if (args[2]?.startsWith('R-') && (!revision || !Number.isSafeInteger(Number(revision[1])))) throw new Error('invalid review revision; use R-<seq> from the current notification');
|
|
108
|
+
const summary = args.slice(revision ? 3 : 2).join(' ');
|
|
109
|
+
task = await service.report(args[0], { type: 'reviewed', decision: args[1], ...(summary ? { summary } : {}) }, {}, undefined, revision ? Number(revision[1]) : undefined);
|
|
107
110
|
}
|
|
108
111
|
if (command === 'complete') task = await service.report(args[0], { type: 'completed' });
|
|
109
112
|
if (command === 'reopen') task = await service.report(args[0], { type: 'reopened', summary: args.slice(1).join(' ') });
|
|
@@ -44,7 +44,7 @@ export async function readPublicKeyFile(path) {
|
|
|
44
44
|
return key.export({ type: 'spki', format: 'pem' });
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
async function getOrCreateIdentityFiles(agentId, directory) {
|
|
47
|
+
export async function getOrCreateIdentityFiles(agentId, directory) {
|
|
48
48
|
if (!idPattern.test(agentId || '') || !isAbsolute(directory)) throw new Error('provide a valid agent ID and absolute identity directory');
|
|
49
49
|
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
50
50
|
const privatePath = join(directory, `${agentId}.private.json`);
|