opencode-collaboration 2.2.0.post1__py3-none-any.whl → 2.2.0.post3__py3-none-any.whl
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.
- {opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/METADATA +2 -2
- {opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/RECORD +7 -6
- src/cli/main.py +75 -11
- src/core/session_manager.py +213 -0
- {opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/WHEEL +0 -0
- {opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/entry_points.txt +0 -0
- {opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-collaboration
|
|
3
|
-
Version: 2.2.0.
|
|
3
|
+
Version: 2.2.0.post3
|
|
4
4
|
Summary: 双Agent协作框架 - 产品经理与开发的分离式协作工具
|
|
5
5
|
Author-email: liuzhen <dev@opencode.ai>
|
|
6
6
|
License: MIT
|
|
@@ -128,7 +128,7 @@ myproject/
|
|
|
128
128
|
## 详细文档
|
|
129
129
|
|
|
130
130
|
完整使用指南请参见项目 GitHub 仓库:
|
|
131
|
-
https://github.com/
|
|
131
|
+
https://github.com/legoland01/dual-agent-collaboration-system
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
{opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/RECORD
RENAMED
|
@@ -2,7 +2,7 @@ src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
2
2
|
src/main.py,sha256=W_G68r7XFyioa8wHlSsdwBK1eIyWDaIQWciyZxhZHgg,15
|
|
3
3
|
src/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
src/cli/agent.py,sha256=o8-3UpfcnUMePltpBdVBuBFMECMiKnOA7airyvi1m54,9874
|
|
5
|
-
src/cli/main.py,sha256=
|
|
5
|
+
src/cli/main.py,sha256=e3lgFfCSB9qHx0GOcG3f00VSQ_e_4AfMSWg-gSGAzeY,47300
|
|
6
6
|
src/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
src/core/agent_manager.py,sha256=Mxe4G_IfEaQ1lERdGNfMvK0tIS6DuE3WJUNOxgtAD8o,16535
|
|
8
8
|
src/core/auto_doc_git.py,sha256=_yphH8tLAMq3R-yMHpc2bcmmap2p7b2So4qVmXUtCh8,1396
|
|
@@ -27,6 +27,7 @@ src/core/monitor.py,sha256=3s0xuc6l7pF4MtnRjYVxbfn8MLfKk7p7mljqtsZDQZ0,8949
|
|
|
27
27
|
src/core/phase_advance.py,sha256=76UN8TI7RpJgRfjgV4bvs7uWlvNt-h_dz6gTDgK2zrY,11285
|
|
28
28
|
src/core/project_manager.py,sha256=qayc8NHy3go26LWZgw17nL57p8LXKjpprAS1_iKZHDg,16637
|
|
29
29
|
src/core/resource_lock.py,sha256=1G2yOdbqZnWqVdcIt6IKbhRLhSg23kLgJhdwiFt7jdY,13889
|
|
30
|
+
src/core/session_manager.py,sha256=2Hr36C71kIPia4UYKXx8Ym86T7_9TTQxC8ZrXm65IZU,6825
|
|
30
31
|
src/core/signoff.py,sha256=fG6KFNz3AYh6hKYMPfognU_SBs5amCW2q4bne4huFf0,6643
|
|
31
32
|
src/core/state_machine.py,sha256=L1gfdsYC6mlWcHP5RwQQen8vCTwV2spIP-Ktwz4gux8,14919
|
|
32
33
|
src/core/state_manager.py,sha256=jkgci5q71DRjmKe8igeFhOTxHJ2xqNjAHJo6THFtw_M,16672
|
|
@@ -41,8 +42,8 @@ src/utils/date.py,sha256=iWS0hTaoDE2iC0jJb3lTIB5yK5xxRbrC1C98Fgb8LFc,577
|
|
|
41
42
|
src/utils/file.py,sha256=5IFKkT2m1emJUHDzIiLsa4YG9GCqOhhmiLvc6aVY9-Y,1301
|
|
42
43
|
src/utils/lock.py,sha256=soxYFsBKJHUzN-_QXkorVfgnmt0D5p1SZtqwPNqcWPI,2880
|
|
43
44
|
src/utils/yaml.py,sha256=zcbh0OP7NOqxTexEAR3akQkllUh8xeKt42O2CHIImyg,777
|
|
44
|
-
opencode_collaboration-2.2.0.
|
|
45
|
-
opencode_collaboration-2.2.0.
|
|
46
|
-
opencode_collaboration-2.2.0.
|
|
47
|
-
opencode_collaboration-2.2.0.
|
|
48
|
-
opencode_collaboration-2.2.0.
|
|
45
|
+
opencode_collaboration-2.2.0.post3.dist-info/METADATA,sha256=bwam0apvaWCByCngne2gy9fW3X1pjX_Who0Gy1LmZgc,3127
|
|
46
|
+
opencode_collaboration-2.2.0.post3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
47
|
+
opencode_collaboration-2.2.0.post3.dist-info/entry_points.txt,sha256=fYyHWa_NefMp527B7fHl-29SwZQCElRdtxm_7LoUK-Y,48
|
|
48
|
+
opencode_collaboration-2.2.0.post3.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
|
|
49
|
+
opencode_collaboration-2.2.0.post3.dist-info/RECORD,,
|
src/cli/main.py
CHANGED
|
@@ -17,6 +17,7 @@ from ..core.auto_engine import AutoCollaborationEngine, TodoCommandExecutor, Wor
|
|
|
17
17
|
from ..core.auto_retry import AutoRetry, AutoRetryConfig
|
|
18
18
|
from ..core.auto_docs import AutoDocs, AutoDocsConfig
|
|
19
19
|
from ..core.phase_advance import PhaseAdvanceEngine
|
|
20
|
+
from ..core.session_manager import SessionManager
|
|
20
21
|
from ..utils.lock import LockExistsError
|
|
21
22
|
|
|
22
23
|
|
|
@@ -123,6 +124,9 @@ def status_command():
|
|
|
123
124
|
req_status = state_manager.get_signoff_status("requirements")
|
|
124
125
|
console.print(f"需求签署 - 产品经理: {'✓' if req_status['pm_signoff'] else '✗'}, 开发: {'✓' if req_status['dev_signoff'] else '✗'}")
|
|
125
126
|
|
|
127
|
+
session_manager = SessionManager(project_path)
|
|
128
|
+
session_manager.show_welcome(active_agent)
|
|
129
|
+
|
|
126
130
|
except StateFileNotFoundError:
|
|
127
131
|
click.echo("错误: 未找到项目状态文件,请先初始化项目")
|
|
128
132
|
sys.exit(1)
|
|
@@ -136,22 +140,33 @@ def status_command():
|
|
|
136
140
|
|
|
137
141
|
@main.command("switch")
|
|
138
142
|
@click.argument("agent_id", type=click.IntRange(1, 2))
|
|
139
|
-
|
|
143
|
+
@click.option("--welcome/--no-welcome", "-w", default=True, help="显示欢迎信息")
|
|
144
|
+
def switch_command(agent_id: int, welcome: bool):
|
|
140
145
|
"""切换Agent角色。"""
|
|
141
146
|
try:
|
|
142
147
|
project_path = get_project_path()
|
|
143
148
|
state_manager = StateManager(project_path)
|
|
144
|
-
|
|
149
|
+
|
|
145
150
|
current_agent = state_manager.get_active_agent()
|
|
146
151
|
if current_agent == f"agent{agent_id}":
|
|
147
152
|
click.echo(f"已经是 Agent {agent_id}")
|
|
148
153
|
return
|
|
149
|
-
|
|
154
|
+
|
|
150
155
|
state_manager.set_active_agent(f"agent{agent_id}")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
|
|
157
|
+
if welcome:
|
|
158
|
+
session_manager = SessionManager(project_path)
|
|
159
|
+
session_manager.show_welcome(f"agent{agent_id}")
|
|
160
|
+
else:
|
|
161
|
+
try:
|
|
162
|
+
state = state_manager.load_state()
|
|
163
|
+
agents = state.get("agents", {})
|
|
164
|
+
agent_info = agents.get(f"agent{agent_id}", {})
|
|
165
|
+
role = agent_info.get("role", "未知")
|
|
166
|
+
except Exception:
|
|
167
|
+
role = "未知"
|
|
168
|
+
click.echo(f"已切换到 Agent {agent_id} ({role})")
|
|
169
|
+
|
|
155
170
|
except Exception as e:
|
|
156
171
|
click.echo(f"错误: {e}")
|
|
157
172
|
sys.exit(1)
|
|
@@ -159,26 +174,75 @@ def switch_command(agent_id: int):
|
|
|
159
174
|
|
|
160
175
|
@main.command("review")
|
|
161
176
|
@click.argument("stage", type=click.Choice(["requirements", "design", "test"]))
|
|
177
|
+
@click.option("--file", "-f", help="指定评审文件路径")
|
|
178
|
+
@click.option("--checklist", "-c", is_flag=True, default=False, help="显示动态检查清单")
|
|
162
179
|
@click.option("--new", is_flag=True, default=False)
|
|
163
180
|
@click.option("--list", "-l", is_flag=True, default=False)
|
|
164
|
-
def review_command(stage: str, new: bool, list: bool):
|
|
181
|
+
def review_command(stage: str, file: str, checklist: bool, new: bool, list: bool):
|
|
165
182
|
"""管理评审流程。"""
|
|
166
183
|
try:
|
|
167
184
|
project_path = get_project_path()
|
|
168
185
|
state_manager = StateManager(project_path)
|
|
169
186
|
workflow_engine = WorkflowEngine(state_manager)
|
|
170
|
-
|
|
187
|
+
|
|
188
|
+
if checklist:
|
|
189
|
+
from ..core.checklist_generator import ChecklistGenerator, CheckStatus
|
|
190
|
+
|
|
191
|
+
generator = ChecklistGenerator(project_path)
|
|
192
|
+
|
|
193
|
+
if stage == "requirements":
|
|
194
|
+
if file:
|
|
195
|
+
doc_path = file
|
|
196
|
+
else:
|
|
197
|
+
req_dir = Path(project_path) / "docs" / "01-requirements"
|
|
198
|
+
doc_path = str(sorted(req_dir.glob("*.md"))[-1] if req_dir.exists() else "")
|
|
199
|
+
|
|
200
|
+
if doc_path and Path(doc_path).exists():
|
|
201
|
+
checklist_items = generator.generate_requirements_checklist(doc_path)
|
|
202
|
+
rendered = generator.render_checklist(checklist_items, f"{stage.upper()} 评审 Checklist")
|
|
203
|
+
console.print(Panel(rendered, title="动态检查清单", style="green"))
|
|
204
|
+
else:
|
|
205
|
+
click.echo("错误: 未找到需求文档")
|
|
206
|
+
|
|
207
|
+
elif stage == "design":
|
|
208
|
+
if file:
|
|
209
|
+
doc_path = file
|
|
210
|
+
else:
|
|
211
|
+
design_dir = Path(project_path) / "docs" / "02-design"
|
|
212
|
+
doc_path = str(sorted(design_dir.glob("*.md"))[-1] if design_dir.exists() else "")
|
|
213
|
+
|
|
214
|
+
if doc_path and Path(doc_path).exists():
|
|
215
|
+
checklist_items = generator.generate_design_checklist(doc_path)
|
|
216
|
+
rendered = generator.render_checklist(checklist_items, f"{stage.upper()} 评审 Checklist")
|
|
217
|
+
console.print(Panel(rendered, title="动态检查清单", style="green"))
|
|
218
|
+
else:
|
|
219
|
+
click.echo("错误: 未找到设计文档")
|
|
220
|
+
|
|
221
|
+
elif stage == "test":
|
|
222
|
+
if file:
|
|
223
|
+
doc_path = file
|
|
224
|
+
else:
|
|
225
|
+
test_dir = Path(project_path) / "docs" / "03-test"
|
|
226
|
+
doc_path = str(sorted(test_dir.glob("*.md"))[-1] if test_dir.exists() else "")
|
|
227
|
+
|
|
228
|
+
if doc_path and Path(doc_path).exists():
|
|
229
|
+
checklist_items = generator.generate_test_checklist(doc_path)
|
|
230
|
+
rendered = generator.render_checklist(checklist_items, f"{stage.upper()} 评审 Checklist")
|
|
231
|
+
console.print(Panel(rendered, title="动态检查清单", style="green"))
|
|
232
|
+
else:
|
|
233
|
+
click.echo("错误: 未找到测试文档")
|
|
234
|
+
|
|
171
235
|
if new:
|
|
172
236
|
workflow_engine.start_review(stage)
|
|
173
237
|
click.echo(f"已发起 {stage} 评审")
|
|
174
|
-
|
|
238
|
+
|
|
175
239
|
if list:
|
|
176
240
|
history = state_manager.get_history()
|
|
177
241
|
console.print(f"\n[bold]{stage.upper()} 评审历史[/bold]")
|
|
178
242
|
for item in history[:10]:
|
|
179
243
|
if "review" in item["action"] or "signoff" in item["action"]:
|
|
180
244
|
console.print(f"- {item['timestamp']}: Agent {item['agent']} - {item['details']}")
|
|
181
|
-
|
|
245
|
+
|
|
182
246
|
except Exception as e:
|
|
183
247
|
click.echo(f"错误: {e}")
|
|
184
248
|
sys.exit(1)
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Optional, List
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.panel import Panel
|
|
5
|
+
from rich.text import Text
|
|
6
|
+
|
|
7
|
+
from .state_manager import StateManager
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
AGENT_ROLES = {
|
|
12
|
+
"agent1": {
|
|
13
|
+
"role": "产品经理",
|
|
14
|
+
"responsibilities": [
|
|
15
|
+
"编写和评审需求文档",
|
|
16
|
+
"定义验收标准",
|
|
17
|
+
"签署需求确认",
|
|
18
|
+
"评审设计文档",
|
|
19
|
+
"评审测试报告"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"agent2": {
|
|
23
|
+
"role": "开发负责人",
|
|
24
|
+
"responsibilities": [
|
|
25
|
+
"评审需求文档",
|
|
26
|
+
"编写详细设计",
|
|
27
|
+
"代码实现",
|
|
28
|
+
"编写单元测试",
|
|
29
|
+
"签署技术确认"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
COMMON_COMMANDS = [
|
|
35
|
+
("oc-collab status", "查看项目状态"),
|
|
36
|
+
("oc-collab todo", "查看待办事项"),
|
|
37
|
+
("oc-collab review", "评审文档"),
|
|
38
|
+
("oc-collab signoff", "签署确认"),
|
|
39
|
+
("oc-collab history", "查看协作历史"),
|
|
40
|
+
("oc-collab switch <1|2>", "切换Agent角色")
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SessionConfig:
|
|
45
|
+
def __init__(self, project_path: str):
|
|
46
|
+
self.project_path = project_path
|
|
47
|
+
self.enabled = True
|
|
48
|
+
self.show_responsibilities = True
|
|
49
|
+
self.show_todo = True
|
|
50
|
+
self.show_pending = True
|
|
51
|
+
self.load_config()
|
|
52
|
+
|
|
53
|
+
def load_config(self):
|
|
54
|
+
state_file = Path(self.project_path) / "state" / "project_state.yaml"
|
|
55
|
+
if state_file.exists():
|
|
56
|
+
try:
|
|
57
|
+
import yaml
|
|
58
|
+
with open(state_file) as f:
|
|
59
|
+
state = yaml.safe_load(f) or {}
|
|
60
|
+
session_config = state.get("session_start", {})
|
|
61
|
+
self.enabled = session_config.get("enabled", True)
|
|
62
|
+
self.show_responsibilities = session_config.get("show_responsibilities", True)
|
|
63
|
+
self.show_todo = session_config.get("show_todo", True)
|
|
64
|
+
self.show_pending = session_config.get("show_pending", True)
|
|
65
|
+
except Exception:
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class SessionManager:
|
|
70
|
+
def __init__(self, project_path: str):
|
|
71
|
+
self.project_path = project_path
|
|
72
|
+
self.state_manager = StateManager(project_path)
|
|
73
|
+
self.config = SessionConfig(project_path)
|
|
74
|
+
|
|
75
|
+
def get_project_info(self) -> dict:
|
|
76
|
+
try:
|
|
77
|
+
state = self.state_manager.load_state()
|
|
78
|
+
metadata = state.get("metadata", {})
|
|
79
|
+
project_info = state.get("project", {})
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"name": metadata.get("project_name") or project_info.get("name", "未配置"),
|
|
83
|
+
"phase": project_info.get("phase") or state.get("phase", "未知"),
|
|
84
|
+
"milestone": state.get("current_milestone", "待定义")
|
|
85
|
+
}
|
|
86
|
+
except Exception:
|
|
87
|
+
return {"name": "未配置", "phase": "未知", "milestone": "待定义"}
|
|
88
|
+
|
|
89
|
+
def get_agent_info(self, agent_id: str) -> dict:
|
|
90
|
+
agent_config = AGENT_ROLES.get(agent_id, {
|
|
91
|
+
"role": "未知",
|
|
92
|
+
"responsibilities": []
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
state = self.state_manager.load_state()
|
|
97
|
+
agents = state.get("agents", {})
|
|
98
|
+
agent_state = agents.get(agent_id, {})
|
|
99
|
+
except KeyError:
|
|
100
|
+
agent_state = {}
|
|
101
|
+
except Exception:
|
|
102
|
+
agent_state = {}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
"id": agent_id,
|
|
106
|
+
"role": agent_config["role"],
|
|
107
|
+
"current_task": agent_state.get("current_task", ""),
|
|
108
|
+
"responsibilities": agent_config["responsibilities"]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
def get_responsibilities_text(self, agent_id: str) -> str:
|
|
112
|
+
agent = self.get_agent_info(agent_id)
|
|
113
|
+
if not self.config.show_responsibilities:
|
|
114
|
+
return ""
|
|
115
|
+
|
|
116
|
+
lines = ["你的职责:"]
|
|
117
|
+
for resp in agent["responsibilities"]:
|
|
118
|
+
lines.append(f" - {resp}")
|
|
119
|
+
return "\n".join(lines)
|
|
120
|
+
|
|
121
|
+
def get_todo_items(self) -> str:
|
|
122
|
+
if not self.config.show_todo:
|
|
123
|
+
return ""
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
from .auto_engine import TodoCommandExecutor
|
|
127
|
+
executor = TodoCommandExecutor(self.project_path)
|
|
128
|
+
todo_list = executor.get_todo_list()
|
|
129
|
+
|
|
130
|
+
if not todo_list:
|
|
131
|
+
return "待办事项:\n 暂无待办事项"
|
|
132
|
+
|
|
133
|
+
lines = ["待办事项:"]
|
|
134
|
+
for item in todo_list[:5]:
|
|
135
|
+
task = item.get("task", "")
|
|
136
|
+
lines.append(f" [ ] {task}")
|
|
137
|
+
return "\n".join(lines)
|
|
138
|
+
except Exception:
|
|
139
|
+
return "待办事项:\n 暂无待办事项"
|
|
140
|
+
|
|
141
|
+
def get_pending_issues(self) -> str:
|
|
142
|
+
if not self.config.show_pending:
|
|
143
|
+
return ""
|
|
144
|
+
|
|
145
|
+
pending_file = Path(self.project_path) / "state" / "memory" / "pending.yaml"
|
|
146
|
+
if not pending_file.exists():
|
|
147
|
+
return "上次会话遗留:\n 无遗留问题"
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
import yaml
|
|
151
|
+
with open(pending_file) as f:
|
|
152
|
+
pending = yaml.safe_load(f) or []
|
|
153
|
+
|
|
154
|
+
if not pending:
|
|
155
|
+
return "上次会话遗留:\n 无遗留问题"
|
|
156
|
+
|
|
157
|
+
lines = ["上次会话遗留:"]
|
|
158
|
+
for item in pending[:5]:
|
|
159
|
+
desc = item.get("description", item)
|
|
160
|
+
lines.append(f" - {desc}")
|
|
161
|
+
return "\n".join(lines)
|
|
162
|
+
except Exception:
|
|
163
|
+
return "上次会话遗留:\n 无遗留问题"
|
|
164
|
+
|
|
165
|
+
def get_common_commands(self) -> str:
|
|
166
|
+
lines = ["常用命令:"]
|
|
167
|
+
for cmd, desc in COMMON_COMMANDS:
|
|
168
|
+
lines.append(f" - {cmd}: {desc}")
|
|
169
|
+
return "\n".join(lines)
|
|
170
|
+
|
|
171
|
+
def get_welcome_message(self, agent_id: str) -> str:
|
|
172
|
+
if not self.config.enabled:
|
|
173
|
+
return ""
|
|
174
|
+
|
|
175
|
+
project = self.get_project_info()
|
|
176
|
+
agent = self.get_agent_info(agent_id)
|
|
177
|
+
|
|
178
|
+
parts = [
|
|
179
|
+
f"=== Agent {agent_id.replace('agent', '')} ({agent['role']}) ===",
|
|
180
|
+
"",
|
|
181
|
+
f"当前项目: {project['name']}",
|
|
182
|
+
f"当前阶段: {project['phase']}",
|
|
183
|
+
f"当前里程碑: {project['milestone']}",
|
|
184
|
+
""
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
resp_text = self.get_responsibilities_text(agent_id)
|
|
188
|
+
if resp_text:
|
|
189
|
+
parts.append(resp_text)
|
|
190
|
+
parts.append("")
|
|
191
|
+
|
|
192
|
+
todo_text = self.get_todo_items()
|
|
193
|
+
if todo_text:
|
|
194
|
+
parts.append(todo_text)
|
|
195
|
+
parts.append("")
|
|
196
|
+
|
|
197
|
+
pending_text = self.get_pending_issues()
|
|
198
|
+
if pending_text:
|
|
199
|
+
parts.append(pending_text)
|
|
200
|
+
parts.append("")
|
|
201
|
+
|
|
202
|
+
parts.append(self.get_common_commands())
|
|
203
|
+
|
|
204
|
+
return "\n".join(parts)
|
|
205
|
+
|
|
206
|
+
def show_welcome(self, agent_id: str):
|
|
207
|
+
message = self.get_welcome_message(agent_id)
|
|
208
|
+
if message:
|
|
209
|
+
console.print(Panel(
|
|
210
|
+
Text(message, justify="left"),
|
|
211
|
+
title="会话引导",
|
|
212
|
+
style="blue"
|
|
213
|
+
))
|
{opencode_collaboration-2.2.0.post1.dist-info → opencode_collaboration-2.2.0.post3.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|