xuym-codex-collab 0.8.0 → 0.10.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 +7 -5
- package/apps/onboarding/server.mjs +16 -3
- package/apps/onboarding/web/app.js +151 -30
- package/apps/onboarding/web/effects.css +47 -0
- package/apps/onboarding/web/effects.js +323 -0
- package/apps/onboarding/web/favicon.svg +6 -0
- package/apps/onboarding/web/index.html +679 -39
- package/apps/onboarding/web/style.css +337 -14
- package/apps/onboarding/workspace.mjs +1 -1
- package/bin/postinstall.mjs +11 -0
- package/docs/onboarding-audit.md +9 -0
- package/docs/onboarding.md +20 -20
- package/docs/releases/0.10.0.md +20 -0
- package/package.json +3 -1
|
@@ -1,14 +1,337 @@
|
|
|
1
|
-
:root{
|
|
2
|
-
*{box-sizing:border-box
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
:root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-synthesis: none; }
|
|
2
|
+
* { box-sizing: border-box; }
|
|
3
|
+
[hidden] { display: none !important; }
|
|
4
|
+
body {
|
|
5
|
+
--bg: #faf9f6; --surface: #fffefa; --ink: #263c32; --muted: #879187; --line: #e4e8df;
|
|
6
|
+
--accent: #355d49; --on-accent: #fff; --wash: #eaf0e6; --hover: #f1f3eb; --shadow: #355d4909;
|
|
7
|
+
color-scheme: light; margin: 0; background: var(--bg); color: var(--ink); min-height: 100dvh; display: flex; flex-direction: column;
|
|
8
|
+
}
|
|
9
|
+
body[data-theme="night"] { color-scheme: dark; --bg: #131b19; --surface: #1a2420; --ink: #e9eee3; --muted: #82958b; --line: #2e3d34; --accent: #c3d5b0; --on-accent: #23372a; --wash: #2b3b2f; --hover: #1d2b22; --shadow: #0000000b; }
|
|
10
|
+
button, input { font: inherit; }
|
|
11
|
+
a { color: inherit; text-decoration: none; }
|
|
12
|
+
button { color: inherit; border: 0; background: none; cursor: pointer; }
|
|
13
|
+
button, a { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
|
|
14
|
+
button:focus-visible, a:focus-visible, input:focus-visible { outline: 2px solid var(--accent); outline-offset: 5px; }
|
|
15
|
+
button:disabled { cursor: default; }
|
|
16
|
+
h1, p { margin: 0; }
|
|
17
|
+
h1:focus { outline: none; }
|
|
18
|
+
.icon { width: 20px; height: 20px; flex-shrink: 0; }
|
|
19
|
+
.masthead { display: flex; align-items: center; justify-content: space-between; padding: 30px 44px; gap: 16px; }
|
|
20
|
+
.brand { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; letter-spacing: -.4px; font-weight: 550; }
|
|
21
|
+
.brand-mark { display: inline-grid; place-items: center; width: 24px; height: 27px; font: 24px/1 sans-serif; color: var(--accent); }
|
|
22
|
+
.preview-label { font-size: 10px; color: var(--muted); letter-spacing: 1px; }
|
|
23
|
+
main { width: 100%; flex: 1; padding: 50px 24px 66px; display: flex; justify-content: center; align-items: flex-start; }
|
|
24
|
+
.scene { width: 100%; max-width: 536px; }
|
|
25
|
+
.home, .project-scene, .setup-scene, .success-scene { position: relative; }
|
|
26
|
+
.intro { text-align: center; }
|
|
27
|
+
h1 { font-size: 35px; line-height: 1.4; letter-spacing: -1.4px; font-weight: 500; overflow-wrap: anywhere; }
|
|
28
|
+
.intro > p { margin-top: 13px; font-size: 13px; color: var(--muted); line-height: 1.9; letter-spacing: .15px; }
|
|
29
|
+
.scene-art { display: grid; place-items: center; width: 88px; height: 88px; position: relative; margin: 0 auto 25px; --art-wash: var(--wash); --art-ink: var(--accent); }
|
|
30
|
+
.art-halo { position: absolute; inset: -7px; border-radius: 50%; background: radial-gradient(circle, var(--art-wash), transparent 72%); opacity: .9; }
|
|
31
|
+
.art-tile { position: relative; display: grid; place-items: center; width: 59px; height: 59px; color: var(--art-ink); background: var(--surface); border: 1px solid var(--line); border-radius: 18px; box-shadow: 0 4px 8px var(--shadow), 0 14px 28px var(--shadow); transform: rotate(-9deg); animation: settle-tile 650ms cubic-bezier(.2,.75,.2,1) both; }
|
|
32
|
+
.art-tile .icon { width: 29px; height: 29px; }
|
|
33
|
+
.scene-art.welcome { width: 110px; height: 97px; margin-bottom: 26px; }
|
|
34
|
+
.welcome .art-tile { transform: translate(-11px, 0) rotate(-12deg); width: 62px; height: 62px; }
|
|
35
|
+
.art-small { position: absolute; bottom: 4px; right: 4px; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 13px; background: var(--wash); color: var(--accent); border: 1px solid var(--line); transform: rotate(10deg); animation: arrive-small 750ms cubic-bezier(.2,.75,.2,1) both; }
|
|
36
|
+
.art-small .icon { width: 22px; height: 22px; }
|
|
37
|
+
.art-spark { position: absolute; width: 5px; height: 5px; background: var(--accent); border-radius: 50%; top: 12px; right: 4px; opacity: .5; animation: little-spark 1s ease-out both; }
|
|
38
|
+
.project-list { display: flex; flex-direction: column; gap: 11px; margin-top: 38px; }
|
|
39
|
+
.project-entry { display: flex; align-items: center; padding: 21px 21px; gap: 16px; border: 1px solid var(--line); background: var(--surface); border-radius: 16px; transition: transform 230ms cubic-bezier(.2,.75,.2,1), background-color 180ms, border-color 180ms, box-shadow 230ms; animation: arrive-row 450ms ease-out calc(var(--order) * 65ms) both; }
|
|
40
|
+
.project-entry:hover { transform: translateY(-3px); background: var(--hover); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); box-shadow: 0 10px 20px var(--shadow); }
|
|
41
|
+
.project-icon { display: inline-grid; place-items: center; width: 43px; height: 43px; border-radius: 13px; background: var(--wash); color: var(--accent); flex-shrink: 0; }
|
|
42
|
+
.project-icon .icon { width: 22px; height: 22px; }
|
|
43
|
+
.blue { --art-wash: #e7edf5; --art-ink: #6682a0; }
|
|
44
|
+
.sand { --art-wash: #f1e9db; --art-ink: #a78a64; }
|
|
45
|
+
.project-icon.blue { color: #6682a0; background: #eaf0f6; }
|
|
46
|
+
.project-icon.sand { color: #a78a64; background: #f4eee3; }
|
|
47
|
+
body[data-theme="night"] .project-icon.blue { color: #a6bdcf; background: #293a41; }
|
|
48
|
+
body[data-theme="night"] .project-icon.sand { color: #cfbc9b; background: #3c372b; }
|
|
49
|
+
.project-copy, .agent-copy { min-width: 0; flex: 1; }
|
|
50
|
+
.project-copy strong { display: block; font-weight: 500; font-size: 17px; letter-spacing: -.4px; overflow-wrap: anywhere; }
|
|
51
|
+
.project-copy > span { display: block; font-size: 11px; color: var(--muted); margin-top: 7px; line-height: 1.5; }
|
|
52
|
+
.entry-arrow { display: inline-flex; color: var(--muted); opacity: .5; transition: transform 220ms, opacity 220ms; }
|
|
53
|
+
.entry-arrow .icon { width: 17px; height: 17px; }
|
|
54
|
+
.project-entry:hover .entry-arrow { transform: translateX(3px); opacity: 1; color: var(--accent); }
|
|
55
|
+
.home-actions, .project-actions { display: flex; align-items: center; justify-content: center; gap: 24px; margin-top: 29px; }
|
|
56
|
+
.button { display: inline-flex; align-items: center; justify-content: center; gap: 9px; padding: 13px 21px; min-height: 45px; border-radius: 30px; font-size: 12px; letter-spacing: .2px; font-weight: 500; transition: transform 180ms, opacity 180ms, box-shadow 180ms; }
|
|
57
|
+
.button .icon { width: 16px; height: 16px; }
|
|
58
|
+
.button.primary { background: var(--accent); color: var(--on-accent); }
|
|
59
|
+
.button.primary:hover:enabled, a.button.primary:hover { transform: translateY(-2px); box-shadow: 0 6px 15px var(--shadow); }
|
|
60
|
+
.button:active:enabled { transform: scale(.98); }
|
|
61
|
+
.button:disabled { opacity: .28; }
|
|
62
|
+
.quiet-button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: 11px; color: var(--muted); padding: 9px 0; transition: color 150ms; }
|
|
63
|
+
.quiet-button:hover { color: var(--accent); }
|
|
64
|
+
.quiet-button .icon { width: 13px; height: 13px; }
|
|
65
|
+
.demo-footer { padding: 20px 44px 25px; display: flex; justify-content: space-between; gap: 20px; align-items: center; }
|
|
66
|
+
.demo-footer > span { color: var(--muted); font-size: 9px; opacity: .7; }
|
|
67
|
+
.theme-picker { display: flex; gap: 13px; }
|
|
68
|
+
.theme-picker button { display: inline-flex; align-items: center; gap: 5px; font-size: 9px; color: var(--muted); padding: 6px 0; opacity: .55; }
|
|
69
|
+
.theme-picker button[aria-pressed="true"] { color: var(--ink); opacity: 1; }
|
|
70
|
+
.theme-picker button:hover { opacity: 1; }
|
|
71
|
+
.theme-picker i { width: 7px; height: 7px; border-radius: 50%; border: 1px solid #c4cbbd; background: #faf9f6; }
|
|
72
|
+
.theme-picker [data-theme-choice="night"] i { background: #344a3e; border-color: #4c6353; }
|
|
73
|
+
.back-link { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; color: var(--muted); padding: 6px 0; margin: 0 0 24px; }
|
|
74
|
+
.back-link:hover { color: var(--accent); }
|
|
75
|
+
.back-link .icon { width: 14px; height: 14px; }
|
|
76
|
+
.project-scene .scene-art { margin-top: 0; margin-bottom: 18px; }
|
|
77
|
+
.project-scene h1 { font-size: 31px; letter-spacing: -1px; }
|
|
78
|
+
.agent-list { margin-top: 34px; }
|
|
79
|
+
.agent-row { display: flex; align-items: center; gap: 14px; border-bottom: 1px solid var(--line); padding: 22px 4px; animation: arrive-row 400ms ease-out calc(var(--order) * 60ms) both; }
|
|
80
|
+
.agent-row:last-child { border-bottom: 0; }
|
|
81
|
+
.agent-icon { display: inline-grid; place-items: center; color: var(--muted); width: 40px; height: 40px; }
|
|
82
|
+
.agent-icon.owned { border-radius: 12px; background: var(--wash); color: var(--accent); }
|
|
83
|
+
.agent-icon .icon { width: 23px; height: 23px; }
|
|
84
|
+
.agent-copy strong { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 14px; font-weight: 500; }
|
|
85
|
+
.agent-copy > span { display: block; font-size: 10px; color: var(--muted); margin-top: 6px; }
|
|
86
|
+
.mine-tag { font-size: 8px; background: var(--wash); color: var(--accent); padding: 3px 6px; border-radius: 4px; font-weight: 400; }
|
|
87
|
+
.agent-action { display: inline-flex; padding: 10px 0 10px 8px; color: var(--muted); }
|
|
88
|
+
.agent-action .icon { width: 14px; height: 14px; }
|
|
89
|
+
.small-link { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: var(--accent); }
|
|
90
|
+
.small-link .icon { width: 13px; height: 13px; }
|
|
91
|
+
.disclosure { margin-top: 24px; display: grid; grid-template-columns: auto 1fr; gap: 10px 18px; color: var(--muted); padding: 17px 20px; background: var(--wash); border-radius: 10px; font-size: 10px; }
|
|
92
|
+
.disclosure code { font: 10px/1.6 ui-monospace, monospace; overflow-wrap: anywhere; color: var(--ink); }
|
|
93
|
+
/* One task at a time. The surrounding page stays quiet during setup. */
|
|
94
|
+
.setup-scene { max-width: 440px; margin: 0 auto; }
|
|
95
|
+
.setup-scene .back-link { margin-bottom: 28px; }
|
|
96
|
+
.step-progress { position: absolute; right: 0; top: 13px; display: flex; gap: 5px; }
|
|
97
|
+
.step-progress span { height: 3px; width: 19px; background: var(--line); border-radius: 9px; }
|
|
98
|
+
.step-progress span.filled { background: var(--accent); }
|
|
99
|
+
.setup-scene .intro h1 { font-size: 30px; letter-spacing: -1.1px; }
|
|
100
|
+
.setup-scene .intro p { font-size: 12px; }
|
|
101
|
+
.setup-scene .scene-art { margin-bottom: 23px; }
|
|
102
|
+
.step-content { margin-top: 34px; }
|
|
103
|
+
.pick-area { width: 100%; display: flex; align-items: center; flex-direction: column; justify-content: center; gap: 13px; min-height: 173px; padding: 27px 20px; background: var(--surface); border: 1px dashed var(--line); border-radius: 17px; transition: border-color 180ms, background-color 180ms; }
|
|
104
|
+
.pick-area:hover { background: var(--hover); border-color: var(--accent); }
|
|
105
|
+
.pick-area > .icon { width: 28px; height: 28px; color: var(--accent); margin-bottom: 1px; }
|
|
106
|
+
.pick-area strong { font-size: 13px; font-weight: 500; overflow-wrap: anywhere; }
|
|
107
|
+
.pick-area > span:last-child { font-size: 10px; color: var(--muted); line-height: 1.7; }
|
|
108
|
+
.pick-area.selected { background: var(--wash); border-style: solid; border-color: color-mix(in srgb, var(--accent) 20%, var(--line)); }
|
|
109
|
+
.selection-check { display: inline-grid; place-items: center; width: 29px; height: 29px; border-radius: 50%; background: var(--accent); color: var(--on-accent); }
|
|
110
|
+
.selection-check .icon { width: 16px; height: 16px; }
|
|
111
|
+
.step-actions { display: flex; flex-direction: column; align-items: center; margin-top: 30px; gap: 18px; }
|
|
112
|
+
.continue-button { min-width: 158px; flex-direction: row-reverse; }
|
|
113
|
+
.step-count { color: var(--muted); font: 9px ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 2px; opacity: .65; }
|
|
114
|
+
.field { display: flex; flex-direction: column; gap: 9px; font-size: 11px; color: var(--muted); }
|
|
115
|
+
.field + .field, .pick-area + .field { margin-top: 21px; }
|
|
116
|
+
.field input { min-width: 0; width: 100%; height: 47px; border: 1px solid var(--line); background: var(--surface); padding: 13px 15px; border-radius: 10px; color: var(--ink); font-size: 12px; box-shadow: none; }
|
|
117
|
+
.field input::placeholder { color: var(--muted); }
|
|
118
|
+
.help-link { display: block; margin: 16px auto 0; font-size: 10px; color: var(--muted); padding: 5px; }
|
|
119
|
+
.help-link:hover { color: var(--accent); }
|
|
120
|
+
.help-note { font-size: 11px; color: var(--muted); line-height: 1.9; padding: 15px 18px; border-radius: 10px; background: var(--wash); margin-top: 12px; }
|
|
121
|
+
.selected-project { display: flex; align-items: center; gap: 13px; padding: 20px; background: var(--wash); border-radius: 14px; margin-bottom: 24px; }
|
|
122
|
+
.selected-project > div { min-width: 0; }
|
|
123
|
+
.selected-project strong { display: block; font-size: 14px; font-weight: 500; }
|
|
124
|
+
.selected-project div > span { display: block; font: 9px/1.6 ui-monospace, monospace; color: var(--muted); margin-top: 6px; overflow-wrap: anywhere; }
|
|
125
|
+
.selected-project > .selection-check { margin-left: auto; width: 23px; height: 23px; flex-shrink: 0; }
|
|
126
|
+
.selected-project > .selection-check .icon { width: 13px; }
|
|
127
|
+
.binding-illustration { display: flex; align-items: center; justify-content: center; padding: 13px 0 28px; }
|
|
128
|
+
.binding-node { display: grid; place-items: center; width: 54px; height: 54px; border-radius: 17px; background: var(--surface); border: 1px solid var(--line); color: var(--accent); }
|
|
129
|
+
.binding-node .icon { width: 27px; height: 27px; }
|
|
130
|
+
.codex-node { font: 32px/1 sans-serif; }
|
|
131
|
+
.binding-line { display: flex; gap: 8px; padding: 0 20px; }
|
|
132
|
+
.binding-line i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); opacity: .25; animation: connect-dot 1.8s ease-in-out 3 both; }
|
|
133
|
+
.binding-line i:nth-child(2) { animation-delay: .2s; }
|
|
134
|
+
.binding-line i:nth-child(3) { animation-delay: .4s; }
|
|
135
|
+
.binding-caption { text-align: center; font-size: 11px; color: var(--muted); line-height: 1.9; }
|
|
136
|
+
.command-preview { padding: 17px; margin-top: 13px; background: var(--wash); border-radius: 10px; }
|
|
137
|
+
.command-preview code { font: 11px/1.8 ui-monospace, "PingFang SC", monospace; overflow-wrap: anywhere; }
|
|
138
|
+
.success-scene { text-align: center; padding-top: 40px; }
|
|
139
|
+
.success .art-tile { background: var(--accent); color: var(--on-accent); border: 0; border-radius: 50%; transform: none; animation: success-stamp 550ms cubic-bezier(.2,.9,.3,1.2) both; }
|
|
140
|
+
.success-project { display: inline-flex; align-items: center; text-align: left; gap: 13px; margin: 36px auto 32px; padding: 18px 23px; background: var(--wash); border-radius: 15px; max-width: 100%; }
|
|
141
|
+
.success-project > div { min-width: 0; }
|
|
142
|
+
.success-project strong { display: block; font-size: 15px; font-weight: 500; overflow-wrap: anywhere; }
|
|
143
|
+
.success-project div > span { display: block; font-size: 10px; margin-top: 7px; color: var(--muted); }
|
|
144
|
+
.success-scene > .button { display: flex; margin: 0 auto; width: max-content; }
|
|
145
|
+
.success-scene > .quiet-button { display: flex; margin: 15px auto 0; width: max-content; }
|
|
146
|
+
#toast { position: fixed; left: 50%; bottom: 30px; transform: translateX(-50%); width: max-content; max-width: calc(100vw - 32px); color: var(--ink); background: var(--surface); border: 1px solid var(--line); padding: 14px 20px; box-shadow: 0 8px 30px var(--shadow); border-radius: 12px; font-size: 11px; z-index: 3; }
|
|
147
|
+
@keyframes settle-tile { from { opacity: 0; translate: 0 10px; rotate: -8deg; } to { opacity: 1; translate: 0 0; rotate: 0deg; } }
|
|
148
|
+
@keyframes arrive-small { from { opacity: 0; translate: -8px -9px; rotate: -10deg; } to { opacity: 1; translate: 0 0; rotate: 0deg; } }
|
|
149
|
+
@keyframes little-spark { from { opacity: 0; transform: scale(.3); } to { opacity: .5; transform: scale(1); } }
|
|
150
|
+
@keyframes arrive-row { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
151
|
+
@keyframes connect-dot { 0%, 100% { opacity: .25; transform: scale(.8); } 40%, 60% { opacity: 1; transform: scale(1.2); } }
|
|
152
|
+
@keyframes success-stamp { from { opacity: 0; transform: scale(.7) rotate(-15deg); } to { opacity: 1; transform: scale(1) rotate(0); } }
|
|
153
|
+
html[data-page-hidden="true"] *, html[data-page-hidden="true"] *::before, html[data-page-hidden="true"] *::after { animation-play-state: paused !important; }
|
|
154
|
+
@media (min-height: 950px) and (min-width: 700px) { main { padding-top: 80px; } }
|
|
155
|
+
@media (max-width: 600px) {
|
|
156
|
+
.masthead { padding: 24px; }
|
|
157
|
+
.preview-label { font-size: 9px; }
|
|
158
|
+
main { padding: 38px 24px 52px; }
|
|
159
|
+
h1 { font-size: 30px; letter-spacing: -1.2px; }
|
|
160
|
+
.intro > p { margin-top: 12px; font-size: 12px; }
|
|
161
|
+
.scene-art.welcome { margin-bottom: 26px; }
|
|
162
|
+
.project-list { margin-top: 30px; gap: 11px; }
|
|
163
|
+
.project-entry { padding: 20px 16px; gap: 12px; border-radius: 15px; }
|
|
164
|
+
.project-icon { width: 38px; height: 38px; border-radius: 12px; }
|
|
165
|
+
.project-icon .icon { width: 20px; height: 20px; }
|
|
166
|
+
.project-copy strong { font-size: 15px; letter-spacing: -.4px; }
|
|
167
|
+
.project-copy > span { font-size: 10px; margin-top: 6px; }
|
|
168
|
+
.entry-arrow .icon { width: 15px; height: 15px; }
|
|
169
|
+
.home-actions { flex-direction: column; gap: 10px; margin-top: 26px; }
|
|
170
|
+
.button { min-height: 45px; font-size: 12px; padding-left: 23px; padding-right: 23px; }
|
|
171
|
+
.demo-footer { flex-direction: column-reverse; gap: 15px; padding: 8px 24px 24px; }
|
|
172
|
+
.demo-footer > span { font-size: 8px; }
|
|
173
|
+
.theme-picker { gap: 20px; }
|
|
174
|
+
.theme-picker button { font-size: 9px; }
|
|
175
|
+
.back-link { margin-bottom: 24px; }
|
|
176
|
+
.project-scene h1 { font-size: 25px; }
|
|
177
|
+
.project-scene .intro p { font-size: 11px; }
|
|
178
|
+
.agent-list { margin-top: 25px; }
|
|
179
|
+
.agent-row { padding: 20px 0; gap: 10px; }
|
|
180
|
+
.agent-copy strong { font-size: 13px; }
|
|
181
|
+
.project-actions { flex-direction: column; gap: 8px; margin-top: 28px; }
|
|
182
|
+
.disclosure { grid-template-columns: 1fr; gap: 8px; }
|
|
183
|
+
.setup-scene .intro h1 { font-size: 26px; letter-spacing: -.9px; }
|
|
184
|
+
.setup-scene .intro p { font-size: 11px; max-width: 285px; margin-left: auto; margin-right: auto; }
|
|
185
|
+
.setup-scene .back-link { margin-bottom: 24px; }
|
|
186
|
+
.setup-scene .scene-art { margin-bottom: 19px; }
|
|
187
|
+
.step-content { margin-top: 28px; }
|
|
188
|
+
.pick-area { min-height: 165px; border-radius: 14px; }
|
|
189
|
+
.step-actions { margin-top: 25px; }
|
|
190
|
+
.selected-project { padding: 17px 15px; gap: 10px; }
|
|
191
|
+
.selected-project strong { font-size: 13px; }
|
|
192
|
+
.selected-project div > span { font-size: 8px; }
|
|
193
|
+
.success-scene { padding-top: 35px; }
|
|
194
|
+
.success-project { padding: 17px; }
|
|
195
|
+
.success-project strong { font-size: 14px; }
|
|
196
|
+
.success-project div > span { font-size: 9px; }
|
|
197
|
+
}
|
|
198
|
+
@media (max-width: 360px) {
|
|
199
|
+
.masthead { padding: 22px 20px; }
|
|
200
|
+
main { padding: 28px 20px 45px; }
|
|
201
|
+
h1 { font-size: 27px; }
|
|
202
|
+
.project-entry { gap: 9px; padding: 19px 13px; }
|
|
203
|
+
.project-copy strong { font-size: 13px; }
|
|
204
|
+
.project-copy > span { font-size: 9px; }
|
|
205
|
+
.project-icon { width: 34px; height: 36px; border-radius: 10px; }
|
|
206
|
+
.entry-arrow .icon { width: 13px; height: 13px; }
|
|
207
|
+
.setup-scene .intro h1 { font-size: 24px; }
|
|
208
|
+
}
|
|
209
|
+
@media (prefers-reduced-motion: reduce) {
|
|
210
|
+
*, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Live onboarding uses the same quiet layout as the design preview. */
|
|
214
|
+
body { --muted: #6e7d73; }
|
|
215
|
+
body[data-theme="night"] { --muted: #a1b1a7; }
|
|
216
|
+
main { flex-direction: column; justify-content: flex-start; align-items: center; }
|
|
217
|
+
main > section { width: 100%; }
|
|
218
|
+
h1, h2, h3, h4, p { overflow-wrap: anywhere; }
|
|
219
|
+
h2, h3, h4 { font-weight: 500; }
|
|
220
|
+
h2 { font-size: 26px; }
|
|
221
|
+
h3 { font-size: 16px; margin: 26px 0 12px; }
|
|
222
|
+
h4 { margin: 0; font-size: 14px; }
|
|
223
|
+
p { font-size: 12px; line-height: 1.85; }
|
|
224
|
+
.workspace-label { color: var(--muted); font-size: 11px; letter-spacing: .8px; }
|
|
225
|
+
.muted { color: var(--muted); font-size: 11px; }
|
|
226
|
+
#notice { width: 100%; max-width: 536px; padding: 14px 18px; margin: 0 auto 28px; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: var(--wash); font-size: 12px; line-height: 1.8; overflow-wrap: anywhere; }
|
|
227
|
+
button, input, select, textarea { font: inherit; }
|
|
228
|
+
input, select, textarea { min-width: 0; width: 100%; border: 1px solid var(--line); background: var(--surface); padding: 13px 14px; border-radius: 10px; color: var(--ink); font-size: 13px; }
|
|
229
|
+
input::placeholder { color: var(--muted); opacity: .8; }
|
|
230
|
+
input:focus-visible, select:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
|
|
231
|
+
input[type="checkbox"] { width: 16px; height: 16px; padding: 0; flex-shrink: 0; accent-color: var(--accent); }
|
|
232
|
+
input[type="file"] { padding: 16px 14px; border-style: dashed; }
|
|
233
|
+
input::file-selector-button { border: 0; background: var(--wash); color: var(--accent); border-radius: 7px; padding: 9px 12px; margin-right: 12px; font: inherit; cursor: pointer; }
|
|
234
|
+
label { display: flex; flex-direction: column; gap: 9px; font-size: 12px; color: var(--muted); min-width: 0; margin-bottom: 20px; }
|
|
235
|
+
.checkbox { flex-direction: row; align-items: flex-start; line-height: 1.7; }
|
|
236
|
+
fieldset { border: 1px solid var(--line); border-radius: 12px; padding: 18px; min-width: 0; margin: 18px 0; }
|
|
237
|
+
legend { font-size: 12px; padding: 0 7px; color: var(--muted); }
|
|
238
|
+
.row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; }
|
|
239
|
+
.row > label { flex: 1 1 160px; }
|
|
240
|
+
.bot-fields { display: flex; flex-direction: column; }
|
|
241
|
+
.bot-fields label:last-child { margin-bottom: 0; }
|
|
242
|
+
form .muted { margin: 12px 0 18px; }
|
|
243
|
+
button:not([class]), button.secondary, a.secondary { display: inline-flex; align-items: center; justify-content: center; gap: 7px; border: 1px solid var(--line); border-radius: 24px; padding: 10px 16px; font-size: 12px; line-height: 1.5; background: var(--surface); color: var(--accent); margin: 4px 4px 4px 0; }
|
|
244
|
+
form > button[type="submit"]:not([class]) { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
|
|
245
|
+
button:disabled { opacity: .45; cursor: wait; }
|
|
246
|
+
button.danger { font-size: 12px; color: #b06c55; padding: 10px 0; }
|
|
247
|
+
button:hover:enabled { filter: brightness(.98); }
|
|
248
|
+
button:focus-visible, a:focus-visible, summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
|
|
249
|
+
h1:focus { outline: none; }
|
|
250
|
+
form { margin-top: 0; }
|
|
251
|
+
.step-content > details { margin-top: 18px; }
|
|
252
|
+
.step-actions { margin-bottom: 12px; }
|
|
253
|
+
.step-actions .muted { margin: 0; }
|
|
254
|
+
.step-count { font-size: 10px; }
|
|
255
|
+
.form-cancel { display: flex; margin: 16px auto 0; }
|
|
256
|
+
.home-more { text-align: center; margin-top: 28px; }
|
|
257
|
+
.home-more > summary { color: var(--muted); font-size: 10px; }
|
|
258
|
+
.home-more[open] { text-align: left; }
|
|
259
|
+
details { min-width: 0; margin-top: 22px; }
|
|
260
|
+
summary { color: var(--muted); font-size: 11px; cursor: pointer; line-height: 1.8; width: fit-content; }
|
|
261
|
+
summary:hover { color: var(--accent); }
|
|
262
|
+
details[open] > summary { margin-bottom: 18px; }
|
|
263
|
+
details p { color: var(--muted); margin: 12px 0; }
|
|
264
|
+
details details { padding-left: 12px; border-left: 1px solid var(--line); }
|
|
265
|
+
pre { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; font: 12px/1.9 ui-monospace, SFMono-Regular, Menlo, "PingFang SC", monospace; color: var(--ink); background: var(--wash); padding: 18px; border-radius: 12px; max-width: 100%; }
|
|
266
|
+
.repository-path { font: 11px/1.8 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted); overflow-wrap: anywhere; word-break: break-word; }
|
|
267
|
+
.profile-repo { text-align: center; margin: 24px 0 14px; }
|
|
268
|
+
.card { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 16px; margin-top: 12px; border: 1px solid var(--line); border-radius: 12px; min-width: 0; }
|
|
269
|
+
.card > div { min-width: 0; flex: 1; }
|
|
270
|
+
.card > span { font-size: 12px; overflow-wrap: anywhere; }
|
|
271
|
+
.project-card { position: relative; flex-wrap: nowrap; gap: 10px; margin: 0; padding: 21px; background: var(--surface); border-radius: 16px; animation: arrive-row 450ms ease-out calc(var(--order, 0) * 60ms) both; transition: transform 180ms, border-color 180ms; }
|
|
272
|
+
.project-card:hover, .project-card:focus-within { transform: translateY(-2px); border-color: var(--accent); }
|
|
273
|
+
.project-card-info { display: grid; grid-template-columns: 43px minmax(0, 1fr); column-gap: 16px; align-items: center; }
|
|
274
|
+
.project-card-info .project-icon { grid-row: span 2; }
|
|
275
|
+
.project-card-info h3 { margin: 0; font-size: 17px; line-height: 1.5; }
|
|
276
|
+
.project-card-info p { margin-top: 5px; color: var(--muted); font-size: 11px; }
|
|
277
|
+
.project-card > button { font-size: 18px; color: var(--muted); border: 0; margin: 0; padding: 8px; background: none; }
|
|
278
|
+
.project-card > button::after { content: ''; position: absolute; inset: 0; border-radius: 16px; }
|
|
279
|
+
.project-details { margin-top: 30px; }
|
|
280
|
+
.project-details summary { margin-left: auto; margin-right: auto; }
|
|
281
|
+
.robot-card { position: relative; display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; row-gap: 6px; padding: 22px 0; border-bottom: 1px solid var(--line); animation: arrive-row 400ms ease-out calc(var(--order, 0) * 50ms) both; }
|
|
282
|
+
.robot-card::before { content: '⌘'; display: grid; place-items: center; grid-column: 1; grid-row: 1 / 4; height: 40px; color: var(--muted); font-size: 22px; }
|
|
283
|
+
.robot-card.is-mine::before { background: var(--wash); color: var(--accent); border-radius: 12px; }
|
|
284
|
+
.robot-card > * { grid-column: 2; min-width: 0; }
|
|
285
|
+
.robot-card:last-child { border-bottom: 0; }
|
|
286
|
+
.robot-title { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
|
|
287
|
+
.robot-title h4 { overflow-wrap: anywhere; }
|
|
288
|
+
.robot-card p { color: var(--muted); font-size: 11px; }
|
|
289
|
+
.robot-connection { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 5px; }
|
|
290
|
+
.robot-connection > button { font-size: 11px; }
|
|
291
|
+
.badge { font-size: 10px; line-height: 1.5; color: var(--accent); }
|
|
292
|
+
.mine-badge { background: var(--wash); border-radius: 5px; padding: 2px 6px; font-size: 9px; }
|
|
293
|
+
.badge.pending, .warning-text { color: #a47750; }
|
|
294
|
+
.check { display: flex; gap: 16px; align-items: center; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 12px; }
|
|
295
|
+
.setup-steps { list-style: none; padding: 0; color: var(--muted); font-size: 11px; line-height: 2.4; }
|
|
296
|
+
.setup-steps .done { color: var(--accent); }
|
|
297
|
+
.setup-steps .active { color: var(--ink); }
|
|
298
|
+
.next-step { color: var(--muted); text-align: center; margin: 20px 0; font-size: 12px; }
|
|
299
|
+
#profile #binding > p { color: var(--muted); text-align: center; margin-bottom: 16px; }
|
|
300
|
+
#copy-binding { display: flex; margin: 24px auto 0; }
|
|
301
|
+
#binding > details { margin-top: 24px; }
|
|
302
|
+
#profile-art[data-state="success"] .art-tile { border-radius: 50%; color: var(--on-accent); background: var(--accent); transform: none; animation: success-stamp 550ms cubic-bezier(.2,.9,.3,1.2) both; }
|
|
303
|
+
#profile-art[data-state="success"] .art-tile svg { display: none; }
|
|
304
|
+
#profile-art[data-state="success"] .art-tile::after { content: '✓'; font-size: 29px; }
|
|
305
|
+
#profile-art[data-state="waiting"] .art-tile { animation: settle-tile 650ms ease both; }
|
|
306
|
+
#profile > .step-actions:has(> [hidden] + [hidden]) { display: none; }
|
|
307
|
+
#pending-requests { display: flex; margin: 26px auto; }
|
|
308
|
+
#admin-tools { border-top: 1px solid var(--line); padding-top: 22px; }
|
|
309
|
+
#delivery-panel { background: var(--wash); padding: 18px; border-radius: 12px; margin-top: 24px; }
|
|
310
|
+
#invite-info { display: block; }
|
|
311
|
+
#invite-info p { margin: 0; }
|
|
312
|
+
#invite-info p + p { margin-top: 8px; }
|
|
313
|
+
#project-check-status { margin: 12px 0; }
|
|
314
|
+
#verification .binding-caption { margin: 20px 0; }
|
|
315
|
+
#reset-view > p, #reset-view > ul { color: var(--muted); font-size: 12px; line-height: 1.9; }
|
|
316
|
+
#reset-view form, #existing form { margin-top: 30px; }
|
|
317
|
+
@media (max-width: 600px) {
|
|
318
|
+
main { padding-top: 35px; }
|
|
319
|
+
.row { flex-direction: column; gap: 0; }
|
|
320
|
+
.row > label { width: 100%; flex-basis: auto; }
|
|
321
|
+
.project-card { padding: 19px 16px; }
|
|
322
|
+
.project-card-info { grid-template-columns: 38px minmax(0, 1fr); column-gap: 12px; }
|
|
323
|
+
.project-card-info h3 { font-size: 15px; }
|
|
324
|
+
.project-card-info p { font-size: 10px; }
|
|
325
|
+
.project-actions { gap: 10px; }
|
|
326
|
+
.robot-card { column-gap: 10px; }
|
|
327
|
+
input, select, textarea { font-size: 16px; }
|
|
328
|
+
.robot-connection { flex-wrap: wrap; }
|
|
329
|
+
.card { padding: 14px; }
|
|
330
|
+
.demo-footer > span { font-size: 10px; }
|
|
331
|
+
.theme-picker button { font-size: 11px; padding: 10px 0; }
|
|
332
|
+
}
|
|
333
|
+
@media (max-width: 360px) {
|
|
334
|
+
.project-card { padding: 17px 12px; }
|
|
335
|
+
.project-card-info { column-gap: 10px; grid-template-columns: 34px minmax(0, 1fr); }
|
|
336
|
+
.project-card-info h3 { font-size: 13px; }
|
|
337
|
+
}
|
|
@@ -31,6 +31,6 @@ export async function selectProfile({ home = workspaceHome(), selector, cwd = pr
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
if (choices.length === 1) return choices[0];
|
|
34
|
-
if (!choices.length) throw new Error('未找到已接入项目。请先运行 codex-collab 完成接入。');
|
|
34
|
+
if (!choices.length) throw new Error('未找到已接入项目。请先运行 codex-collab setup 完成接入。');
|
|
35
35
|
throw new Error(`找到多个接入,请使用 --profile <项目ID> 选择:\n${choices.map((state) => `${state.id} ${state.agent_id} ${state.repo}`).join('\n')}`);
|
|
36
36
|
}
|
package/docs/onboarding-audit.md
CHANGED
|
@@ -126,3 +126,12 @@ Skill 校验通过。`npm pack --dry-run` 确认发布包包含 `guided.mjs`、`
|
|
|
126
126
|
持续动画仅有两处背景光晕位移与就绪状态透明度变化;在动画稳定后的 1.8 秒 Chrome Performance 采样中,新增 LayoutCount、RecalcStyleCount 和 ScriptDuration 均为 0。此记录反映本机隔离示例,不代表所有设备上的帧率。一次性入场动画完成后不保留最终变换。系统减少动态效果设置能关闭全部动画;页面隐藏信号能暂停动画,后台项目轮询不发出同步请求。
|
|
127
127
|
|
|
128
128
|
npm tarball 在独立目录安装后,命令入口、带会话鉴权的 API、新项目读取路由和静态页面资源检查通过。包包含 77 个文件,含新增项目聚合模块,不包含测试目录、本机凭据、运行日志或截图。此轮验证未连接真实企业微信群、修改个人业务 clone 或建立 Codex 自动化;任务协议与既有操作授权保持原有行为。
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## 2026-10-24 · 0.9.0 轻引导与安装提示
|
|
132
|
+
|
|
133
|
+
正式向导采用单列居中的分步流程:首页按项目展示,项目中统一列出机器人并标记“我的”;接入项目、接受邀请和添加本人机器人均按步骤收集必要信息。远程、分支、验证命令、团队管理、诊断和重置按需展开。上一步保留输入;项目存在歧义或缺少验证命令时要求确认;完成页只依据实际对话绑定和轮询记录更新,复制指令不会视为接入完成。配色、原生与 CSS 动画支持减少动态效果偏好和后台暂停。
|
|
134
|
+
|
|
135
|
+
完整自动测试通过 215 项,0 失败。浏览器使用真实页面资源和隔离示例服务,检查管理员接入、成员邀请、添加本人机器人、返回保留输入、真实状态驱动的群验证和绑定阶段、归属标记、管理入口,以及切换项目时清理旧状态。320、390、768、1024、1440 像素宽度、三种配色、减少动态效果和动画结束状态检查通过,未出现脚本、控制台或资源错误。此轮未连接真实企业微信群或建立真实 Codex 自动化,不构成跨机器联合验收。
|
|
136
|
+
|
|
137
|
+
npm 包新增被动安装提示,引导执行 `codex-collab setup`;不会在安装期间自动启动服务或打开浏览器。npm 默认可能隐藏生命周期脚本输出,因此文档推荐使用 `npm install --global --foreground-scripts xuym-codex-collab` 并明确列出 setup 命令。安装脚本和全部向导资源已打包;独立临时目录实际安装及 CLI 入口检查通过。设计演示源码保留在 `design-demos/onboarding/`,演示和本机截图不进入 npm 包。
|
package/docs/onboarding.md
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
1. 安装 Node.js 20+、Git 和支持对话 heartbeat 的 Codex 桌面应用。
|
|
8
8
|
2. 确认业务仓库至少有一个远程业务分支(如 `main`、`master`、`develop`),本机 Git 凭据能读取并 push `agent-collab` 及任务代码分支。已有独立 clone 可以直接使用;没有 clone 时让向导从 Git 地址拉取。
|
|
9
|
-
3.
|
|
9
|
+
3. 打开终端执行。已有项目时可先进入项目目录,让向导自动带入信息;没有本机 clone 时也可直接启动:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install --global xuym-codex-collab
|
|
13
|
-
codex-collab
|
|
12
|
+
npm install --global --foreground-scripts xuym-codex-collab
|
|
13
|
+
codex-collab setup
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
安装完成后会提示运行 `codex-collab setup`;`--foreground-scripts` 用于显示 npm 默认可能隐藏的安装脚本输出。使用 `--ignore-scripts` 或没有看到提示时,仍可直接运行该命令。安装过程只显示提示,运行 `setup` 后网页自动打开;若未打开,执行 `codex-collab setup --no-open`,复制终端打印的本机链接。工作台已在后台运行,可以关闭终端和浏览器。macOS 默认设置登录自启,Linux 尝试设置 systemd 用户服务;未配置成功时页面和终端会明确提示。手动停止的连接不会在登录或后台检查时重新启动。团队成员无需 clone 工具仓库。也可执行 `npx xuym-codex-collab@latest setup` 临时打开向导;长期运行推荐全局安装,以便登录服务使用稳定安装路径。
|
|
17
17
|
|
|
18
18
|
同一台电脑模拟两位成员时,使用同一业务仓库的两个独立 clone、两个机器人、两个 Codex 对话;同一个 clone 只能接入一个身份。同一个企业微信账号可以拥有多个 Agent,每个 Agent 的机器人、签名身份、clone 和对话独立。真正同事使用自己的企业微信账号和 Git 凭据。
|
|
19
19
|
|
|
@@ -23,19 +23,19 @@ codex-collab
|
|
|
23
23
|
|
|
24
24
|
打开项目后只有一份“项目机器人”列表,包含自己的和同事的机器人。自己的标记“我的”;标记依据本机签名身份与团队已验证的所有者关系,同一已验证账号的其他机器人也会标记。本机没有接入的机器人会明确提示;同事的机器人展示角色和职责,不推测远端机器是否在线。
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
本机已接入的机器人显示实际连接状态,点击“管理机器人”或“继续接入”打开原接入详情,随后可“返回项目”。项目中的“团队与邀请”和“添加我的机器人”对已验证且就绪的本机管理员显示。普通成员拥有多个机器人时继续通过管理员分配的独立接入包接入。
|
|
27
27
|
|
|
28
28
|
首页读取本机接入记录;项目页先显示本机签名校验通过的团队记录,再同步远程账本。同步失败保留已验证记录并提示重试。归属标签只用于展示,操作仍检查对应身份的既有权限。
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
页面采用居中、逐步接入的布局,每屏只处理一个动作;项目、机器人、群验证和对话绑定之间有轻量过渡,不加载外部字体或动画库。页脚可切换纸白、雾绿与夜色。动画使用 `transform` 和 `opacity`;页面进入后台时暂停动画与项目自动同步请求,系统开启“减少动态效果”时关闭动画与过渡。
|
|
31
31
|
|
|
32
32
|
## 管理员操作
|
|
33
33
|
|
|
34
34
|
1. 在企业微信创建独立智能机器人,获取 Bot ID 和 Secret,拉进协作群。为每位成员分别创建机器人并加入同一个群;真人同事也加入群。
|
|
35
|
-
2.
|
|
36
|
-
3.
|
|
35
|
+
2. 选择“接入一个项目”。当前目录属于 Git 项目时会自动带入项目根目录,并带入本机用户名。确认项目,或选择 Git 地址拉取新目录(目录可留空自动生成),点击“继续”。向导会检查项目并推荐验证命令;需要修改时展开“分支与验证方式”,例如 `npm test`、`go test ./...` 或 `sh test.sh`。未识别到验证命令时会展开选项,要求填写后再继续。工具自动识别协作远程与远程默认分支;多个不同远程或默认分支不明时,页面要求选择一次,也可主动选择其他基准分支。检查只读取常见测试入口,不执行项目脚本;实际任务使用确认后的固定程序与参数,不支持管道或命令拼接。
|
|
36
|
+
3. 输入自己的 Bot ID/Secret,点击“连接机器人”。显示名称与主要职责在折叠选项中调整;名称可以是 `Alice` 或“张三”,内部 Agent ID 自动生成,也可自定义身份和标签。
|
|
37
37
|
4. 用自己的企业微信账号 @ 此机器人,发送页面显示的 `协作 接入 六位数字`。页面自动发现群 `chatid` 与本人 `userid`,创建身份、签名账本,配置项目 MCP/Skill 并启动本机机器人 Runner;无需再点击继续。群验证中刷新页面可以恢复进度。
|
|
38
|
-
5.
|
|
38
|
+
5. 从项目页点击“团队与邀请”,找到“批量分配机器人给同事”。每行填写显示名称、选择职责、填写独立机器人的 Bot ID/Secret,点击“增加一位成员/机器人”添加更多行。默认设为该职责的首选执行者并允许所有者群命令;候补与自定义 ID/职责在折叠选项中调整。一次最多 25 行。
|
|
39
39
|
6. 点击“生成全部接入包”。密码自动生成;在“已分配的机器人”逐个下载加密 JSON 文件、查看并复制接入说明。把文件和说明交给指定成员,密码通过另一条可信渠道单独发送。说明不包含密码或 Secret。包默认 7 天有效,同一成员或机器人不会同时分发多个有效邀请;重复 ID/Bot 的批次会在发布前拒绝。
|
|
40
40
|
7. 成员群验证后,“待确认的成员”自动出现申请。核对内部 Agent ID、职责和 userid,明确点击“确认此成员入队”。成员页面自动等待批准并继续配置;批准不会由向导替你做。新的签名策略通过 Git 同步到其他在线成员。
|
|
41
41
|
8. 管理员也按下文把自己的 Codex 对话启用。需要调整审核人时,展开“团队分工、审核与通知设置”,默认阶段审核由执行 Agent 的本人处理;可选管理员或已验证身份的同事。
|
|
@@ -48,7 +48,7 @@ codex-collab
|
|
|
48
48
|
|
|
49
49
|
远程别名属于各自的本机配置:你的 clone 可以叫 `origin`,同事可以叫 `upstream`。成员接入时按邀请中的仓库地址匹配远程,不需要改别名;如果另有个人 fork,不会误选它。团队基准分支写进管理员签名的策略,成员和新增机器人自动继承。每个机器人继续使用独立 clone 和 Codex 对话。
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
管理员在项目页点击“团队与邀请”,再展开“团队分工、审核与通知设置”,点击“读取并调整基准分支”即可切换到已有远程业务分支。修改通过签名版本链同步,只对之后创建的任务生效。已有任务保留原基准分支、创建时的完整 commit SHA、分工与审核规则。修改与其他管理员操作冲突时,重新读取后再保存。
|
|
52
52
|
|
|
53
53
|
新任务在创建时从团队远程基准分支固定起始 SHA。排队期间分支继续提交,首次领取和失败后的候补仍从这个 SHA 开始;阶段接力从上一阶段已验证的精确提交继续。创建快照使用私有账本 clone,不改变业务工作区、当前分支或它的 `FETCH_HEAD`。如果远程基准分支被删除、强制改写为不包含起始 SHA 的历史,或无法读取所需提交,任务会报错;不会自动换成最新代码。应先恢复可读历史,或明确终止旧任务并创建新任务。
|
|
54
54
|
|
|
@@ -62,7 +62,7 @@ codex-collab
|
|
|
62
62
|
2. 在管理员项目的“已分配的机器人”中,打开对应成员的“查看接入说明与密码”。如果显示密码缺失,点击“重新生成接入包与密码”。
|
|
63
63
|
3. 页面会预填原 Bot ID;管理员在本机输入该机器人的 Secret。工具保留原 Agent 与职责,生成新加密文件和新密码,并在 Git 签名版本链中撤销旧邀请。Secret 不会发到聊天或写入 Git。
|
|
64
64
|
4. 通过可信渠道分别交给成员新接入包和新密码。旧文件以及基于旧包创建、尚未批准的申请都不能再使用。
|
|
65
|
-
5.
|
|
65
|
+
5. 成员在“接受同事的邀请”选择 Bob 原来的本机 clone,上传新包并输入新密码,选中文件并填完密码后点击“继续”,核对下一屏展示的接入信息和项目目录后再接入。工具会在确认签名替换关系后复用该 clone 的本地身份记录,清除旧申请并要求重新验证群身份;管理员随后确认新申请。
|
|
66
66
|
|
|
67
67
|
该恢复入口仅用于未批准的普通成员邀请。已获批准的成员不能重签,应继续使用已有本机配置;管理员自己的机器人也不使用分发包恢复流程。若 Git 发布中断,半成品不会显示为可下载包;回到原邀请重试生成即可复用同一恢复记录。
|
|
68
68
|
|
|
@@ -74,8 +74,8 @@ codex-collab
|
|
|
74
74
|
|
|
75
75
|
## 成员操作
|
|
76
76
|
|
|
77
|
-
1. 从管理员取得自己的加密接入包、接入说明和单独发送的密码,打开 `codex-collab setup` 或 `npx xuym-codex-collab@latest setup
|
|
78
|
-
2.
|
|
77
|
+
1. 从管理员取得自己的加密接入包、接入说明和单独发送的密码,打开 `codex-collab setup` 或 `npx xuym-codex-collab@latest setup`,选择“接受同事的邀请”。
|
|
78
|
+
2. 选择接入包文件、输入密码,点击“继续”。下一屏会展示团队、Agent、职责、仓库和建议目录;默认“帮我拉取到新目录”,可修改保存路径,也可切换“使用本机已有项目”。确认后点击“接入项目”。工具先验证接入包再 clone,使用本机 Git 登录;已有项目必须属于包内同一 remote,支持同一仓库的 SSH/HTTPS 表达。
|
|
79
79
|
3. 用**自己的企业微信账号** @ 分配给你的机器人,发送页面验证码。页面自动生成签名身份,把带公钥的入队申请写进协作分支,并进入等待批准;无需返回点击确认。刷新页面可以恢复当前验证或申请进度。
|
|
80
80
|
4. 管理员明确批准后,页面自动检查 Git 权限、写入项目本地 MCP 和 Skill、启动机器人连接。正常流程无需点击“继续接入”;Git/配置异常时会停在可恢复的步骤,处理后再明确重试。
|
|
81
81
|
5. 在 Codex 打开页面上的业务项目,信任项目并加载 MCP/Skill。点击“复制启用指令”,粘贴到要代表你的**已有对话**,例如:
|
|
@@ -84,7 +84,7 @@ codex-collab
|
|
|
84
84
|
使用 $team-collab-desktop,启用当前项目的团队协作,将 bob 机器人绑定到当前对话。项目:项目绝对路径
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
6. Skill 完成身份核对、绑定真实 thread ID、复用或创建该对话的 heartbeat
|
|
87
|
+
6. Skill 完成身份核对、绑定真实 thread ID、复用或创建该对话的 heartbeat,并立即做一次轮询。工作台自动更新状态;展开“查看连接详情”确认机器人认证、对话绑定和实际轮询。
|
|
88
88
|
|
|
89
89
|
启用指令不是 Secret。成员无需手工编辑 JSON、生成密钥或复制 userid;无法识别 Skill 时可展开详细指令作为备用。Codex 若没有暴露真实对话 ID,仍需本人提供该对话 ID/链接;工具不会猜测或访问应用私有数据库。若应用不支持 heartbeat,Skill 会明确说明尚未启用自动轮询,不能仅凭已绑定就认定能接单。
|
|
90
90
|
|
|
@@ -95,7 +95,7 @@ codex-collab
|
|
|
95
95
|
现有通过私有 `peer.json` 运行的项目无需重新生成身份或重绑对话。
|
|
96
96
|
|
|
97
97
|
1. 用原配置停止该机器人的 Runner:`codex-collab stop /absolute/path/to/private-peer.json`。有正在执行的任务时先处理其租约/执行状态。
|
|
98
|
-
2.
|
|
98
|
+
2. 在网页首页展开“其他接入方式”,选择“导入已有配置”,填写原私有配置的完整路径。**旧团队由管理员先导入,然后其他成员分别导入**。
|
|
99
99
|
3. 工具从原策略建立签名版本根,保留原身份、私有数据目录、Codex 对话绑定和任务,再通过原配置路径重启 Runner。
|
|
100
100
|
4. 向导刷新可识别的项目 MCP 和 Skill;重新加载 MCP,再把页面的新启用指令发送到原绑定对话,更新原 heartbeat 的提示词。以后统一在工作台查看状态、添加新成员。
|
|
101
101
|
5. 原 v2 团队不会仅因导入就改变接力行为。所有成员更新工具并重启机器人和 MCP 后,管理员在“真人审核与通知”保存规则,发布 v3 策略。此后创建的新任务应用新规则;正在执行的旧任务继续遵循原策略。
|
|
@@ -138,8 +138,8 @@ codex-collab
|
|
|
138
138
|
准备同一业务仓库的两个独立 clone、两个企业微信机器人和两个 Codex 对话。管理员给自己增加 Agent 可以直接在同一工作台完成:
|
|
139
139
|
|
|
140
140
|
1. 以 Alice 初始化团队,完成群验证并进入管理员项目。已有团队可直接打开已就绪的管理员项目。
|
|
141
|
-
2.
|
|
142
|
-
3. 保留“首选执行者”时,Bob 成为 backend 首选;Alice 若也有 backend
|
|
141
|
+
2. 在项目页点击“添加我的机器人”(或“团队与邀请”中的“给自己增加机器人”),确认独立项目目录并填写新 Agent 名称 `bob`、职责 `backend`,点击“继续”,再填写新机器人的 Bot ID/Secret。
|
|
142
|
+
3. 保留“首选执行者”时,Bob 成为 backend 首选;Alice 若也有 backend 能力则是候补。点击“连接机器人”。无需包密码或下载接入包。
|
|
143
143
|
4. 用初始化 Alice 时的**同一个企业微信账号** @Bob,发送页面验证码,页面自动继续。工具校验本人身份,自动签名批准新 Agent、配置 Bob 项目的 MCP/Skill 并启动连接。Bob 仍是 member,不会继承 Alice 的管理员角色。
|
|
144
144
|
5. 在 Alice clone 和 Bob clone 中分别打开要绑定的已有 Codex 对话,向各自对话粘贴该项目的“启用指令”。每个 Agent 各自创建 heartbeat,确认身份与最近轮询。
|
|
145
145
|
6. 在群里 @Alice 创建包含两种职责的任务,例如 `[frontend>backend]`。默认 Alice 阶段提交后你 @Alice 审核,Bob 阶段提交后你 @Bob 审核,最后 @Alice 完成任务。以每次通知指定的审核身份和版本号为准。
|
|
@@ -182,7 +182,7 @@ Secret 若曾发到聊天或 Git,应在企业微信重新生成后更新本机
|
|
|
182
182
|
|
|
183
183
|
## 管理、重绑与移除本机接入
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
从首页打开项目,再打开自己的机器人,展开“查看连接详情 → 管理与重置”。所有操作先预览当前 Agent、clone、对话 ID 和影响,再输入当前 Agent 名称确认。重新绑定或移除时先在原对话暂停协作 heartbeat;网页无法控制 Codex 应用自动化,也不会删除聊天。
|
|
186
186
|
|
|
187
187
|
**重新绑定对话**保留成员私钥和机器人配置,停止 Runner 并清除本机对话绑定及轮询观察状态。复制项目页面的启用指令到目标对话,完成绑定后启动连接。旧对话的轮询因绑定失效无法再领取任务。
|
|
188
188
|
|
|
@@ -198,9 +198,9 @@ Secret 若曾发到聊天或 Git,应在企业微信重新生成后更新本机
|
|
|
198
198
|
|
|
199
199
|
## 0.5.0 后台连接与排查
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
首次使用推荐 `codex-collab setup`;直接运行 `codex-collab` 也会打开同一个向导。首次在项目目录运行会带入项目路径与本机显示名称。团队名称、内部身份与职责标签收在更多设置中,仍需确认适合项目的验证命令。
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
邀请文件和密码填好后点击“继续”,下一屏展示成员、职责与项目。默认拉取到推荐目录;可以留空目录直接接入,也可以选择已有独立 clone。给自己增加机器人同样支持自动拉取独立目录。
|
|
204
204
|
|
|
205
205
|
后台工作台与浏览器生命周期独立。macOS 使用 LaunchAgent;Linux 使用 systemd 用户服务。服务保留启动时的 Node 路径和 PATH,升级或更换 Node 安装位置后可运行 `codex-collab autostart on` 更新。自启注册失败会显示说明,当前会话仍尝试使用独立后台进程。Windows 暂时只支持独立后台进程。
|
|
206
206
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 0.10.0:让 Codex 组队工作
|
|
2
|
+
|
|
3
|
+
将已确认的星尘设计接入正式本机向导。首页说明两种协作方式:在企业微信群里连接自己的多个 Codex 会话,或与同事的 Codex 会话按角色分工、接力完成任务。
|
|
4
|
+
|
|
5
|
+
- 首页标题更新为“让 Codex 组队工作。”,桌面与移动端统一使用紧凑 Logo。
|
|
6
|
+
- 配色保留纸白、夜色;旧的雾绿选择自动回落到纸白。
|
|
7
|
+
- 增加 Three.js 星尘背景、轻微鼠标视差、星点牵引与短尾迹,移除鼠标光晕、手动停用按钮和背景说明文案。
|
|
8
|
+
- Three.js 固定版本,模块由本机向导提供,无需 CDN 或额外配置。背景不拦截点击,保留系统鼠标。
|
|
9
|
+
- 触屏与系统减少动态效果设置下使用静态星点,不创建 WebGL 上下文。无 WebGL 或上下文丢失时自动降级;页面隐藏时暂停动画。星点与尾迹各一次绘制,动画约 30 帧,像素比最多 1.5,画布最长边最多 2048 像素。
|
|
10
|
+
|
|
11
|
+
## 升级
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install --global xuym-codex-collab@0.10.0
|
|
15
|
+
codex-collab setup
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
已有项目配置和协作记录无需迁移。升级后重启已运行的本机工作台进程,再打开向导,才能加载新代码;已有机器人连接按原有配置使用。
|
|
19
|
+
|
|
20
|
+
本次通过 216 项自动化测试,并在浏览器验证正式页面及临时目录安装后的 npm 包:项目归属、主题切换保留表单、320–3840 像素布局、后台暂停与恢复、触屏与减少动态效果、WebGL 降级与恢复均通过;安装后的 CLI 能启动独立工作台并提供完整背景资源。不新增真实企业微信群或跨机器验收结论。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xuym-codex-collab",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Git-backed collaboration tools for Codex teams, with MCP, WeCom, and local runners.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"node": ">=20"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
|
+
"postinstall": "node bin/postinstall.mjs",
|
|
41
42
|
"test": "node --test packages/protocol/test/*.test.mjs packages/git-store/test/*.test.mjs packages/peer/test/*.test.mjs apps/server/test/*.test.mjs apps/peer/test/*.test.mjs apps/onboarding/test/*.test.mjs scripts/peer/test/*.test.mjs tests/e2e/*.test.mjs",
|
|
42
43
|
"server": "node apps/server/main.mjs",
|
|
43
44
|
"runner": "node apps/runner/main.mjs",
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"@modelcontextprotocol/server": "2.3.1",
|
|
57
58
|
"@openai/codex-sdk": "0.161.0",
|
|
58
59
|
"@wecom/aibot-node-sdk": "1.0.7",
|
|
60
|
+
"three": "0.186.1",
|
|
59
61
|
"zod": "^4.6.5"
|
|
60
62
|
}
|
|
61
63
|
}
|