xuym-codex-collab 0.7.0 → 0.9.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.
@@ -1,39 +1,673 @@
1
- <!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Codex Collab · 团队接入</title><link rel="stylesheet" href="/style.css"></head><body>
2
- <div class="ambient" aria-hidden="true"><i></i><i></i></div><header><a class="brand" href="/" data-view="home" aria-label="Codex Collab 首页"><span class="brand-mark" aria-hidden="true">C</span>Codex Collab</a><span class="workspace-label"><span class="status-dot" aria-hidden="true"></span>本机协作工作台</span></header>
3
- <main><div class="hero"><p class="eyebrow">YOUR TEAM, IN SYNC</p><h1>一个项目,<span>一支协作队伍。</span></h1><p class="intro">连接群机器人与 Codex 对话,让任务在团队中有序接力。</p></div><div id="notice" role="status" hidden></div>
4
- <nav><button data-view="home">我的项目</button><button data-view="admin">连接我的机器人</button><button data-view="join">接受同事邀请</button><button data-view="existing">导入已有配置</button></nav>
5
- <section id="home"><div class="entry-options"><button data-view="admin">连接我的机器人<small>首次接入,或为团队建立协作项目</small></button><button data-view="join">接受同事邀请<small>已有接入包,自动带入机器人和项目信息</small></button></div><p id="startup-status" class="muted"></p><div class="section-heading"><div><p class="eyebrow">PROJECTS</p><h2>我的项目</h2></div><span class="muted" id="project-count"></span></div><div id="profiles" class="project-grid"></div><details id="removed-projects" hidden><summary>已移除的接入</summary><p class="muted">本机身份与恢复记录保留。恢复前请确保原 clone 未绑定其他身份。</p><div id="removed-profiles"></div></details></section>
6
- <section id="project" hidden><button id="project-back" class="back-button secondary">← 我的项目</button><div class="section-heading"><div><p class="eyebrow">PROJECT WORKSPACE</p><h2 id="project-title"></h2></div><button id="project-refresh" class="secondary">刷新项目</button></div><p id="project-repository" class="repository-path"></p><div id="project-summary" class="project-summary"></div><p id="project-sync" class="muted" role="status"></p><div class="section-heading robot-heading"><h3>项目机器人</h3><div class="manage-actions"><button id="project-add-own" hidden>添加我的机器人</button><button id="project-settings" class="secondary" hidden>团队管理</button></div></div><div id="project-agents" class="robot-grid"></div></section>
7
- <section id="admin" hidden><h2>连接我的机器人</h2><p>先在企业微信创建智能机器人并加入协作群。这里会通过群验证码自动获取群和你的 userid。</p>
8
- <form id="admin-form">
9
- <fieldset><legend>选择业务项目</legend><label>项目来源<select id="admin-repo-mode" name="repo_mode"><option value="existing">使用本机已有项目</option><option value="clone">从 Git 地址拉取新项目</option></select></label>
10
- <label id="admin-existing-repo">项目目录<input name="repo" id="admin-repo" placeholder="Git 仓库根目录的完整路径"></label>
11
- <div id="admin-clone-repo" hidden><label>Git 仓库地址<input name="remote" id="admin-remote" placeholder="HTTPS 或 SSH 地址,不含 Token"></label><label>保存到新目录(可选)<input name="destination" id="admin-destination" placeholder="留空按项目与名称生成独立目录"></label></div>
12
- <button id="check-project" type="button" class="secondary">检查项目并推荐验证命令</button><p id="project-recommendation" class="muted">使用本机已有的 Git 登录,自动识别远程仓库和默认分支;无法确定时只需选择一次。</p>
13
- <div id="repository-options" hidden><label>协作远程<select name="remote_name" id="admin-remote-name"><option value="">自动识别</option></select></label><label>业务基准分支<select name="base_branch" id="admin-base-branch"><option value="">使用远程默认分支</option></select></label><p class="muted">同事和新增机器人会继承这个基准分支。每个新任务固定起始提交,后续分支更新不会改变已有任务。</p></div>
14
- <label>验证命令<input id="test-command" name="test_command" required placeholder="例如 npm test、go test ./...、sh test.sh"></label><p class="muted">请确认这个命令适合项目。工具使用固定程序和参数执行,不运行管道或拼接命令。</p></fieldset>
15
- <div class="row"><label>你的显示名称<input name="display_name" required placeholder="例如 Alice 或张三" maxlength="80"></label><label>主要职责<select name="responsibility"><option value="fullstack">全栈开发</option><option value="frontend">前端开发</option><option value="backend">后端开发</option><option value="testing">测试</option><option value="docs">文档</option><option value="general">通用开发</option></select></label></div>
16
- <details><summary>更多设置:团队名称、内部身份与职责</summary><label>团队名称(可选)<input name="team_name" placeholder="留空使用项目名称" maxlength="80"></label><label>内部 Agent ID(可选)<input name="agent_id" pattern="[a-zA-Z0-9_-]{1,64}" placeholder="留空自动生成"></label><label>自定义职责标签(可选)<input name="capabilities" placeholder="英文标签,以逗号分隔"></label></details>
17
- <div class="row"><label>你的机器人 Bot ID<input name="bot_id" required autocomplete="off"></label><label>机器人 Secret<input name="secret" type="password" required autocomplete="off"></label></div>
18
- <button type="submit">连接并进入群验证</button></form></section>
19
- <section id="own" hidden><h2>给自己增加机器人</h2><p>同一个企业微信账号可以拥有多个 Agent。每个 Agent 使用独立机器人、独立 clone 和独立 Codex 对话。验证后自动完成本机接入,无需下载接入包。</p>
20
- <form id="own-form"><label>准备项目<select id="own-repo-mode" name="repo_mode"><option value="clone">自动拉取独立项目</option><option value="existing">使用已有的独立 clone</option></select></label><label id="own-clone-repo">新项目目录(可选)<input name="destination" placeholder="留空按项目和 Agent 名称创建"></label><label id="own-existing-repo" hidden>另一个 clone 的本机目录<input name="repo" placeholder="同一业务仓库的另一个独立 clone"></label><div class="row"><label>新的 Agent 名称<input name="agent_id" required pattern="[a-zA-Z0-9_-]{1,64}" placeholder="bob"></label><label>职责标签<input name="capabilities" required placeholder="backend"></label></div><div class="row"><label>新机器人 Bot ID<input name="bot_id" required autocomplete="off"></label><label>新机器人 Secret<input name="secret" type="password" required autocomplete="off"></label></div><label class="checkbox"><input name="prefer" type="checkbox" checked>该 Agent 为这些职责的首选执行者</label><button type="submit">连接我的新机器人</button><button id="own-cancel" type="button" class="secondary">返回原项目</button></form></section>
21
- <section id="join" hidden><h2>接受同事邀请</h2><p>导入管理员提供的加密接入包。机器人、职责和仓库信息会自动带入,密码请向管理员单独获取。</p>
22
- <form id="join-form"><label>接入包文件<input name="file" id="invite-file" type="file" accept=".json" required></label><label>接入包密码<input name="password" id="invite-password" type="password" required autocomplete="off"></label>
23
- <button id="inspect-invite" type="button" class="secondary">重新读取接入信息</button><div id="invite-info" hidden><p id="invite-summary"></p><p id="invite-remote" class="muted"></p></div>
24
- <label>准备项目<select id="join-repo-mode" name="repo_mode"><option value="clone">帮我拉取到新目录</option><option value="existing">使用本机已有项目</option></select></label>
25
- <label id="join-clone-repo">新项目目录<input name="destination" placeholder="留空使用推荐目录,亦可填写完整路径"></label>
26
- <label id="join-existing-repo" hidden>已有项目目录<input name="repo" placeholder="Git 仓库根目录的完整路径"></label>
27
- <button type="submit">接入我的机器人</button><p class="muted">工具使用本机 Git 登录拉取代码,不会改写已有目录。导入后请按提示在群里确认一次身份,审批和配置会自动继续。</p></form></section>
28
- <section id="existing" hidden><h2>导入已有协作项目</h2><p>先停止原 Runner。导入会保留原成员身份、任务和对话绑定,并重新启动机器人。旧团队由管理员先导入。</p><form id="existing-form"><label>已有私有 peer.json 路径<input name="config_path" required placeholder="完整路径"></label><button type="submit">导入已有项目</button></form></section>
29
- <section id="verification" hidden><h2>在群里确认身份</h2><p id="connection" role="status"></p><p class="muted">发送消息后页面会自动继续,无需回来确认。刷新页面可恢复当前接入进度。</p><p>请用自己的企业微信账号,<strong>@ 刚刚分配的机器人</strong>,发送下面这条消息:</p><pre id="code"></pre><button id="copy-code">复制消息</button><button id="confirm-code">立即检查</button><button id="retry-code" class="secondary" hidden>重新连接</button></section>
30
- <section id="profile" hidden><button id="profile-back" class="back-button secondary" hidden>← 返回项目</button><div class="row"><h2 id="profile-title"></h2><button id="refresh" class="secondary">刷新机器人状态</button></div><p id="profile-repo"></p><details id="profile-diagnostics" hidden><summary>查看本机配置路径</summary><pre id="config-path"></pre><button id="copy-config-path">复制配置路径</button></details><p id="next-step" class="next-step" role="status"></p><ol id="setup-steps" class="setup-steps"></ol><details><summary>连接检查详情</summary><div id="checks"></div></details><div id="progress"></div><div id="binding" hidden><h3>最后一步:在你选定的 Codex 对话启用</h3><p>在 Codex 打开上面的项目,信任项目并加载 MCP(已打开的项目请重新加载 MCP),将下面的指令发到要绑定的对话。Skill 会完成身份检查、对话绑定和轮询启用。完成后本页自动更新实际连接状态。</p><pre id="binding-text"></pre><button id="copy-binding">复制启用指令</button><details><summary>无法识别 Skill 时使用详细指令</summary><pre id="binding-details"></pre><button id="copy-binding-details">复制详细指令</button></details></div><div id="diagnostic-actions" hidden><button id="run-diagnostics" class="secondary">检查整条连接</button><button id="repair-project" class="secondary">修复本机配置</button><div id="diagnostic-result" role="status"></div></div><div id="runner-actions" hidden><button id="start">启动机器人连接</button><button id="stop" class="secondary">停止机器人连接</button><p class="muted">停止连接仅断开群机器人。对话中的轮询自动化需要在 Codex 中单独暂停。</p></div>
31
- <details id="manage-project"><summary>管理与重置</summary><p>选择要调整的配置,先查看影响,再确认。每次只操作当前 Agent 和 clone。</p><div class="manage-actions"><button id="reset-conversation" class="secondary">重新绑定对话</button><button id="reset-robot" class="secondary">更新机器人凭据</button><button id="reset-project" class="danger">移除本机接入</button></div></details>
32
- <div id="admin-tools" hidden><details><summary>团队分工、审核与通知设置</summary><h3>团队 Agent 与分工</h3><div id="members"></div><div id="owners"></div><button id="add-own-agent" class="secondary">给自己增加机器人</button><div id="routes"></div><h3>任务基准分支</h3><button type="button" id="load-repository-settings" class="secondary">读取并调整基准分支</button><form id="repository-policy-form" hidden><label>业务基准分支<select id="team-base-branch" required></select></label><p class="muted">保存后所有成员的新任务使用此分支。已创建任务保留原来的分支、起始提交和审核规则。</p><button type="submit">保存团队基准分支</button></form><h3>真人审核与通知</h3><p>按职责设置:阶段结果提交后由谁审核、通知谁。关闭中间审核可直接接力;最终提交仍需真人审核,并由管理员完成任务。关闭审核的职责作为最后阶段时由管理员审核。</p><p id="review-policy-note" class="muted"></p><form id="review-form" hidden><div id="review-rules"></div><button type="submit">保存审核规则</button></form><p class="muted">规则保存后用于新任务。现有任务继续使用创建时的规则。审核通知附带分支、提交、测试和可复制的群命令;企业微信原生 @ 的显示效果需要在实际群中确认。</p></details><h3>批量分配机器人给同事</h3><p>每行分配一个独立机器人。同一个同事可以领取多行,分别绑定独立项目和对话。接入包密码自动生成。</p>
33
- <form id="batch-form"><div id="assignment-rows"></div><div class="row"><button id="add-assignment" type="button" class="secondary">增加一位成员/机器人</button><button type="submit">生成全部接入包</button></div></form>
34
- <div id="delivery-panel" hidden><h3 id="delivery-title"></h3><p>接入包与密码请分开传递。下面的接入说明不包含密码或 Secret。</p><pre id="delivery-instructions"></pre><button id="copy-delivery">复制接入说明</button><label id="delivery-password-label">接入包密码<input id="delivery-password" type="password" readonly></label><button id="copy-password" type="button" class="secondary">复制密码</button><p id="delivery-password-note" class="muted" hidden></p><a id="delivery-download" class="secondary">下载这份接入包</a><button id="reissue-invite" type="button" class="secondary" hidden>重新生成接入包与密码</button><form id="reissue-form" hidden><p>旧包和未批准的旧入队申请将失效。保持原机器人和职责;请输入这个机器人的 Secret,自动生成新的密码。</p><label>机器人 Bot ID<input id="reissue-bot-id" readonly></label><label>机器人 Secret<input id="reissue-secret" name="secret" type="password" required autocomplete="off"></label><button type="submit">生成新的接入包与密码</button><button id="reissue-cancel" type="button" class="secondary">取消</button></form><button id="hide-delivery" type="button" class="secondary">收起</button></div>
35
- <details><summary>单独分配(兼容入口)</summary><form id="issue-form"><div class="row"><label>Agent ID<input name="agent_id" required pattern="[a-zA-Z0-9_-]{1,64}" placeholder="bob"></label><label>职责标签<input name="capabilities" required placeholder="backend"></label></div><div class="row"><label>机器人 Bot ID<input name="bot_id" required autocomplete="off"></label><label>机器人 Secret<input name="secret" type="password" required autocomplete="off"></label></div><label>自定义密码(可选,留空自动生成)<input name="password" type="password" minlength="12" autocomplete="off"></label><label class="checkbox"><input name="prefer" type="checkbox" checked>设为这些职责的首选执行者</label><label class="checkbox"><input name="commands_enabled" type="checkbox" checked>允许所有者通过此机器人发送群命令</label><button type="submit">生成接入包</button></form></details>
36
- <h3>已分配的机器人</h3><div id="exports"></div><h3>待确认的成员</h3><div id="requests"></div></div>
37
- </section>
38
- <section id="reset-view" hidden><h2 id="reset-title"></h2><p id="reset-target"></p><ul id="reset-effects"></ul><p id="reset-thread" class="muted"></p><form id="reset-form"><label id="reset-pause-label" class="checkbox"><input id="reset-paused" name="heartbeat_paused" type="checkbox">我已在原 Codex 对话暂停协作轮询</label><div id="reset-secret-fields" hidden><label>新的机器人 Secret<input id="reset-secret" name="secret" type="password" autocomplete="off"></label><p class="muted">保持原 Bot ID、群和本人身份。更换机器人或成员请移除本机接入后,由管理员提供新的接入包。</p><button id="reset-connect" type="button" class="secondary">验证新凭据</button><div id="reset-verification" hidden><p id="reset-connection"></p><p>用原绑定的企业微信本人账号,在原协作群 @ 当前机器人,发送:</p><pre id="reset-code"></pre><button id="reset-copy-code" type="button" class="secondary">复制验证码</button></div></div><label>输入 Agent 名称确认<input id="reset-confirmation" name="confirmation" required autocomplete="off"></label><div class="row"><button id="reset-submit" type="submit">确认操作</button><button id="reset-cancel" type="button" class="secondary">取消并返回</button></div></form><p class="muted">操作前自动保存本机恢复记录。向导不会删除 Codex 聊天,也无法替你暂停聊天中的自动化。移除接入保留私有身份与历史凭据;需要彻底删除时可按完成页显示的备份路径手动处理。</p></section>
39
- </main><footer>配置仅保存在本机。任务与签名协议记录在业务仓库的 agent-collab 分支。</footer><script src="/app.js" defer></script></body></html>
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>Codex Collab · 团队接入</title>
8
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
9
+ <link rel="stylesheet" href="/style.css">
10
+ </head>
11
+ <body>
12
+ <header class="masthead">
13
+ <a class="brand" href="/" data-view="home" aria-label="Codex Collab 首页">
14
+ <span class="brand-mark" aria-hidden="true">⌘</span>Codex Collab</a>
15
+ <span class="workspace-label">本机连接</span>
16
+ </header>
17
+ <main>
18
+ <div id="notice" role="status" hidden>
19
+ </div>
20
+ <section id="home" class="scene home">
21
+ <div class="scene-art welcome" aria-hidden="true">
22
+ <span class="art-halo">
23
+ </span>
24
+ <span class="art-tile">
25
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
26
+ <path d="m8 6-5 6 5 6m8-12 5 6-5 6m-3-14-2 16"/>
27
+ </svg>
28
+ </span>
29
+ <span class="art-small" aria-hidden="true">↗</span>
30
+ <span class="art-spark">
31
+ </span>
32
+ </div>
33
+ <div class="intro">
34
+ <h1 tabindex="-1">让协作,简单一点。</h1>
35
+ <p>选一个项目,和你的团队继续工作。</p>
36
+ </div>
37
+ <div id="profiles" class="project-list" aria-label="我的项目">
38
+ </div>
39
+ <div class="home-actions">
40
+ <button data-view="admin" class="button primary">+ 接入一个项目</button>
41
+ <button data-view="join" class="quiet-button">接受同事的邀请 →</button>
42
+ </div>
43
+ <details class="home-more">
44
+ <summary>其他接入方式</summary>
45
+ <button data-view="existing" class="quiet-button">导入已有配置 →</button>
46
+ <p id="startup-status" class="muted">
47
+ </p>
48
+ <details id="removed-projects" hidden>
49
+ <summary>已移除的接入</summary>
50
+ <p class="muted">恢复前请确保原项目目录未绑定其他身份。</p>
51
+ <div id="removed-profiles">
52
+ </div>
53
+ </details>
54
+ </details>
55
+ </section>
56
+ <section id="project" class="scene project-scene" hidden>
57
+ <button id="project-back" class="back-link">← 所有项目</button>
58
+ <div class="scene-art code" aria-hidden="true">
59
+ <span class="art-halo">
60
+ </span>
61
+ <span class="art-tile">
62
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
63
+ <path d="m8 6-5 6 5 6m8-12 5 6-5 6m-3-14-2 16"/>
64
+ </svg>
65
+ </span>
66
+ </div>
67
+ <div class="intro">
68
+ <h1 id="project-title" tabindex="-1">
69
+ </h1>
70
+ <p>你的机器人和同事,都在这里。</p>
71
+ </div>
72
+ <div id="project-agents" class="agent-list">
73
+ </div>
74
+ <div class="project-actions">
75
+ <button id="project-add-own" class="button primary" hidden>+ 添加我的机器人</button>
76
+ <button id="project-settings" class="quiet-button" hidden>团队与邀请 →</button>
77
+ </div>
78
+ <details class="project-details">
79
+ <summary>查看项目信息</summary>
80
+ <p id="project-repository" class="repository-path">
81
+ </p>
82
+ <p id="project-sync" class="muted" role="status">
83
+ </p>
84
+ <button id="project-refresh" class="quiet-button">刷新项目信息</button>
85
+ </details>
86
+ </section>
87
+ <section id="admin" class="scene setup-scene" hidden>
88
+ <button id="admin-back" class="back-link">← 返回</button>
89
+ <div id="admin-step-progress" class="step-progress" aria-label="接入进度">
90
+ <span class="filled" aria-current="step">
91
+ </span>
92
+ <span>
93
+ </span>
94
+ <span>
95
+ </span>
96
+ <span>
97
+ </span>
98
+ </div>
99
+ <form id="admin-form" novalidate>
100
+ <div data-wizard-panel="0">
101
+ <div class="scene-art folder" aria-hidden="true">
102
+ <span class="art-halo">
103
+ </span>
104
+ <span class="art-tile">
105
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
106
+ <path d="M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10H3Z"/>
107
+ </svg>
108
+ </span>
109
+ </div>
110
+ <div class="intro">
111
+ <h1 tabindex="-1">从一个项目开始。</h1>
112
+ <p>确认电脑里的项目,其他信息会自动带入。</p>
113
+ </div>
114
+ <div class="step-content">
115
+ <label>项目来源<select id="admin-repo-mode" name="repo_mode">
116
+ <option value="existing">使用本机已有项目</option>
117
+ <option value="clone">从 Git 地址拉取新项目</option>
118
+ </select>
119
+ </label>
120
+ <label id="admin-existing-repo">项目目录<input name="repo" id="admin-repo" placeholder="Git 仓库根目录的完整路径">
121
+ </label>
122
+ <div id="admin-clone-repo" hidden>
123
+ <label>Git 仓库地址<input name="remote" id="admin-remote" placeholder="HTTPS 或 SSH 地址,不含 Token">
124
+ </label>
125
+ <label>保存到新目录(可选)<input name="destination" id="admin-destination" placeholder="留空按项目与名称生成独立目录">
126
+ </label>
127
+ </div>
128
+ <p id="project-check-status" class="muted" role="status">会自动识别仓库、默认分支和验证命令。</p>
129
+ <details id="project-options">
130
+ <summary>分支与验证方式</summary>
131
+ <button id="check-project" type="button" class="secondary">重新检查项目</button>
132
+ <p id="project-recommendation" class="muted">使用本机已有的 Git 登录,自动识别远程仓库和默认分支;无法确定时只需选择一次。</p>
133
+ <div id="repository-options" hidden>
134
+ <label>协作远程<select name="remote_name" id="admin-remote-name">
135
+ <option value="">自动识别</option>
136
+ </select>
137
+ </label>
138
+ <label>业务基准分支<select name="base_branch" id="admin-base-branch">
139
+ <option value="">使用远程默认分支</option>
140
+ </select>
141
+ </label>
142
+ <p class="muted">同事和新增机器人会继承这个基准分支。每个新任务固定起始提交,后续分支更新不会改变已有任务。</p>
143
+ </div>
144
+ <label>验证命令<input id="test-command" name="test_command" required placeholder="例如 npm test、go test ./...、sh test.sh">
145
+ </label>
146
+ <p class="muted">请确认这个命令适合项目。工具使用固定程序和参数执行,不运行管道或拼接命令。</p>
147
+ </details>
148
+ </div>
149
+ </div>
150
+ <div data-wizard-panel="1" hidden>
151
+ <div class="scene-art bot" aria-hidden="true">
152
+ <span class="art-halo">
153
+ </span>
154
+ <span class="art-tile">
155
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
156
+ <rect x="4" y="7" width="16" height="13" rx="4"/>
157
+ <path d="M12 3v4m-4 6h.01M16 13h.01M9 17h6"/>
158
+ </svg>
159
+ </span>
160
+ </div>
161
+ <div class="intro">
162
+ <h1 tabindex="-1">连上你的企微机器人。</h1>
163
+ <p>填写这两项,就可以继续了。</p>
164
+ </div>
165
+ <div class="step-content">
166
+ <div class="bot-fields">
167
+ <label>你的机器人 Bot ID<input name="bot_id" required autocomplete="off">
168
+ </label>
169
+ <label>机器人 Secret<input name="secret" type="password" required autocomplete="off">
170
+ </label>
171
+ </div>
172
+ <details>
173
+ <summary>机器人信息从哪里获取?</summary>
174
+ <p>在企业微信中创建智能机器人,选择 API 模式,复制 Bot ID 和 Secret,并把机器人加入协作群。</p>
175
+ </details>
176
+ <details>
177
+ <summary>名称与分工</summary>
178
+ <div class="row">
179
+ <label>你的显示名称<input name="display_name" required placeholder="例如 Alice 或张三" maxlength="80">
180
+ </label>
181
+ <label>主要职责<select name="responsibility">
182
+ <option value="fullstack">全栈开发</option>
183
+ <option value="frontend">前端开发</option>
184
+ <option value="backend">后端开发</option>
185
+ <option value="testing">测试</option>
186
+ <option value="docs">文档</option>
187
+ <option value="general">通用开发</option>
188
+ </select>
189
+ </label>
190
+ </div>
191
+ <details>
192
+ <summary>更多设置:团队名称、内部身份与职责</summary>
193
+ <label>团队名称(可选)<input name="team_name" placeholder="留空使用项目名称" maxlength="80">
194
+ </label>
195
+ <label>内部 Agent ID(可选)<input name="agent_id" pattern="[a-zA-Z0-9_\-]{1,64}" placeholder="留空自动生成">
196
+ </label>
197
+ <label>自定义职责标签(可选)<input name="capabilities" placeholder="英文标签,以逗号分隔">
198
+ </label>
199
+ </details>
200
+ </details>
201
+ </div>
202
+ </div>
203
+ <div class="step-actions">
204
+ <button id="admin-continue" type="submit" class="button primary continue-button">继续 →</button>
205
+ <span id="admin-step-count" class="step-count">01 / 04</span>
206
+ </div>
207
+ </form>
208
+ </section>
209
+ <section id="own" class="scene setup-scene" hidden>
210
+ <button id="own-back" class="back-link">← 返回</button>
211
+ <div id="own-step-progress" class="step-progress" aria-label="接入进度">
212
+ <span class="filled" aria-current="step">
213
+ </span>
214
+ <span>
215
+ </span>
216
+ <span>
217
+ </span>
218
+ <span>
219
+ </span>
220
+ </div>
221
+ <form id="own-form" novalidate>
222
+ <div data-wizard-panel="0">
223
+ <div class="scene-art folder" aria-hidden="true">
224
+ <span class="art-halo">
225
+ </span>
226
+ <span class="art-tile">
227
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
228
+ <path d="M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10H3Z"/>
229
+ </svg>
230
+ </span>
231
+ </div>
232
+ <div class="intro">
233
+ <h1 tabindex="-1">再加一位助手。</h1>
234
+ <p>每个机器人使用独立项目目录和 Codex 对话。</p>
235
+ </div>
236
+ <div class="step-content">
237
+ <label>准备项目<select id="own-repo-mode" name="repo_mode">
238
+ <option value="clone">自动拉取独立项目</option>
239
+ <option value="existing">使用已有的独立 clone</option>
240
+ </select>
241
+ </label>
242
+ <label id="own-clone-repo">新项目目录(可选)<input name="destination" placeholder="留空按项目和 Agent 名称创建">
243
+ </label>
244
+ <label id="own-existing-repo" hidden>另一个 clone 的本机目录<input name="repo" placeholder="同一业务仓库的另一个独立 clone">
245
+ </label>
246
+ <div class="row">
247
+ <label>新的 Agent 名称<input name="agent_id" required pattern="[a-zA-Z0-9_\-]{1,64}" placeholder="bob">
248
+ </label>
249
+ <label>职责标签<input name="capabilities" required placeholder="backend">
250
+ </label>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ <div data-wizard-panel="1" hidden>
255
+ <div class="scene-art bot" aria-hidden="true">
256
+ <span class="art-halo">
257
+ </span>
258
+ <span class="art-tile">
259
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
260
+ <rect x="4" y="7" width="16" height="13" rx="4"/>
261
+ <path d="M12 3v4m-4 6h.01M16 13h.01M9 17h6"/>
262
+ </svg>
263
+ </span>
264
+ </div>
265
+ <div class="intro">
266
+ <h1 tabindex="-1">连接新的企微机器人。</h1>
267
+ <p>同一个企微账号验证后,会自动完成入队。</p>
268
+ </div>
269
+ <div class="step-content">
270
+ <div class="bot-fields">
271
+ <label>新机器人 Bot ID<input name="bot_id" required autocomplete="off">
272
+ </label>
273
+ <label>新机器人 Secret<input name="secret" type="password" required autocomplete="off">
274
+ </label>
275
+ </div>
276
+ <label class="checkbox">
277
+ <input name="prefer" type="checkbox" checked>该 Agent 为这些职责的首选执行者</label>
278
+ </div>
279
+ </div>
280
+ <div class="step-actions">
281
+ <button id="own-continue" type="submit" class="button primary continue-button">继续 →</button>
282
+ <span id="own-step-count" class="step-count">01 / 04</span>
283
+ </div>
284
+ <button id="own-cancel" type="button" class="quiet-button form-cancel">返回原项目</button>
285
+ </form>
286
+ </section>
287
+ <section id="join" class="scene setup-scene" hidden>
288
+ <button id="join-back" class="back-link">← 返回</button>
289
+ <div id="join-step-progress" class="step-progress" aria-label="接入进度">
290
+ <span class="filled" aria-current="step">
291
+ </span>
292
+ <span>
293
+ </span>
294
+ <span>
295
+ </span>
296
+ <span>
297
+ </span>
298
+ </div>
299
+ <form id="join-form" novalidate>
300
+ <div data-wizard-panel="0">
301
+ <div class="scene-art folder" aria-hidden="true">
302
+ <span class="art-halo">
303
+ </span>
304
+ <span class="art-tile">
305
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
306
+ <path d="M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10H3Z"/>
307
+ </svg>
308
+ </span>
309
+ </div>
310
+ <div class="intro">
311
+ <h1 tabindex="-1">加入同事的项目。</h1>
312
+ <p>选择同事发来的接入包,填入单独收到的密码。</p>
313
+ </div>
314
+ <div class="step-content">
315
+ <label>接入包文件<input name="file" id="invite-file" type="file" accept=".json" required>
316
+ </label>
317
+ <label>接入包密码<input name="password" id="invite-password" type="password" required autocomplete="off">
318
+ </label>
319
+ <button id="inspect-invite" type="button" class="secondary">重新读取邀请</button>
320
+ </div>
321
+ </div>
322
+ <div data-wizard-panel="1" hidden>
323
+ <div class="scene-art folder" aria-hidden="true">
324
+ <span class="art-halo">
325
+ </span>
326
+ <span class="art-tile">
327
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
328
+ <path d="M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10H3Z"/>
329
+ </svg>
330
+ </span>
331
+ </div>
332
+ <div class="intro">
333
+ <h1 tabindex="-1">是这个项目,对吗?</h1>
334
+ <p>机器人和分工已带入,只需确认本机目录。</p>
335
+ </div>
336
+ <div class="step-content">
337
+ <div id="invite-info" class="selected-project" hidden>
338
+ <p id="invite-summary">
339
+ </p>
340
+ <p id="invite-remote" class="muted">
341
+ </p>
342
+ </div>
343
+ <label>准备项目<select id="join-repo-mode" name="repo_mode">
344
+ <option value="clone">帮我拉取到新目录</option>
345
+ <option value="existing">使用本机已有项目</option>
346
+ </select>
347
+ </label>
348
+ <label id="join-clone-repo">新项目目录<input name="destination" placeholder="留空使用推荐目录,亦可填写完整路径">
349
+ </label>
350
+ <label id="join-existing-repo" hidden>已有项目目录<input name="repo" placeholder="Git 仓库根目录的完整路径">
351
+ </label>
352
+ </div>
353
+ </div>
354
+ <div class="step-actions">
355
+ <button id="join-continue" type="submit" class="button primary continue-button">继续 →</button>
356
+ <span id="join-step-count" class="step-count">01 / 04</span>
357
+ </div>
358
+ </form>
359
+ </section>
360
+ <section id="existing" class="scene setup-scene" hidden>
361
+ <button class="back-link" data-view="home">← 所有项目</button>
362
+ <div class="scene-art folder" aria-hidden="true">
363
+ <span class="art-halo">
364
+ </span>
365
+ <span class="art-tile">
366
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
367
+ <path d="M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v10H3Z"/>
368
+ </svg>
369
+ </span>
370
+ </div>
371
+ <div class="intro">
372
+ <h1 tabindex="-1">继续已有的协作。</h1>
373
+ </div>
374
+ <p>先停止原 Runner。导入会保留原成员身份、任务和对话绑定,并重新启动机器人。旧团队由管理员先导入。</p>
375
+ <form id="existing-form">
376
+ <label>已有私有 peer.json 路径<input name="config_path" required placeholder="完整路径">
377
+ </label>
378
+ <button type="submit">导入已有项目</button>
379
+ </form>
380
+ </section>
381
+ <section id="verification" class="scene setup-scene" hidden>
382
+ <button class="back-link" data-view="home">← 所有项目</button>
383
+ <div class="step-progress" aria-label="第 3 步,共 4 步">
384
+ <span class="filled">
385
+ </span>
386
+ <span class="filled">
387
+ </span>
388
+ <span class="filled" aria-current="step">
389
+ </span>
390
+ <span>
391
+ </span>
392
+ </div>
393
+ <div class="scene-art bot" aria-hidden="true">
394
+ <span class="art-halo">
395
+ </span>
396
+ <span class="art-tile">
397
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
398
+ <rect x="4" y="7" width="16" height="13" rx="4"/>
399
+ <path d="M12 3v4m-4 6h.01M16 13h.01M9 17h6"/>
400
+ </svg>
401
+ </span>
402
+ </div>
403
+ <div class="intro">
404
+ <h1 tabindex="-1">在群里,打个招呼。</h1>
405
+ <p>用自己的企业微信账号,@ 刚刚连接的机器人。</p>
406
+ </div>
407
+ <div class="step-content">
408
+ <pre id="code" class="command-preview">
409
+ </pre>
410
+ <p id="connection" class="binding-caption" role="status">
411
+ </p>
412
+ <div class="step-actions">
413
+ <button id="copy-code" class="button primary">复制群验证消息</button>
414
+ <span class="muted">发送后,这里会自动继续。</span>
415
+ </div>
416
+ <details>
417
+ <summary>还没有继续?</summary>
418
+ <p>请确认消息发在目标协作群里,并且 @ 了对应的机器人。</p>
419
+ <button id="confirm-code" class="quiet-button">立即检查</button>
420
+ </details>
421
+ <button id="retry-code" class="quiet-button" hidden>重新连接 →</button>
422
+ </div>
423
+ </section>
424
+ <section id="profile" class="scene setup-scene" hidden>
425
+ <button id="profile-back" class="back-link" hidden>← 返回项目</button>
426
+ <div id="profile-step-progress" class="step-progress" aria-label="第 4 步,共 4 步">
427
+ <span class="filled"></span>
428
+ <span class="filled"></span>
429
+ <span class="filled"></span>
430
+ <span class="filled" aria-current="step"></span>
431
+ </div>
432
+ <div id="profile-art">
433
+ <div class="scene-art code" aria-hidden="true">
434
+ <span class="art-halo">
435
+ </span>
436
+ <span class="art-tile">
437
+ <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
438
+ <path d="m8 6-5 6 5 6m8-12 5 6-5 6m-3-14-2 16"/>
439
+ </svg>
440
+ </span>
441
+ </div>
442
+ </div>
443
+ <div class="intro">
444
+ <h1 id="profile-heading" tabindex="-1">正在准备你的项目。</h1>
445
+ <p id="profile-title">
446
+ </p>
447
+ </div>
448
+ <p id="profile-repo" class="repository-path profile-repo">
449
+ </p>
450
+ <p id="next-step" class="next-step" role="status">
451
+ </p>
452
+ <div id="progress">
453
+ </div>
454
+ <div id="binding" hidden>
455
+ <div class="binding-illustration" aria-hidden="true">
456
+ <span class="binding-node">企微</span>
457
+ <span class="binding-line">
458
+ <i>
459
+ </i>
460
+ <i>
461
+ </i>
462
+ <i>
463
+ </i>
464
+ </span>
465
+ <span class="binding-node codex-node">⌘</span>
466
+ </div>
467
+ <pre id="binding-text">
468
+ </pre>
469
+ <button id="copy-binding" class="button primary">复制启用指令</button>
470
+ <details>
471
+ <summary>无法识别 Skill 时使用详细指令</summary>
472
+ <p>首次使用请信任项目并加载 MCP;已打开的项目请重新加载 MCP。</p>
473
+ <pre id="binding-details">
474
+ </pre>
475
+ <button id="copy-binding-details">复制详细指令</button>
476
+ </details>
477
+ </div>
478
+ <div class="step-actions">
479
+ <button id="profile-done" class="button primary" hidden>回到项目 →</button>
480
+ <button id="profile-start" class="button primary" hidden>恢复机器人连接 →</button>
481
+ </div>
482
+ <button id="pending-requests" class="quiet-button" hidden>
483
+ </button>
484
+ <details id="connection-details">
485
+ <summary>查看连接详情</summary>
486
+ <ol id="setup-steps" class="setup-steps">
487
+ </ol>
488
+ <details>
489
+ <summary>连接检查详情</summary>
490
+ <div id="checks">
491
+ </div>
492
+ </details>
493
+ <details id="profile-diagnostics" hidden>
494
+ <summary>本机配置路径</summary>
495
+ <pre id="config-path">
496
+ </pre>
497
+ <button id="copy-config-path" class="quiet-button">复制配置路径</button>
498
+ </details>
499
+ <button id="refresh" class="quiet-button">刷新机器人状态</button>
500
+ <div id="diagnostic-actions" hidden>
501
+ <button id="run-diagnostics" class="secondary">检查整条连接</button>
502
+ <button id="repair-project" class="secondary">修复本机配置</button>
503
+ <div id="diagnostic-result" role="status">
504
+ </div>
505
+ </div>
506
+ <div id="runner-actions" hidden>
507
+ <button id="start">启动机器人连接</button>
508
+ <button id="stop" class="secondary">停止机器人连接</button>
509
+ <p class="muted">停止连接仅断开群机器人。对话中的轮询自动化需要在 Codex 中单独暂停。</p>
510
+ </div>
511
+ <details id="manage-project">
512
+ <summary>管理与重置</summary>
513
+ <p>选择要调整的配置,先查看影响,再确认。每次只操作当前 Agent 和 clone。</p>
514
+ <div class="manage-actions">
515
+ <button id="reset-conversation" class="secondary">重新绑定对话</button>
516
+ <button id="reset-robot" class="secondary">更新机器人凭据</button>
517
+ <button id="reset-project" class="danger">移除本机接入</button>
518
+ </div>
519
+ </details>
520
+ </details>
521
+ <details id="admin-tools" hidden>
522
+ <summary>团队与邀请</summary>
523
+ <details>
524
+ <summary>团队分工、审核与通知设置</summary>
525
+ <h3>团队 Agent 与分工</h3>
526
+ <div id="members">
527
+ </div>
528
+ <div id="owners">
529
+ </div>
530
+ <button id="add-own-agent" class="secondary">给自己增加机器人</button>
531
+ <div id="routes">
532
+ </div>
533
+ <h3>任务基准分支</h3>
534
+ <button type="button" id="load-repository-settings" class="secondary">读取并调整基准分支</button>
535
+ <form id="repository-policy-form" hidden>
536
+ <label>业务基准分支<select id="team-base-branch" required>
537
+ </select>
538
+ </label>
539
+ <p class="muted">保存后所有成员的新任务使用此分支。已创建任务保留原来的分支、起始提交和审核规则。</p>
540
+ <button type="submit">保存团队基准分支</button>
541
+ </form>
542
+ <h3>真人审核与通知</h3>
543
+ <p>按职责设置:阶段结果提交后由谁审核、通知谁。关闭中间审核可直接接力;最终提交仍需真人审核,并由管理员完成任务。关闭审核的职责作为最后阶段时由管理员审核。</p>
544
+ <p id="review-policy-note" class="muted">
545
+ </p>
546
+ <form id="review-form" hidden>
547
+ <div id="review-rules">
548
+ </div>
549
+ <button type="submit">保存审核规则</button>
550
+ </form>
551
+ <p class="muted">规则保存后用于新任务。现有任务继续使用创建时的规则。审核通知附带分支、提交、测试和可复制的群命令;企业微信原生 @ 的显示效果需要在实际群中确认。</p>
552
+ </details>
553
+ <h3>批量分配机器人给同事</h3>
554
+ <p>每行分配一个独立机器人。同一个同事可以领取多行,分别绑定独立项目和对话。接入包密码自动生成。</p>
555
+ <form id="batch-form">
556
+ <div id="assignment-rows">
557
+ </div>
558
+ <div class="row">
559
+ <button id="add-assignment" type="button" class="secondary">增加一位成员/机器人</button>
560
+ <button type="submit">生成全部接入包</button>
561
+ </div>
562
+ </form>
563
+ <div id="delivery-panel" hidden>
564
+ <h3 id="delivery-title">
565
+ </h3>
566
+ <p>接入包与密码请分开传递。下面的接入说明不包含密码或 Secret。</p>
567
+ <pre id="delivery-instructions">
568
+ </pre>
569
+ <button id="copy-delivery">复制接入说明</button>
570
+ <label id="delivery-password-label">接入包密码<input id="delivery-password" type="password" readonly>
571
+ </label>
572
+ <button id="copy-password" type="button" class="secondary">复制密码</button>
573
+ <p id="delivery-password-note" class="muted" hidden>
574
+ </p>
575
+ <a id="delivery-download" class="secondary">下载这份接入包</a>
576
+ <button id="reissue-invite" type="button" class="secondary" hidden>重新生成接入包与密码</button>
577
+ <form id="reissue-form" hidden>
578
+ <p>旧包和未批准的旧入队申请将失效。保持原机器人和职责;请输入这个机器人的 Secret,自动生成新的密码。</p>
579
+ <label>机器人 Bot ID<input id="reissue-bot-id" readonly>
580
+ </label>
581
+ <label>机器人 Secret<input id="reissue-secret" name="secret" type="password" required autocomplete="off">
582
+ </label>
583
+ <button type="submit">生成新的接入包与密码</button>
584
+ <button id="reissue-cancel" type="button" class="secondary">取消</button>
585
+ </form>
586
+ <button id="hide-delivery" type="button" class="secondary">收起</button>
587
+ </div>
588
+ <details>
589
+ <summary>单独分配(兼容入口)</summary>
590
+ <form id="issue-form">
591
+ <div class="row">
592
+ <label>Agent ID<input name="agent_id" required pattern="[a-zA-Z0-9_\-]{1,64}" placeholder="bob">
593
+ </label>
594
+ <label>职责标签<input name="capabilities" required placeholder="backend">
595
+ </label>
596
+ </div>
597
+ <div class="row">
598
+ <label>机器人 Bot ID<input name="bot_id" required autocomplete="off">
599
+ </label>
600
+ <label>机器人 Secret<input name="secret" type="password" required autocomplete="off">
601
+ </label>
602
+ </div>
603
+ <label>自定义密码(可选,留空自动生成)<input name="password" type="password" minlength="12" autocomplete="off">
604
+ </label>
605
+ <label class="checkbox">
606
+ <input name="prefer" type="checkbox" checked>设为这些职责的首选执行者</label>
607
+ <label class="checkbox">
608
+ <input name="commands_enabled" type="checkbox" checked>允许所有者通过此机器人发送群命令</label>
609
+ <button type="submit">生成接入包</button>
610
+ </form>
611
+ </details>
612
+ <h3>已分配的机器人</h3>
613
+ <div id="exports">
614
+ </div>
615
+ <h3>待确认的成员</h3>
616
+ <div id="requests">
617
+ </div>
618
+ </details>
619
+ </section>
620
+ <section id="reset-view" class="scene setup-scene" hidden>
621
+ <h2 id="reset-title">
622
+ </h2>
623
+ <p id="reset-target">
624
+ </p>
625
+ <ul id="reset-effects">
626
+ </ul>
627
+ <p id="reset-thread" class="muted">
628
+ </p>
629
+ <form id="reset-form">
630
+ <label id="reset-pause-label" class="checkbox">
631
+ <input id="reset-paused" name="heartbeat_paused" type="checkbox">我已在原 Codex 对话暂停协作轮询</label>
632
+ <div id="reset-secret-fields" hidden>
633
+ <label>新的机器人 Secret<input id="reset-secret" name="secret" type="password" autocomplete="off">
634
+ </label>
635
+ <p class="muted">保持原 Bot ID、群和本人身份。更换机器人或成员请移除本机接入后,由管理员提供新的接入包。</p>
636
+ <button id="reset-connect" type="button" class="secondary">验证新凭据</button>
637
+ <div id="reset-verification" hidden>
638
+ <p id="reset-connection">
639
+ </p>
640
+ <p>用原绑定的企业微信本人账号,在原协作群 @ 当前机器人,发送:</p>
641
+ <pre id="reset-code">
642
+ </pre>
643
+ <button id="reset-copy-code" type="button" class="secondary">复制验证码</button>
644
+ </div>
645
+ </div>
646
+ <label>输入 Agent 名称确认<input id="reset-confirmation" name="confirmation" required autocomplete="off">
647
+ </label>
648
+ <div class="row">
649
+ <button id="reset-submit" type="submit">确认操作</button>
650
+ <button id="reset-cancel" type="button" class="secondary">取消并返回</button>
651
+ </div>
652
+ </form>
653
+ <p class="muted">操作前自动保存本机恢复记录。向导不会删除 Codex 聊天,也无法替你暂停聊天中的自动化。移除接入保留私有身份与历史凭据;需要彻底删除时可按完成页显示的备份路径手动处理。</p>
654
+ </section>
655
+ </main>
656
+ <footer class="demo-footer">
657
+ <span>企业微信 · 本机协作</span>
658
+ <div class="theme-picker" role="group" aria-label="页面配色">
659
+ <button class="theme-choice" data-theme-choice="day" aria-pressed="true">
660
+ <i aria-hidden="true">
661
+ </i>纸白</button>
662
+ <button class="theme-choice" data-theme-choice="studio" aria-pressed="false">
663
+ <i aria-hidden="true">
664
+ </i>雾绿</button>
665
+ <button class="theme-choice" data-theme-choice="night" aria-pressed="false">
666
+ <i aria-hidden="true">
667
+ </i>夜色</button>
668
+ </div>
669
+ </footer>
670
+ <script src="/app.js" defer>
671
+ </script>
672
+ </body>
673
+ </html>