@markus-global/cli 0.2.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/dist/api-client.d.ts +31 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +96 -0
- package/dist/api-client.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +224 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/approval.d.ts +3 -0
- package/dist/commands/approval.d.ts.map +1 -0
- package/dist/commands/approval.js +59 -0
- package/dist/commands/approval.js.map +1 -0
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +92 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/builder.d.ts +3 -0
- package/dist/commands/builder.d.ts.map +1 -0
- package/dist/commands/builder.js +85 -0
- package/dist/commands/builder.js.map +1 -0
- package/dist/commands/deliverable.d.ts +3 -0
- package/dist/commands/deliverable.d.ts.map +1 -0
- package/dist/commands/deliverable.js +127 -0
- package/dist/commands/deliverable.js.map +1 -0
- package/dist/commands/external-agent.d.ts +3 -0
- package/dist/commands/external-agent.d.ts.map +1 -0
- package/dist/commands/external-agent.js +74 -0
- package/dist/commands/external-agent.js.map +1 -0
- package/dist/commands/gateway.d.ts +3 -0
- package/dist/commands/gateway.d.ts.map +1 -0
- package/dist/commands/gateway.js +155 -0
- package/dist/commands/gateway.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +251 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/key.d.ts +3 -0
- package/dist/commands/key.d.ts.map +1 -0
- package/dist/commands/key.js +68 -0
- package/dist/commands/key.js.map +1 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +164 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/report.d.ts +3 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +69 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/requirement.d.ts +3 -0
- package/dist/commands/requirement.d.ts.map +1 -0
- package/dist/commands/requirement.js +197 -0
- package/dist/commands/requirement.js.map +1 -0
- package/dist/commands/review.d.ts +3 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +71 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/role.d.ts +3 -0
- package/dist/commands/role.d.ts.map +1 -0
- package/dist/commands/role.js +39 -0
- package/dist/commands/role.js.map +1 -0
- package/dist/commands/settings.d.ts +3 -0
- package/dist/commands/settings.d.ts.map +1 -0
- package/dist/commands/settings.js +53 -0
- package/dist/commands/settings.js.map +1 -0
- package/dist/commands/skill.d.ts +3 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +136 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/start.d.ts +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +628 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/system.d.ts +3 -0
- package/dist/commands/system.d.ts.map +1 -0
- package/dist/commands/system.js +248 -0
- package/dist/commands/system.js.map +1 -0
- package/dist/commands/task.d.ts +3 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +510 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/team.d.ts +3 -0
- package/dist/commands/team.d.ts.map +1 -0
- package/dist/commands/team.js +312 -0
- package/dist/commands/team.js.map +1 -0
- package/dist/commands/template.d.ts +3 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +77 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/user.d.ts +3 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +68 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/markus.mjs +82359 -0
- package/dist/output.d.ts +31 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +121 -0
- package/dist/output.js.map +1 -0
- package/dist/paths.d.ts +20 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +61 -0
- package/dist/paths.js.map +1 -0
- package/dist/web-ui/assets/index-Bcc58A3R.css +1 -0
- package/dist/web-ui/assets/index-CP5PJ1Oz.js +61 -0
- package/dist/web-ui/index.html +20 -0
- package/dist/web-ui/logo.png +0 -0
- package/package.json +37 -0
- package/templates/openclaw-markus-skill/AGENTS.md +163 -0
- package/templates/openclaw-markus-skill/TOOLS.md +155 -0
- package/templates/openclaw-markus-skill/config.json5 +44 -0
- package/templates/openclaw-markus-skill/heartbeat.md +45 -0
- package/templates/roles/SHARED.md +383 -0
- package/templates/roles/agent-father/ROLE.md +42 -0
- package/templates/roles/content-writer/ROLE.md +28 -0
- package/templates/roles/developer/HEARTBEAT.md +8 -0
- package/templates/roles/developer/POLICIES.md +31 -0
- package/templates/roles/developer/ROLE.md +23 -0
- package/templates/roles/devops/ROLE.md +28 -0
- package/templates/roles/finance/ROLE.md +16 -0
- package/templates/roles/hr/ROLE.md +17 -0
- package/templates/roles/marketing/ROLE.md +16 -0
- package/templates/roles/openclaw-developer/openclaw.md +78 -0
- package/templates/roles/operations/HEARTBEAT.md +10 -0
- package/templates/roles/operations/ROLE.md +23 -0
- package/templates/roles/org-manager/HEARTBEAT.md +12 -0
- package/templates/roles/org-manager/POLICIES.md +14 -0
- package/templates/roles/org-manager/ROLE.md +102 -0
- package/templates/roles/product-manager/HEARTBEAT.md +9 -0
- package/templates/roles/product-manager/ROLE.md +37 -0
- package/templates/roles/project-manager/ROLE.md +44 -0
- package/templates/roles/qa-engineer/ROLE.md +28 -0
- package/templates/roles/research-assistant/ROLE.md +23 -0
- package/templates/roles/reviewer/HEARTBEAT.md +13 -0
- package/templates/roles/reviewer/ROLE.md +69 -0
- package/templates/roles/secretary/HEARTBEAT.md +50 -0
- package/templates/roles/secretary/ROLE.md +148 -0
- package/templates/roles/skill-architect/ROLE.md +42 -0
- package/templates/roles/support/ROLE.md +16 -0
- package/templates/roles/team-factory/ROLE.md +54 -0
- package/templates/roles/tech-writer/ROLE.md +23 -0
- package/templates/skills/agent-building/SKILL.md +140 -0
- package/templates/skills/agent-building/skill.json +13 -0
- package/templates/skills/chrome-devtools/SKILL.md +257 -0
- package/templates/skills/chrome-devtools/skill.json +21 -0
- package/templates/skills/markus-admin-cli/SKILL.md +121 -0
- package/templates/skills/markus-admin-cli/skill.json +14 -0
- package/templates/skills/markus-agent-cli/SKILL.md +67 -0
- package/templates/skills/markus-agent-cli/skill.json +14 -0
- package/templates/skills/markus-cli/SKILL.md +113 -0
- package/templates/skills/markus-cli/skill.json +14 -0
- package/templates/skills/markus-hub-connector/SKILL.md +64 -0
- package/templates/skills/markus-hub-connector/server.mjs +321 -0
- package/templates/skills/markus-hub-connector/skill.json +20 -0
- package/templates/skills/markus-project-cli/SKILL.md +161 -0
- package/templates/skills/markus-project-cli/skill.json +14 -0
- package/templates/skills/markus-skill-cli/SKILL.md +57 -0
- package/templates/skills/markus-skill-cli/skill.json +14 -0
- package/templates/skills/markus-team-cli/SKILL.md +52 -0
- package/templates/skills/markus-team-cli/skill.json +14 -0
- package/templates/skills/self-evolution/SKILL.md +207 -0
- package/templates/skills/self-evolution/skill.json +14 -0
- package/templates/skills/skill-building/SKILL.md +172 -0
- package/templates/skills/skill-building/skill.json +13 -0
- package/templates/skills/team-building/SKILL.md +159 -0
- package/templates/skills/team-building/skill.json +13 -0
- package/templates/teams/content-team/ANNOUNCEMENT.md +10 -0
- package/templates/teams/content-team/NORMS.md +20 -0
- package/templates/teams/content-team/team.json +18 -0
- package/templates/teams/dev-squad/ANNOUNCEMENT.md +11 -0
- package/templates/teams/dev-squad/NORMS.md +22 -0
- package/templates/teams/dev-squad/team.json +19 -0
- package/templates/teams/startup-team/ANNOUNCEMENT.md +11 -0
- package/templates/teams/startup-team/NORMS.md +21 -0
- package/templates/teams/startup-team/team.json +20 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chrome-devtools
|
|
3
|
+
description: Chrome DevTools browser automation via MCP - control a live Chrome browser
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chrome DevTools Browser Automation
|
|
7
|
+
|
|
8
|
+
You have access to a live Chrome browser via Chrome DevTools MCP tools (prefixed `chrome-devtools__`).
|
|
9
|
+
This gives you full browser automation: navigation, clicking, typing, screenshots, JS evaluation,
|
|
10
|
+
network inspection, and performance profiling.
|
|
11
|
+
|
|
12
|
+
## When to use these tools
|
|
13
|
+
|
|
14
|
+
Use Chrome DevTools tools when you need to:
|
|
15
|
+
- Interact with web pages (click buttons, fill forms, navigate)
|
|
16
|
+
- Test web applications in a real browser
|
|
17
|
+
- Take screenshots of pages or elements
|
|
18
|
+
- Inspect console logs, network requests, or page structure
|
|
19
|
+
- Run Lighthouse audits or performance traces
|
|
20
|
+
- Debug frontend issues with live DOM inspection
|
|
21
|
+
|
|
22
|
+
Do NOT use these tools when `web_fetch` or `web_search` suffice (simple content retrieval or search).
|
|
23
|
+
Chrome DevTools is for interactive browser sessions that require a real rendering engine.
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
|
|
27
|
+
The MCP server connects to the user's running Chrome via `--autoConnect` (Chrome 144+).
|
|
28
|
+
|
|
29
|
+
**Setup steps:**
|
|
30
|
+
1. Chrome version must be 144 or newer (146+ recommended).
|
|
31
|
+
2. Open `chrome://inspect/#remote-debugging` in Chrome and enable remote debugging.
|
|
32
|
+
3. On first MCP connection, Chrome will show a permission dialog — the user must click **Allow**.
|
|
33
|
+
|
|
34
|
+
**Known limitation — frozen/suspended tabs cause connection timeout:**
|
|
35
|
+
|
|
36
|
+
When Chrome has frozen or suspended tabs (common with Memory Saver or "Continue where you left off"),
|
|
37
|
+
the MCP server may hang on the first tool call. This is a known upstream issue
|
|
38
|
+
(puppeteer [#12808](https://github.com/puppeteer/puppeteer/issues/12808),
|
|
39
|
+
chrome-devtools-mcp [#775](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/775)).
|
|
40
|
+
|
|
41
|
+
If you encounter a tool call timeout, inform the user and suggest these steps (in order):
|
|
42
|
+
1. **Upgrade Chrome to 146+** — contains a partial fix for frozen tab handling.
|
|
43
|
+
2. **Disable Memory Saver** — go to `chrome://settings/performance` and turn off "Memory Saver"
|
|
44
|
+
so Chrome stops freezing inactive tabs.
|
|
45
|
+
3. **Activate suspended tabs** — click on each unloaded tab to wake it up, especially tabs
|
|
46
|
+
restored after a Chrome restart.
|
|
47
|
+
4. **Use a dedicated Chrome profile** — create a clean profile with few tabs for development use,
|
|
48
|
+
reducing the chance of frozen targets blocking the connection.
|
|
49
|
+
|
|
50
|
+
## Tool reference
|
|
51
|
+
|
|
52
|
+
### Navigation (6 tools)
|
|
53
|
+
|
|
54
|
+
| Tool | Purpose |
|
|
55
|
+
|------|---------|
|
|
56
|
+
| `chrome-devtools__navigate_page` | Navigate to a URL |
|
|
57
|
+
| `chrome-devtools__list_pages` | List all open tabs/pages |
|
|
58
|
+
| `chrome-devtools__new_page` | Open a new tab |
|
|
59
|
+
| `chrome-devtools__close_page` | Close a tab |
|
|
60
|
+
| `chrome-devtools__select_page` | Switch to a specific tab |
|
|
61
|
+
| `chrome-devtools__wait_for` | Wait for selector, navigation, or network idle |
|
|
62
|
+
|
|
63
|
+
### Input (9 tools)
|
|
64
|
+
|
|
65
|
+
| Tool | Purpose |
|
|
66
|
+
|------|---------|
|
|
67
|
+
| `chrome-devtools__click` | Click an element by selector |
|
|
68
|
+
| `chrome-devtools__fill` | Clear and fill a form field (preferred over type_text) |
|
|
69
|
+
| `chrome-devtools__fill_form` | Fill multiple form fields at once |
|
|
70
|
+
| `chrome-devtools__type_text` | Type text character by character (use for contenteditable) |
|
|
71
|
+
| `chrome-devtools__press_key` | Press keyboard keys (Enter, Tab, Escape, etc.) |
|
|
72
|
+
| `chrome-devtools__hover` | Hover over an element |
|
|
73
|
+
| `chrome-devtools__drag` | Drag from one element to another |
|
|
74
|
+
| `chrome-devtools__handle_dialog` | Accept or dismiss browser dialogs (alert/confirm/prompt) |
|
|
75
|
+
| `chrome-devtools__upload_file` | Upload a file to a file input element |
|
|
76
|
+
|
|
77
|
+
### Inspection (6 tools)
|
|
78
|
+
|
|
79
|
+
| Tool | Purpose |
|
|
80
|
+
|------|---------|
|
|
81
|
+
| `chrome-devtools__take_screenshot` | Capture screenshot (full page or viewport) |
|
|
82
|
+
| `chrome-devtools__take_snapshot` | Get page accessibility tree (best for finding elements) |
|
|
83
|
+
| `chrome-devtools__evaluate_script` | Execute JavaScript in the page context |
|
|
84
|
+
| `chrome-devtools__get_console_message` | Get a specific console message |
|
|
85
|
+
| `chrome-devtools__list_console_messages` | List recent console messages |
|
|
86
|
+
| `chrome-devtools__lighthouse_audit` | Run a Lighthouse audit |
|
|
87
|
+
|
|
88
|
+
### Network (2 tools)
|
|
89
|
+
|
|
90
|
+
| Tool | Purpose |
|
|
91
|
+
|------|---------|
|
|
92
|
+
| `chrome-devtools__list_network_requests` | List captured network requests |
|
|
93
|
+
| `chrome-devtools__get_network_request` | Get details of a specific request |
|
|
94
|
+
|
|
95
|
+
### Performance (4 tools)
|
|
96
|
+
|
|
97
|
+
| Tool | Purpose |
|
|
98
|
+
|------|---------|
|
|
99
|
+
| `chrome-devtools__performance_start_trace` | Start a performance trace |
|
|
100
|
+
| `chrome-devtools__performance_stop_trace` | Stop trace and get results |
|
|
101
|
+
| `chrome-devtools__performance_analyze_insight` | Analyze performance data |
|
|
102
|
+
| `chrome-devtools__take_memory_snapshot` | Capture heap snapshot |
|
|
103
|
+
|
|
104
|
+
### Emulation (2 tools)
|
|
105
|
+
|
|
106
|
+
| Tool | Purpose |
|
|
107
|
+
|------|---------|
|
|
108
|
+
| `chrome-devtools__emulate` | Emulate device (mobile, tablet) |
|
|
109
|
+
| `chrome-devtools__resize_page` | Resize browser viewport |
|
|
110
|
+
|
|
111
|
+
## Best practices
|
|
112
|
+
|
|
113
|
+
1. **Always open your own tab first**: Call `new_page` before any browser interaction.
|
|
114
|
+
Never reuse existing tabs — they may belong to the user or another agent.
|
|
115
|
+
|
|
116
|
+
2. **Snapshot before interaction**: Always call `take_snapshot` before clicking or filling.
|
|
117
|
+
The snapshot returns the accessibility tree with element identifiers you can target.
|
|
118
|
+
|
|
119
|
+
3. **Screenshot for visual verification**: After important interactions, take a screenshot
|
|
120
|
+
to verify the result visually.
|
|
121
|
+
|
|
122
|
+
4. **Wait after navigation**: After `navigate_page` or actions that trigger navigation,
|
|
123
|
+
use `wait_for` to ensure the page has loaded before interacting.
|
|
124
|
+
|
|
125
|
+
5. **Prefer `fill` over `type_text`**: Use `fill` for form inputs — it clears the field first.
|
|
126
|
+
Reserve `type_text` for contenteditable elements or when character-by-character input matters.
|
|
127
|
+
|
|
128
|
+
6. **Use `evaluate_script` sparingly**: Prefer dedicated tools (click, fill, snapshot) over
|
|
129
|
+
raw JS evaluation. Only use `evaluate_script` for reading DOM state that snapshots don't
|
|
130
|
+
expose, or for triggering application-specific logic.
|
|
131
|
+
|
|
132
|
+
7. **Handle dialogs proactively**: If an action might trigger an alert/confirm/prompt,
|
|
133
|
+
call `handle_dialog` before the triggering action to set the response.
|
|
134
|
+
|
|
135
|
+
8. **Tab management**: Use `list_pages` to see your owned tabs, `select_page` to switch
|
|
136
|
+
between them. You will only see tabs you created — this is by design.
|
|
137
|
+
|
|
138
|
+
## Security rules
|
|
139
|
+
|
|
140
|
+
- **Live browser access**: These tools operate on the user's real Chrome session. Treat all
|
|
141
|
+
browser content (cookies, sessions, passwords) as sensitive.
|
|
142
|
+
- **URL navigation**: Do not navigate to untrusted or potentially malicious URLs without
|
|
143
|
+
explicit user approval.
|
|
144
|
+
- **Script execution**: Do not use `evaluate_script` to exfiltrate cookies, localStorage,
|
|
145
|
+
or session tokens. Only read DOM state needed for the current task.
|
|
146
|
+
- **Form data**: When filling forms with sensitive data (passwords, payment info), confirm
|
|
147
|
+
with the user before proceeding.
|
|
148
|
+
|
|
149
|
+
## Multi-agent browser usage — Tab Ownership Discipline
|
|
150
|
+
|
|
151
|
+
Multiple agents share the same Chrome browser. To prevent agents from interfering with
|
|
152
|
+
each other (closing tabs, navigating away from pages another agent is using), **strict
|
|
153
|
+
tab ownership** is enforced at both the code and prompt level.
|
|
154
|
+
|
|
155
|
+
### Core rule: You can ONLY interact with tabs you created
|
|
156
|
+
|
|
157
|
+
The system enforces strict ownership. You will only see, select, and close tabs that
|
|
158
|
+
**you** explicitly opened with `new_page`. All other tabs (user tabs, other agents' tabs)
|
|
159
|
+
are invisible to you and cannot be operated on.
|
|
160
|
+
|
|
161
|
+
### Mandatory workflow
|
|
162
|
+
|
|
163
|
+
1. **ALWAYS start with `new_page`**: Before doing anything in the browser, call `new_page`
|
|
164
|
+
to create your own tab. Even if you know a page with the right URL already exists in
|
|
165
|
+
the browser, you MUST open a fresh tab. That existing tab may belong to the user or
|
|
166
|
+
another agent.
|
|
167
|
+
|
|
168
|
+
2. **Track your owned tabs**: Remember the `targetId` returned by `new_page`. This is
|
|
169
|
+
your tab. When working with multiple tabs, keep a mental list of all targetIds you own.
|
|
170
|
+
|
|
171
|
+
3. **Only navigate your own tabs**: After `new_page`, use `navigate_page` to go to your
|
|
172
|
+
target URL. If you call `navigate_page` without first creating a tab with `new_page`,
|
|
173
|
+
the call will be blocked.
|
|
174
|
+
|
|
175
|
+
4. **Only close your own tabs**: When your task is done, close tabs you opened with
|
|
176
|
+
`close_page`. Never attempt to close tabs you did not create — the system will
|
|
177
|
+
reject the call.
|
|
178
|
+
|
|
179
|
+
5. **Never reuse existing tabs**: Even if `list_pages` shows a tab at the URL you need,
|
|
180
|
+
open a new one. That tab may be actively used by another agent or the user.
|
|
181
|
+
|
|
182
|
+
### What the system enforces (code-level)
|
|
183
|
+
|
|
184
|
+
| Tool | Enforcement |
|
|
185
|
+
|------|-------------|
|
|
186
|
+
| `new_page` | Creates a tab and registers it as yours |
|
|
187
|
+
| `list_pages` | Only returns tabs you created (all others are hidden) |
|
|
188
|
+
| `select_page` | Blocked unless the target tab is one you created |
|
|
189
|
+
| `close_page` | Blocked unless the target tab is one you created |
|
|
190
|
+
| `navigate_page` | Blocked if you have no owned tabs (must call `new_page` first) |
|
|
191
|
+
|
|
192
|
+
### Shared state warning
|
|
193
|
+
|
|
194
|
+
- **Cookies and login sessions are shared** across all agents (same Chrome instance).
|
|
195
|
+
If one agent logs out of a site, other agents lose that session too.
|
|
196
|
+
- Avoid actions that affect global browser state (clearing cookies, changing Chrome
|
|
197
|
+
settings, closing all tabs) unless the task explicitly requires it.
|
|
198
|
+
|
|
199
|
+
### Example: correct multi-agent workflow
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
Agent A: Agent B:
|
|
203
|
+
1. new_page → gets tab T1 1. new_page → gets tab T2
|
|
204
|
+
2. navigate_page T1 → localhost:3000 2. navigate_page T2 → localhost:3000
|
|
205
|
+
3. (test feature X on T1) 3. (test feature Y on T2)
|
|
206
|
+
4. close_page T1 4. close_page T2
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Both agents work on the same URL but in separate tabs without interference.
|
|
210
|
+
|
|
211
|
+
## Common workflows
|
|
212
|
+
|
|
213
|
+
### Web testing
|
|
214
|
+
```
|
|
215
|
+
1. new_page → create your own tab (remember targetId)
|
|
216
|
+
2. navigate_page → target URL
|
|
217
|
+
3. wait_for → page loaded
|
|
218
|
+
4. take_snapshot → understand page structure
|
|
219
|
+
5. click / fill / press_key → interact with elements
|
|
220
|
+
6. take_screenshot → verify result
|
|
221
|
+
7. close_page → clean up when done
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Form automation
|
|
225
|
+
```
|
|
226
|
+
1. new_page → create your own tab
|
|
227
|
+
2. navigate_page → form URL
|
|
228
|
+
3. take_snapshot → identify form fields
|
|
229
|
+
4. fill_form → fill all fields at once
|
|
230
|
+
5. click → submit button
|
|
231
|
+
6. wait_for → response/redirect
|
|
232
|
+
7. take_screenshot → confirm submission
|
|
233
|
+
8. close_page → clean up when done
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Debugging frontend issues
|
|
237
|
+
```
|
|
238
|
+
1. new_page → create your own tab
|
|
239
|
+
2. navigate_page → problematic page
|
|
240
|
+
3. list_console_messages → check for errors
|
|
241
|
+
4. list_network_requests → check for failed requests
|
|
242
|
+
5. evaluate_script → inspect specific DOM state
|
|
243
|
+
6. take_screenshot → capture visual state
|
|
244
|
+
7. close_page → clean up when done
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Performance analysis
|
|
248
|
+
```
|
|
249
|
+
1. new_page → create your own tab
|
|
250
|
+
2. navigate_page → target page
|
|
251
|
+
3. performance_start_trace
|
|
252
|
+
4. (perform user actions that need profiling)
|
|
253
|
+
5. performance_stop_trace → get trace data
|
|
254
|
+
6. performance_analyze_insight → interpret results
|
|
255
|
+
7. lighthouse_audit → comprehensive audit
|
|
256
|
+
8. close_page → clean up when done
|
|
257
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "skill",
|
|
3
|
+
"name": "chrome-devtools",
|
|
4
|
+
"displayName": "Chrome DevTools",
|
|
5
|
+
"version": "1.0.1",
|
|
6
|
+
"description": "Chrome DevTools browser automation - control a live Chrome browser (navigate, click, type, screenshot, evaluate JS, inspect network, performance profiling)",
|
|
7
|
+
"author": "markus",
|
|
8
|
+
"category": "browser",
|
|
9
|
+
"tags": ["browser", "chrome", "devtools", "automation", "testing", "mcp"],
|
|
10
|
+
"skill": {
|
|
11
|
+
"skillFile": "SKILL.md",
|
|
12
|
+
"requiredPermissions": ["browser", "network"],
|
|
13
|
+
"isolation": "per-agent",
|
|
14
|
+
"mcpServers": {
|
|
15
|
+
"chrome-devtools": {
|
|
16
|
+
"command": "npx",
|
|
17
|
+
"args": ["-y", "chrome-devtools-mcp@latest", "--autoConnect"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markus-admin-cli
|
|
3
|
+
description: System administration via markus CLI — system controls, audit, users, settings, gateway.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# System Administration via CLI
|
|
7
|
+
|
|
8
|
+
Administrative operations through `shell_execute` with `markus admin` commands. Always use `--json` for parseable output.
|
|
9
|
+
|
|
10
|
+
## System Controls
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
markus admin system status --json
|
|
14
|
+
markus admin system version --json
|
|
15
|
+
markus admin system update
|
|
16
|
+
markus admin system update --dry-run
|
|
17
|
+
markus admin system pause-all --reason "Deploying updates"
|
|
18
|
+
markus admin system resume-all
|
|
19
|
+
markus admin system emergency-stop
|
|
20
|
+
markus admin system storage --json
|
|
21
|
+
markus admin system orphans --json
|
|
22
|
+
markus admin system announce --title "Maintenance" --content "Downtime at 2am" --priority high
|
|
23
|
+
markus admin system policy --json
|
|
24
|
+
markus admin system policy --set --body '{"defaultApproval":"manager"}'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Command | Key Options |
|
|
28
|
+
|---------|-------------|
|
|
29
|
+
| `admin system status` | |
|
|
30
|
+
| `admin system version` | Shows current version, git info, and whether updates are available |
|
|
31
|
+
| `admin system update` | `--dry-run` (preview without applying). Pulls latest code, installs deps, rebuilds |
|
|
32
|
+
| `admin system pause-all` | `--reason` |
|
|
33
|
+
| `admin system resume-all` | |
|
|
34
|
+
| `admin system emergency-stop` | |
|
|
35
|
+
| `admin system storage` | |
|
|
36
|
+
| `admin system orphans` | |
|
|
37
|
+
| `admin system announce` | `--title` `--content` `--priority` `--type` `--expires-at` |
|
|
38
|
+
| `admin system policy` | `--set <json>` (update mode) |
|
|
39
|
+
|
|
40
|
+
**Update workflow**: When updating the platform, always: (1) confirm with the user, (2) pause all agents first (`pause-all`), (3) run `update`, (4) restart the service (`markus start`), (5) resume agents (`resume-all`).
|
|
41
|
+
|
|
42
|
+
## Audit (nested under admin system)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
markus admin system audit log --json --limit 50
|
|
46
|
+
markus admin system audit log --type llm_request --agent-id agt_xxx
|
|
47
|
+
markus admin system audit summary --json
|
|
48
|
+
markus admin system audit tokens --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Users
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
markus admin user list --json
|
|
55
|
+
markus admin user add --name "John" --role admin --email john@example.com
|
|
56
|
+
markus admin user delete usr_xxx
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Keys
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
markus admin key list --json
|
|
63
|
+
markus admin key create --name "CI Key"
|
|
64
|
+
markus admin key delete key_xxx
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Roles
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
markus admin role list --json
|
|
71
|
+
markus admin role get developer --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Templates
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
markus admin template list --json
|
|
78
|
+
markus admin template get Developer --json
|
|
79
|
+
markus admin template instantiate --template-id Developer --name "New Agent" --org-id default
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Builder Artifacts
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
markus admin builder list --json
|
|
86
|
+
markus admin builder get agent my-agent --json
|
|
87
|
+
markus admin builder install agent my-agent
|
|
88
|
+
markus admin builder uninstall agent my-agent
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Settings
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
markus admin settings llm --json
|
|
95
|
+
markus admin settings env-models --json
|
|
96
|
+
markus admin settings oauth-status --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Gateway (External Agent Access)
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
markus admin gateway info --json
|
|
103
|
+
markus admin gateway register --agent-id ext_001 --agent-name "CI Bot" --org default
|
|
104
|
+
markus admin gateway auth --agent-id ext_001 --org default --secret <secret>
|
|
105
|
+
markus admin gateway message --text "Status update" --token <bearer-token>
|
|
106
|
+
markus admin gateway status --token <bearer-token>
|
|
107
|
+
markus admin gateway manual --token <bearer-token>
|
|
108
|
+
markus admin gateway team --token <bearer-token>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## External Agents
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
markus admin external-agent list --json
|
|
115
|
+
markus admin external-agent register --name "CI Bot" --type ci
|
|
116
|
+
markus admin external-agent delete ext_xxx
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Permissions Note
|
|
120
|
+
|
|
121
|
+
Most admin commands require owner or admin role. Agent-level operations require the agent to be part of your organization.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "skill",
|
|
3
|
+
"name": "markus-admin-cli",
|
|
4
|
+
"displayName": "Markus Admin CLI",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "System administration via markus CLI — system controls, audit, users, settings, gateway.",
|
|
7
|
+
"author": "markus",
|
|
8
|
+
"category": "platform",
|
|
9
|
+
"tags": ["cli", "admin", "governance", "audit", "settings"],
|
|
10
|
+
"skill": {
|
|
11
|
+
"skillFile": "SKILL.md",
|
|
12
|
+
"alwaysOn": false
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markus-agent-cli
|
|
3
|
+
description: Manage agents via markus CLI — lifecycle, messaging, config, memory, skills.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent Management via CLI
|
|
7
|
+
|
|
8
|
+
Operate agents through `shell_execute` with `markus agent` commands. Always use `--json` for parseable output.
|
|
9
|
+
|
|
10
|
+
## Quick examples
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# List all agents
|
|
14
|
+
markus agent list --json
|
|
15
|
+
|
|
16
|
+
# Get agent details
|
|
17
|
+
markus agent get agt_xxx --json
|
|
18
|
+
|
|
19
|
+
# Create an agent
|
|
20
|
+
markus agent create --name "Alice" --role developer --team team_xxx
|
|
21
|
+
|
|
22
|
+
# Start / stop agents
|
|
23
|
+
markus agent start agt_xxx
|
|
24
|
+
markus agent stop agt_xxx
|
|
25
|
+
|
|
26
|
+
# Send a message
|
|
27
|
+
markus agent message agt_xxx --text "Please review the API changes"
|
|
28
|
+
|
|
29
|
+
# Update config
|
|
30
|
+
markus agent config agt_xxx --skills "self-evolution,chrome-devtools"
|
|
31
|
+
|
|
32
|
+
# View memory
|
|
33
|
+
markus agent memory agt_xxx --json
|
|
34
|
+
|
|
35
|
+
# Manage skills
|
|
36
|
+
markus agent skill-add agt_xxx --skill-name chrome-devtools
|
|
37
|
+
markus agent skill-remove agt_xxx --skill-name chrome-devtools
|
|
38
|
+
|
|
39
|
+
# Trigger heartbeat or daily report
|
|
40
|
+
markus agent heartbeat agt_xxx
|
|
41
|
+
markus agent daily-report agt_xxx
|
|
42
|
+
|
|
43
|
+
# Sync role from template
|
|
44
|
+
markus agent role-sync agt_xxx
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Command Reference
|
|
48
|
+
|
|
49
|
+
| Command | Key Options |
|
|
50
|
+
|---------|-------------|
|
|
51
|
+
| `agent list` | |
|
|
52
|
+
| `agent get <id>` | |
|
|
53
|
+
| `agent create` | `--name` (required) `--role` (required) `--org` `--team` `--agent-role` `--skills` |
|
|
54
|
+
| `agent delete <id>` | `--purge` |
|
|
55
|
+
| `agent start <id>` | |
|
|
56
|
+
| `agent stop <id>` | |
|
|
57
|
+
| `agent message <id>` | `--text` (required) `--sender` `--session` |
|
|
58
|
+
| `agent chat <id>` | Interactive REPL mode |
|
|
59
|
+
| `agent config <id>` | `--name` `--agent-role` `--skills` `--heartbeat` |
|
|
60
|
+
| `agent memory <id>` | |
|
|
61
|
+
| `agent files <id>` | |
|
|
62
|
+
| `agent skill-add <id>` | `--skill-name` (required) |
|
|
63
|
+
| `agent skill-remove <id>` | `--skill-name` (required) |
|
|
64
|
+
| `agent activities <id>` | `--type` `--limit` |
|
|
65
|
+
| `agent heartbeat <id>` | |
|
|
66
|
+
| `agent daily-report <id>` | |
|
|
67
|
+
| `agent role-sync <id>` | |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "skill",
|
|
3
|
+
"name": "markus-agent-cli",
|
|
4
|
+
"displayName": "Markus Agent CLI",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Manage agents via markus CLI — lifecycle, messaging, config, memory, skills.",
|
|
7
|
+
"author": "markus",
|
|
8
|
+
"category": "platform",
|
|
9
|
+
"tags": ["cli", "agents", "lifecycle"],
|
|
10
|
+
"skill": {
|
|
11
|
+
"skillFile": "SKILL.md",
|
|
12
|
+
"alwaysOn": false
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markus-cli
|
|
3
|
+
description: Core knowledge for operating the Markus platform via CLI. Prerequisite for domain-specific markus-*-cli skills.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Markus CLI
|
|
7
|
+
|
|
8
|
+
The `markus` command-line tool lets you operate the Markus platform programmatically.
|
|
9
|
+
Use it via `shell_execute` to manage agents, projects, tasks, teams, and more.
|
|
10
|
+
|
|
11
|
+
## How to invoke
|
|
12
|
+
|
|
13
|
+
Use `markus` via `shell_execute`. The binary is automatically available in PATH — either from npm global install (`npm install -g @markus-global/cli`) or injected by the server at startup in source-dev mode.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
markus agent list --json
|
|
17
|
+
markus project task get tsk_abc123 --json
|
|
18
|
+
markus admin system status --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
- The Markus server must be running (started via `markus start`).
|
|
24
|
+
- `markus start` auto-detects first run and initializes everything (DB, config wizard).
|
|
25
|
+
- The CLI connects to `http://localhost:8056` by default. Override with `--server <url>` or `MARKUS_API_URL`.
|
|
26
|
+
- For authenticated access use `--api-key <key>` or `MARKUS_API_KEY`.
|
|
27
|
+
|
|
28
|
+
## Output format
|
|
29
|
+
|
|
30
|
+
**Always use `--json` when parsing results programmatically.** Without `--json`, output is human-readable tables.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Machine-readable — use this in automation
|
|
34
|
+
markus agent list --json
|
|
35
|
+
|
|
36
|
+
# Human-readable table
|
|
37
|
+
markus agent list
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Platform Info
|
|
41
|
+
|
|
42
|
+
- **Website**: https://www.markus.global/
|
|
43
|
+
- **GitHub**: https://github.com/markus-global/markus
|
|
44
|
+
|
|
45
|
+
## Command structure
|
|
46
|
+
|
|
47
|
+
Commands follow the pattern: `markus <domain> [sub] <action> [id] [options]`
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
markus agent list # List agents
|
|
51
|
+
markus project list --json # List projects
|
|
52
|
+
markus project task create --title "..." # Create a task
|
|
53
|
+
markus admin system status # System health
|
|
54
|
+
markus admin system version --json # Check version and updates
|
|
55
|
+
markus <domain> --help # See all subcommands
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Command hierarchy
|
|
59
|
+
|
|
60
|
+
| Command | Description | Skill |
|
|
61
|
+
|---------|-------------|-------|
|
|
62
|
+
| `start` | Start server (auto-init on first run) | — |
|
|
63
|
+
| `agent` | Agent lifecycle, config, memory, skills | markus-agent-cli |
|
|
64
|
+
| `team` | Team CRUD, members, lifecycle | markus-team-cli |
|
|
65
|
+
| `skill` | Skill registry, install, scaffold | markus-skill-cli |
|
|
66
|
+
| `project` | Project CRUD | markus-project-cli |
|
|
67
|
+
| `project task` | Task CRUD, lifecycle, subtasks, comments | markus-project-cli |
|
|
68
|
+
| `project requirement` | Requirement CRUD, approval | markus-project-cli |
|
|
69
|
+
| `project deliverable` | Deliverable CRUD | markus-project-cli |
|
|
70
|
+
| `project report` | Report generation, usage stats | markus-project-cli |
|
|
71
|
+
| `project review` | Code / task reviews | markus-project-cli |
|
|
72
|
+
| `project approval` | HITL approvals | markus-project-cli |
|
|
73
|
+
| `admin` | Platform administration & system controls | markus-admin-cli |
|
|
74
|
+
| `admin system` | Global controls, governance, storage, version, update | markus-admin-cli |
|
|
75
|
+
| `admin system audit` | Audit log and summary | markus-admin-cli |
|
|
76
|
+
| `admin user` | Human user management | markus-admin-cli |
|
|
77
|
+
| `admin key` | API key management | markus-admin-cli |
|
|
78
|
+
| `admin role` | Role templates | markus-admin-cli |
|
|
79
|
+
| `admin template` | Agent/team templates | markus-admin-cli |
|
|
80
|
+
| `admin builder` | Builder artifacts | markus-admin-cli |
|
|
81
|
+
| `admin gateway` | External agent gateway | markus-admin-cli |
|
|
82
|
+
| `admin settings` | LLM and platform settings | markus-admin-cli |
|
|
83
|
+
| `admin external-agent` | External agent registration | markus-admin-cli |
|
|
84
|
+
|
|
85
|
+
## Installation & Update
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Install via npm (recommended)
|
|
89
|
+
npm install -g @markus-global/cli
|
|
90
|
+
|
|
91
|
+
# Or one-line install
|
|
92
|
+
curl -fsSL https://markus.global/install.sh | bash
|
|
93
|
+
|
|
94
|
+
# Check current version
|
|
95
|
+
markus admin system version --json
|
|
96
|
+
|
|
97
|
+
# Update to latest (npm mode)
|
|
98
|
+
npm update -g @markus-global/cli
|
|
99
|
+
|
|
100
|
+
# Update to latest (source mode — pulls from GitHub, installs deps, rebuilds)
|
|
101
|
+
markus admin system update
|
|
102
|
+
|
|
103
|
+
# Preview update without making changes
|
|
104
|
+
markus admin system update --dry-run
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Always confirm with the user before updating** — it requires a service restart which interrupts running agents.
|
|
108
|
+
|
|
109
|
+
## Tips
|
|
110
|
+
|
|
111
|
+
- Always use `--json` and parse the JSON output for reliable automation.
|
|
112
|
+
- When creating tasks, always specify `--project-id` if projects exist.
|
|
113
|
+
- Use `markus <domain> --help` to discover available subcommands and options.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "skill",
|
|
3
|
+
"name": "markus-cli",
|
|
4
|
+
"displayName": "Markus CLI",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Core knowledge for operating the Markus platform via CLI commands. Prerequisite for all markus-*-cli skills.",
|
|
7
|
+
"author": "markus",
|
|
8
|
+
"category": "platform",
|
|
9
|
+
"tags": ["cli", "platform", "management", "api"],
|
|
10
|
+
"skill": {
|
|
11
|
+
"skillFile": "SKILL.md",
|
|
12
|
+
"alwaysOn": false
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: markus-hub-connector
|
|
3
|
+
description: Search, download, and publish agents/teams/skills on Markus Hub
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Markus Hub Connector
|
|
7
|
+
|
|
8
|
+
You have access to the Markus Hub community marketplace via MCP tools (prefixed `markus-hub__`).
|
|
9
|
+
This lets you search for shared packages, download them locally, publish user creations, and manage published items.
|
|
10
|
+
|
|
11
|
+
## When to use these tools
|
|
12
|
+
|
|
13
|
+
Use Hub tools when the user wants to:
|
|
14
|
+
- Find agents, teams, or skills shared by the community
|
|
15
|
+
- Download a package from Hub to try locally
|
|
16
|
+
- Share/publish a builder artifact to Hub
|
|
17
|
+
- Check what they've published on Hub
|
|
18
|
+
|
|
19
|
+
Do NOT use these tools for local skill/agent management — those are separate operations.
|
|
20
|
+
|
|
21
|
+
## Authentication
|
|
22
|
+
|
|
23
|
+
Hub operations that modify data (download, publish, my_items) require the user to be logged in to Markus Hub via the web UI. If a tool returns an authentication error, tell the user to log in to Hub from the Markus web interface first.
|
|
24
|
+
|
|
25
|
+
The login state is synced automatically — no manual token setup is needed.
|
|
26
|
+
|
|
27
|
+
## Tool reference
|
|
28
|
+
|
|
29
|
+
| Tool | Purpose | Auth required |
|
|
30
|
+
|------|---------|:---:|
|
|
31
|
+
| `markus-hub__hub_search` | Search Hub for packages by keyword, type, category | No |
|
|
32
|
+
| `markus-hub__hub_download` | Download a package to local builder-artifacts | Yes |
|
|
33
|
+
| `markus-hub__hub_publish` | Publish a local artifact to Hub | Yes |
|
|
34
|
+
| `markus-hub__hub_my_items` | List the user's published items | Yes |
|
|
35
|
+
|
|
36
|
+
## Common workflows
|
|
37
|
+
|
|
38
|
+
### Finding and downloading a skill
|
|
39
|
+
```
|
|
40
|
+
1. markus-hub__hub_search → query="code review", type="skill"
|
|
41
|
+
2. Review results, confirm with user which one to download
|
|
42
|
+
3. markus-hub__hub_download → id="<item_id>"
|
|
43
|
+
4. Tell user to install from Builder page
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Publishing a builder artifact
|
|
47
|
+
```
|
|
48
|
+
1. markus-hub__hub_publish → directory="~/.markus/builder-artifacts/skills/my-skill"
|
|
49
|
+
(auto-reads manifest + files from directory)
|
|
50
|
+
2. Share the Hub URL with the user
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Checking published items
|
|
54
|
+
```
|
|
55
|
+
1. markus-hub__hub_my_items → see all published packages
|
|
56
|
+
2. Report status to user
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Best practices
|
|
60
|
+
|
|
61
|
+
1. **Always confirm before publishing**: Show the user what will be published (name, description, files) before calling `hub_publish`.
|
|
62
|
+
2. **Use directory mode for publish**: When publishing a local artifact, pass the `directory` parameter — it auto-reads the manifest and all files.
|
|
63
|
+
3. **Guide on auth errors**: If a tool returns an auth error, tell the user to log in via the Hub icon in the Markus web UI.
|
|
64
|
+
4. **Search before download**: Help the user find the right package before downloading.
|