superacli 1.1.2 → 1.1.4
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/LICENSE +22 -0
- package/README.md +10 -1
- package/__tests__/blogwatcher-plugin.test.js +157 -0
- package/__tests__/clix-plugin.test.js +143 -0
- package/__tests__/config.test.js +46 -1
- package/__tests__/himalaya-plugin.test.js +121 -0
- package/__tests__/mcp-adapter.test.js +79 -0
- package/__tests__/mcp-local.test.js +43 -1
- package/__tests__/mongosh-plugin.test.js +106 -0
- package/__tests__/mysql-plugin.test.js +94 -0
- package/__tests__/plugin-blogwatcher.test.js +55 -0
- package/__tests__/plugin-clix.test.js +51 -0
- package/__tests__/plugin-xurl.test.js +51 -0
- package/__tests__/server-config-service.test.js +8 -1
- package/__tests__/skills.test.js +26 -0
- package/__tests__/wacli-plugin.test.js +132 -0
- package/__tests__/xurl-plugin.test.js +176 -0
- package/cli/adapter-schema.js +7 -0
- package/cli/adapters/mcp.js +82 -20
- package/cli/config.js +65 -8
- package/cli/mcp-local.js +50 -4
- package/cli/plugin-install-guidance.js +100 -0
- package/cli/skills.js +55 -0
- package/cli/supercli.js +1 -1
- package/docs/features/adapters.md +6 -2
- package/docs/initial/mcp-local-mode.md +3 -0
- package/docs/skills-catalog.md +50 -0
- package/docs/supported-harnesses.md +20 -0
- package/package.json +2 -1
- package/plugins/blogwatcher/README.md +52 -0
- package/plugins/blogwatcher/plugin.json +195 -0
- package/plugins/blogwatcher/scripts/post-install.js +66 -0
- package/plugins/blogwatcher/scripts/post-uninstall.js +25 -0
- package/plugins/clix/README.md +44 -0
- package/plugins/clix/plugin.json +126 -0
- package/plugins/clix/scripts/post-install.js +66 -0
- package/plugins/clix/scripts/post-uninstall.js +25 -0
- package/plugins/himalaya/README.md +48 -0
- package/plugins/himalaya/plugin.json +157 -0
- package/plugins/mongosh/README.md +56 -0
- package/plugins/mongosh/plugin.json +88 -0
- package/plugins/mysql/README.md +48 -0
- package/plugins/mysql/plugin.json +64 -0
- package/plugins/plugins.json +63 -0
- package/plugins/wacli/README.md +52 -0
- package/plugins/wacli/plugin.json +260 -0
- package/plugins/xurl/README.md +52 -0
- package/plugins/xurl/plugin.json +239 -0
- package/plugins/xurl/scripts/post-install.js +66 -0
- package/plugins/xurl/scripts/post-uninstall.js +25 -0
- package/server/routes/mcp.js +30 -4
- package/server/services/configService.js +9 -1
- package/tests/test-blogwatcher-smoke.sh +48 -0
- package/tests/test-clix-smoke.sh +44 -0
- package/tests/test-himalaya-smoke.sh +47 -0
- package/tests/test-mcp-browser-use-smoke.sh +141 -0
- package/tests/test-mongosh-smoke.sh +40 -0
- package/tests/test-mysql-smoke.sh +37 -0
- package/tests/test-plugins-registry.js +35 -0
- package/tests/test-wacli-smoke.sh +46 -0
- package/tests/test-xurl-smoke.sh +46 -0
package/cli/skills.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { createPlan } = require("./planner")
|
|
2
2
|
|
|
3
3
|
const PLUGINS_USAGE_SKILL_ID = "plugins.registry.usage"
|
|
4
|
+
const MCP_SERVERS_USAGE_SKILL_ID = "mcp.servers.usage"
|
|
4
5
|
const {
|
|
5
6
|
listProviders,
|
|
6
7
|
addProvider,
|
|
@@ -221,6 +222,49 @@ function buildPluginsUsageSkillMarkdown(options = {}) {
|
|
|
221
222
|
return `---\n${renderYamlObject(frontmatter)}\n---\n\n# Instruction\n\nUse this workflow for plugin discovery and installation:\n\n1. Explore registry metadata (name/description/tags):\n\n\`\`\`bash\nsupercli plugins explore --json\nsupercli plugins explore --name commiat --json\nsupercli plugins explore --tags git,ai --json\n\`\`\`\n\n2. Install by registry name:\n\n\`\`\`bash\nsupercli plugins install commiat --json\n\`\`\`\n\n3. Install directly from a remote git repository:\n\n\`\`\`bash\nsupercli plugins install --git https://github.com/org/repo.git --manifest-path plugins/supercli/plugin.json --ref main --json\n\`\`\`\n\n4. Validate installed plugin health and guidance:\n\n\`\`\`bash\nsupercli plugins doctor commiat --json\nsupercli plugins show commiat --json\n\`\`\`\n\n5. Use the namespace command exposed by the plugin.\n\n# Examples\n\n\`\`\`bash\nsupercli skills get ${PLUGINS_USAGE_SKILL_ID} --format skill.md\nsupercli skills get ${PLUGINS_USAGE_SKILL_ID} --format skill.md --show-dag\n\`\`\``
|
|
222
223
|
}
|
|
223
224
|
|
|
225
|
+
function buildMcpServersUsageSkillMarkdown(options = {}) {
|
|
226
|
+
const includeDag = !!options.showDag
|
|
227
|
+
const frontmatter = {
|
|
228
|
+
skill_name: "mcp_servers_usage",
|
|
229
|
+
description: "Teaches agents how to manage and use MCP servers through SuperCLI, including browser-use style SSE bridges.",
|
|
230
|
+
command: `skills get ${MCP_SERVERS_USAGE_SKILL_ID}`,
|
|
231
|
+
arguments: [
|
|
232
|
+
{
|
|
233
|
+
name: "format",
|
|
234
|
+
type: "string",
|
|
235
|
+
required: false,
|
|
236
|
+
description: "Output format, default skill.md"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "show-dag",
|
|
240
|
+
type: "boolean",
|
|
241
|
+
required: false,
|
|
242
|
+
description: "Include internal DAG for agent reasoning"
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
output_schema: {
|
|
246
|
+
instruction: "string",
|
|
247
|
+
examples: "array"
|
|
248
|
+
},
|
|
249
|
+
metadata: {
|
|
250
|
+
side_effects: false,
|
|
251
|
+
risk_level: "safe",
|
|
252
|
+
dag_supported: true
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (includeDag) {
|
|
257
|
+
frontmatter.dag = [
|
|
258
|
+
{ id: 1, type: "list_mcp_servers" },
|
|
259
|
+
{ id: 2, type: "register_or_update_mcp_server", depends_on: [1] },
|
|
260
|
+
{ id: 3, type: "verify_mcp_server_configuration", depends_on: [2] },
|
|
261
|
+
{ id: 4, type: "execute_mcp_backed_command", depends_on: [3] }
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return `---\n${renderYamlObject(frontmatter)}\n---\n\n# Instruction\n\nUse this workflow to manage and use MCP servers safely in non-interactive agent flows:\n\n1. List registered MCP servers and inspect current state:\n\n\`\`\`bash\nsupercli mcp list --json\n\`\`\`\n\n2. Register or update a server by URL (HTTP MCP):\n\n\`\`\`bash\nsupercli mcp add summarize-local --url http://127.0.0.1:8787 --json\n\`\`\`\n\n3. Register a stdio bridge server (browser-use style over remote SSE using mcp-remote):\n\n\`\`\`bash\n# Provide key at runtime; do not hardcode secrets in repository files\nsupercli mcp add browser-use --command npx \\\n --args-json '["mcp-remote","https://api.browser-use.com/mcp","--header","X-Browser-Use-API-Key: \${BROWSER_USE_API_KEY}"]' \\\n --env-json '{"BROWSER_USE_API_KEY":"\${BROWSER_USE_API_KEY}"}' \\\n --json\n\`\`\`\n\n4. Verify the MCP server registration:\n\n\`\`\`bash\nsupercli mcp list --json\n\`\`\`\n\n5. Execute MCP-backed commands normally once configured:\n\n\`\`\`bash\n# Example command that uses adapter: mcp under the hood\nsupercli ai browser probe --json\n\`\`\`\n\n6. Remove stale MCP entries when no longer needed:\n\n\`\`\`bash\nsupercli mcp remove browser-use --json\n\`\`\`\n\n# Notes\n\n- Prefer passing secrets via runtime environment variables and CLI args, not committed files.\n- For named MCP servers, command-level adapter settings override server-level defaults on conflicts.\n- Use \`supercli skills teach --format skill.md\` for general skills discovery guidance.`
|
|
266
|
+
}
|
|
267
|
+
|
|
224
268
|
function listSkillsMetadata(config) {
|
|
225
269
|
const commandSkills = (config.commands || []).map(cmd => ({
|
|
226
270
|
name: `${cmd.namespace}.${cmd.resource}.${cmd.action}`,
|
|
@@ -230,6 +274,10 @@ function listSkillsMetadata(config) {
|
|
|
230
274
|
name: PLUGINS_USAGE_SKILL_ID,
|
|
231
275
|
description: "Discover and install plugins from the registry or remote git repos"
|
|
232
276
|
})
|
|
277
|
+
commandSkills.push({
|
|
278
|
+
name: MCP_SERVERS_USAGE_SKILL_ID,
|
|
279
|
+
description: "Manage MCP servers and execute MCP-backed commands (including browser-use style bridges)"
|
|
280
|
+
})
|
|
233
281
|
return commandSkills
|
|
234
282
|
}
|
|
235
283
|
|
|
@@ -386,6 +434,11 @@ function handleSkillsCommand(options) {
|
|
|
386
434
|
return true
|
|
387
435
|
}
|
|
388
436
|
|
|
437
|
+
if (parsed.id === MCP_SERVERS_USAGE_SKILL_ID) {
|
|
438
|
+
console.log(buildMcpServersUsageSkillMarkdown({ showDag: !!flags["show-dag"] }))
|
|
439
|
+
return true
|
|
440
|
+
}
|
|
441
|
+
|
|
389
442
|
const cmd = config.commands.find(c =>
|
|
390
443
|
c.namespace === parsed.namespace && c.resource === parsed.resource && c.action === parsed.action
|
|
391
444
|
)
|
|
@@ -404,10 +457,12 @@ function handleSkillsCommand(options) {
|
|
|
404
457
|
|
|
405
458
|
module.exports = {
|
|
406
459
|
PLUGINS_USAGE_SKILL_ID,
|
|
460
|
+
MCP_SERVERS_USAGE_SKILL_ID,
|
|
407
461
|
normalizeSkillId,
|
|
408
462
|
buildCommandSkillMarkdown,
|
|
409
463
|
buildTeachSkillMarkdown,
|
|
410
464
|
buildPluginsUsageSkillMarkdown,
|
|
465
|
+
buildMcpServersUsageSkillMarkdown,
|
|
411
466
|
listSkillsMetadata,
|
|
412
467
|
handleSkillsCommand,
|
|
413
468
|
renderYamlObject // Export for testing coverage
|
package/cli/supercli.js
CHANGED
|
@@ -212,7 +212,7 @@ function renderTopLevelHelp(config) {
|
|
|
212
212
|
" Plugins: supercli plugins explore | supercli plugins install <name|path> | supercli plugins install --git <repo>",
|
|
213
213
|
);
|
|
214
214
|
console.log(
|
|
215
|
-
" MCP: supercli mcp list | supercli mcp add <name> --url <url> | supercli mcp remove <name>",
|
|
215
|
+
" MCP: supercli mcp list | supercli mcp add <name> --url <url> | supercli mcp add <name> --command <cmd> --args-json '[]' | supercli mcp remove <name>",
|
|
216
216
|
);
|
|
217
217
|
console.log(
|
|
218
218
|
" Skills: supercli skills list | supercli skills get <id> | supercli skills search --query <q> | supercli skills sync",
|
|
@@ -6,8 +6,8 @@ SUPERCLI acts as a universal frontend proxy that translates semantic commands (e
|
|
|
6
6
|
|
|
7
7
|
- **HTTP Adapter**: Directly invokes external REST APIs with configured methods, headers, and interpolated path/query parameters.
|
|
8
8
|
- **OpenAPI Adapter**: Given a registered OpenAPI spec URL, maps a SUPERCLI command dynamically to an OpenAPI operation, handling auth and schema resolution on the fly.
|
|
9
|
-
- **MCP Adapter (Model Context Protocol)**: Connects to local or remote MCP servers to trigger their exposed tools. Supports
|
|
10
|
-
- **Local MCP Registry**: Decouples MCP tool integration from the backend server by maintaining
|
|
9
|
+
- **MCP Adapter (Model Context Protocol)**: Connects to local or remote MCP servers to trigger their exposed tools. Supports HTTP endpoints and local `stdio` execution (`command` + `args`).
|
|
10
|
+
- **Local MCP Registry**: Decouples MCP tool integration from the backend server by maintaining MCP server entries in `~/.supercli/config.json`.
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
@@ -20,6 +20,10 @@ supercli mcp list
|
|
|
20
20
|
# Add an offline local MCP stdio server
|
|
21
21
|
supercli mcp add summarize-local --url http://127.0.0.1:8787
|
|
22
22
|
|
|
23
|
+
# Add a stdio bridge for remote SSE MCP servers (browser-use style)
|
|
24
|
+
supercli mcp add browser-use --command npx \
|
|
25
|
+
--args-json '["mcp-remote","https://api.browser-use.com/mcp","--header","X-Browser-Use-API-Key: your-api-key"]'
|
|
26
|
+
|
|
23
27
|
# Execute an MCP tool via the bound alias
|
|
24
28
|
supercli ai text summarize --text "Hello world"
|
|
25
29
|
```
|
|
@@ -16,11 +16,14 @@ For `adapter: mcp`, SUPERCLI resolves the tool endpoint in this order:
|
|
|
16
16
|
```bash
|
|
17
17
|
supercli mcp list
|
|
18
18
|
supercli mcp add summarize-local --url http://127.0.0.1:8787
|
|
19
|
+
supercli mcp add browser-use --command npx --args-json '["mcp-remote","https://api.browser-use.com/mcp","--header","X-Browser-Use-API-Key: your-api-key"]'
|
|
19
20
|
supercli mcp remove summarize-local
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
These commands only update local cache (`~/.supercli/config.json`).
|
|
23
24
|
|
|
25
|
+
Local config also accepts a Claude-style `mcpServers` object and normalizes it to `mcp_servers` internally.
|
|
26
|
+
|
|
24
27
|
## Demo: `ai text summarize` with stdio MCP (no server)
|
|
25
28
|
|
|
26
29
|
From the repository root:
|
package/docs/skills-catalog.md
CHANGED
|
@@ -27,6 +27,16 @@ supercli skills search --query "planning" --json
|
|
|
27
27
|
supercli skills get opencode:plan-changes
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
## Built-in MCP Usage Skill (Agent-Friendly)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
supercli skills get mcp.servers.usage
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This built-in skill teaches non-human agents how to register, verify, and use MCP servers
|
|
37
|
+
through SuperCLI, including a browser-use style `mcp-remote` SSE bridge pattern with
|
|
38
|
+
runtime API-key passing.
|
|
39
|
+
|
|
30
40
|
## Notes
|
|
31
41
|
|
|
32
42
|
- IDs are always provider-qualified (`provider:id`) for future-proof disambiguation.
|
|
@@ -69,6 +79,46 @@ supercli skills get nullclaw:docs.en.commands
|
|
|
69
79
|
project overview, operator docs, security guidance, and implementation notes on demand.
|
|
70
80
|
It also exposes the local `nullclaw` binary through wrapped commands and full passthrough.
|
|
71
81
|
|
|
82
|
+
## Remote Provider Example: blogwatcher
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
supercli plugins install blogwatcher --json
|
|
86
|
+
supercli skills list --catalog --provider blogwatcher --json
|
|
87
|
+
supercli skills get blogwatcher:root.skill
|
|
88
|
+
supercli skills get blogwatcher:root.readme
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`blogwatcher` indexes the upstream `SKILL.md` and `README.md` from `Hyaxia/blogwatcher`
|
|
92
|
+
so agents can learn the CLI workflow, storage model, and testing expectations on demand.
|
|
93
|
+
It also exposes the local `blogwatcher` binary through wrapped commands and passthrough.
|
|
94
|
+
|
|
95
|
+
## Remote Provider Example: xurl
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
supercli plugins install xurl --json
|
|
99
|
+
supercli skills list --catalog --provider xurl --json
|
|
100
|
+
supercli skills get xurl:root.skill
|
|
101
|
+
supercli skills get xurl:root.readme
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`xurl` indexes the upstream `SKILL.md` and `README.md` from `xdevplatform/xurl`
|
|
105
|
+
so agents can learn safe X API workflows, auth constraints, and shortcut command patterns
|
|
106
|
+
without reading local token storage. It also exposes curated read-only wrappers for the local
|
|
107
|
+
`xurl` binary.
|
|
108
|
+
|
|
109
|
+
## Remote Provider Example: clix
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
supercli plugins install clix --json
|
|
113
|
+
supercli skills list --catalog --provider clix --json
|
|
114
|
+
supercli skills get clix:root.skill
|
|
115
|
+
supercli skills get clix:root.readme
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`clix` indexes the upstream `SKILL.md` and `README.md` from `spideystreet/clix`
|
|
119
|
+
so agents can learn safe cookie-auth X workflows, JSON usage, and agent-mode guidance.
|
|
120
|
+
It also exposes curated read-only wrappers for the local `clix` binary.
|
|
121
|
+
|
|
72
122
|
## Local Repo Skill Example: cline-non-interactive
|
|
73
123
|
|
|
74
124
|
```bash
|
|
@@ -209,6 +209,26 @@ These harnesses are in active development and will be available as plugins. Stat
|
|
|
209
209
|
|
|
210
210
|
---
|
|
211
211
|
|
|
212
|
+
### Databases
|
|
213
|
+
|
|
214
|
+
| Harness | CLI | Status | Purpose |
|
|
215
|
+
|---------|-----|--------|---------|
|
|
216
|
+
| **mysql** | mysql | Available via plugin | MySQL client version checks, one-off queries, passthrough |
|
|
217
|
+
| **mongosh** | mongosh | Available via plugin | MongoDB shell ping, eval, and passthrough |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
### Communication
|
|
222
|
+
|
|
223
|
+
| Harness | CLI | Status | Purpose |
|
|
224
|
+
|---------|-----|--------|---------|
|
|
225
|
+
| **himalaya** | himalaya | Available via plugin | Read-only email account, folder, envelope, and preview workflows |
|
|
226
|
+
| **wacli** | wacli | Available via plugin | Read-only WhatsApp diagnostics, chats, messages, contacts, and groups |
|
|
227
|
+
| **xurl** | xurl | Available via plugin | Read-only X account, timeline, search, and social graph workflows |
|
|
228
|
+
| **clix** | clix | Available via plugin | Read-only X timeline, search, user, tweet, and bookmarks workflows |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
212
232
|
### Version Control & Release
|
|
213
233
|
|
|
214
234
|
| Harness | CLI | Status | Purpose |
|
package/package.json
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# BlogWatcher Plugin
|
|
2
|
+
|
|
3
|
+
This plugin is a hybrid harness: it indexes BlogWatcher's upstream `SKILL.md` and `README.md` into the local skills catalog and exposes the local `blogwatcher` binary through wrapped commands plus full passthrough.
|
|
4
|
+
|
|
5
|
+
## What It Adds
|
|
6
|
+
|
|
7
|
+
- agent-oriented usage guidance from the upstream `SKILL.md`
|
|
8
|
+
- project and end-user documentation from the upstream `README.md`
|
|
9
|
+
- non-interactive wrappers for the local BlogWatcher CLI
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
supercli plugins install blogwatcher --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Explore Indexed Skills
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
supercli skills list --catalog --provider blogwatcher --json
|
|
21
|
+
supercli skills get blogwatcher:root.skill
|
|
22
|
+
supercli skills get blogwatcher:root.readme
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Available CLI Commands
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Wrapped version command
|
|
29
|
+
supercli blogwatcher cli version --json
|
|
30
|
+
|
|
31
|
+
# Wrapped list/add/remove commands
|
|
32
|
+
supercli blogwatcher blogs list --json
|
|
33
|
+
supercli blogwatcher blogs add --name "Example" --url "https://example.com/blog" --feed-url "https://example.com/feed.xml" --json
|
|
34
|
+
supercli blogwatcher blogs remove --name "Example" --json
|
|
35
|
+
|
|
36
|
+
# Wrapped scan and article commands
|
|
37
|
+
supercli blogwatcher scan run --workers 4 --json
|
|
38
|
+
supercli blogwatcher articles list --all --json
|
|
39
|
+
supercli blogwatcher articles read-all --json
|
|
40
|
+
|
|
41
|
+
# Full passthrough
|
|
42
|
+
supercli blogwatcher articles --all
|
|
43
|
+
supercli blogwatcher scan "Example Blog"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Notes
|
|
47
|
+
|
|
48
|
+
- This plugin indexes remote markdown from `https://github.com/Hyaxia/blogwatcher`.
|
|
49
|
+
- Wrapped commands return raw text in the dcli envelope because upstream does not expose JSON output.
|
|
50
|
+
- The wrapped `blogs remove` and `articles read-all` commands force `--yes` to avoid interactive prompts.
|
|
51
|
+
- BlogWatcher stores its SQLite data under `~/.blogwatcher`, so use an isolated `HOME` if you want disposable smoke testing.
|
|
52
|
+
- Removing the plugin also removes its registered skills provider from the local catalog.
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "blogwatcher",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Hybrid BlogWatcher plugin with remote agent docs plus local CLI wrappers",
|
|
5
|
+
"source": "https://github.com/Hyaxia/blogwatcher",
|
|
6
|
+
"checks": [
|
|
7
|
+
{ "type": "binary", "name": "curl" },
|
|
8
|
+
{ "type": "binary", "name": "blogwatcher" }
|
|
9
|
+
],
|
|
10
|
+
"post_install": {
|
|
11
|
+
"script": "scripts/post-install.js",
|
|
12
|
+
"runtime": "node",
|
|
13
|
+
"timeout_ms": 15000
|
|
14
|
+
},
|
|
15
|
+
"post_uninstall": {
|
|
16
|
+
"script": "scripts/post-uninstall.js",
|
|
17
|
+
"runtime": "node",
|
|
18
|
+
"timeout_ms": 15000
|
|
19
|
+
},
|
|
20
|
+
"commands": [
|
|
21
|
+
{
|
|
22
|
+
"namespace": "blogwatcher",
|
|
23
|
+
"resource": "cli",
|
|
24
|
+
"action": "version",
|
|
25
|
+
"description": "Show BlogWatcher CLI version",
|
|
26
|
+
"adapter": "process",
|
|
27
|
+
"adapterConfig": {
|
|
28
|
+
"command": "blogwatcher",
|
|
29
|
+
"baseArgs": ["--version"],
|
|
30
|
+
"parseJson": false,
|
|
31
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
32
|
+
},
|
|
33
|
+
"args": []
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"namespace": "blogwatcher",
|
|
37
|
+
"resource": "blogs",
|
|
38
|
+
"action": "list",
|
|
39
|
+
"description": "List tracked blogs",
|
|
40
|
+
"adapter": "process",
|
|
41
|
+
"adapterConfig": {
|
|
42
|
+
"command": "blogwatcher",
|
|
43
|
+
"baseArgs": ["blogs"],
|
|
44
|
+
"parseJson": false,
|
|
45
|
+
"timeout_ms": 15000,
|
|
46
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
47
|
+
},
|
|
48
|
+
"args": []
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"namespace": "blogwatcher",
|
|
52
|
+
"resource": "blogs",
|
|
53
|
+
"action": "add",
|
|
54
|
+
"description": "Add a blog to BlogWatcher",
|
|
55
|
+
"adapter": "process",
|
|
56
|
+
"adapterConfig": {
|
|
57
|
+
"command": "blogwatcher",
|
|
58
|
+
"baseArgs": ["add"],
|
|
59
|
+
"positionalArgs": ["name", "url"],
|
|
60
|
+
"parseJson": false,
|
|
61
|
+
"timeout_ms": 15000,
|
|
62
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
63
|
+
},
|
|
64
|
+
"args": [
|
|
65
|
+
{ "name": "name", "type": "string", "required": true },
|
|
66
|
+
{ "name": "url", "type": "string", "required": true },
|
|
67
|
+
{ "name": "feed-url", "type": "string", "required": false },
|
|
68
|
+
{ "name": "scrape-selector", "type": "string", "required": false }
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"namespace": "blogwatcher",
|
|
73
|
+
"resource": "blogs",
|
|
74
|
+
"action": "remove",
|
|
75
|
+
"description": "Remove a tracked blog without prompting",
|
|
76
|
+
"adapter": "process",
|
|
77
|
+
"adapterConfig": {
|
|
78
|
+
"command": "blogwatcher",
|
|
79
|
+
"baseArgs": ["remove", "--yes"],
|
|
80
|
+
"positionalArgs": ["name"],
|
|
81
|
+
"parseJson": false,
|
|
82
|
+
"timeout_ms": 15000,
|
|
83
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
84
|
+
},
|
|
85
|
+
"args": [
|
|
86
|
+
{ "name": "name", "type": "string", "required": true }
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"namespace": "blogwatcher",
|
|
91
|
+
"resource": "scan",
|
|
92
|
+
"action": "run",
|
|
93
|
+
"description": "Scan blogs for new articles in non-interactive mode",
|
|
94
|
+
"adapter": "process",
|
|
95
|
+
"adapterConfig": {
|
|
96
|
+
"command": "blogwatcher",
|
|
97
|
+
"baseArgs": ["scan", "--silent"],
|
|
98
|
+
"positionalArgs": ["blog"],
|
|
99
|
+
"parseJson": false,
|
|
100
|
+
"timeout_ms": 15000,
|
|
101
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
102
|
+
},
|
|
103
|
+
"args": [
|
|
104
|
+
{ "name": "blog", "type": "string", "required": false },
|
|
105
|
+
{ "name": "workers", "type": "integer", "required": false }
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"namespace": "blogwatcher",
|
|
110
|
+
"resource": "articles",
|
|
111
|
+
"action": "list",
|
|
112
|
+
"description": "List tracked articles",
|
|
113
|
+
"adapter": "process",
|
|
114
|
+
"adapterConfig": {
|
|
115
|
+
"command": "blogwatcher",
|
|
116
|
+
"baseArgs": ["articles"],
|
|
117
|
+
"parseJson": false,
|
|
118
|
+
"timeout_ms": 15000,
|
|
119
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
120
|
+
},
|
|
121
|
+
"args": [
|
|
122
|
+
{ "name": "all", "type": "boolean", "required": false },
|
|
123
|
+
{ "name": "blog", "type": "string", "required": false }
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"namespace": "blogwatcher",
|
|
128
|
+
"resource": "articles",
|
|
129
|
+
"action": "read",
|
|
130
|
+
"description": "Mark an article as read",
|
|
131
|
+
"adapter": "process",
|
|
132
|
+
"adapterConfig": {
|
|
133
|
+
"command": "blogwatcher",
|
|
134
|
+
"baseArgs": ["read"],
|
|
135
|
+
"positionalArgs": ["article_id"],
|
|
136
|
+
"parseJson": false,
|
|
137
|
+
"timeout_ms": 15000,
|
|
138
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
139
|
+
},
|
|
140
|
+
"args": [
|
|
141
|
+
{ "name": "article_id", "type": "integer", "required": true }
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"namespace": "blogwatcher",
|
|
146
|
+
"resource": "articles",
|
|
147
|
+
"action": "unread",
|
|
148
|
+
"description": "Mark an article as unread",
|
|
149
|
+
"adapter": "process",
|
|
150
|
+
"adapterConfig": {
|
|
151
|
+
"command": "blogwatcher",
|
|
152
|
+
"baseArgs": ["unread"],
|
|
153
|
+
"positionalArgs": ["article_id"],
|
|
154
|
+
"parseJson": false,
|
|
155
|
+
"timeout_ms": 15000,
|
|
156
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
157
|
+
},
|
|
158
|
+
"args": [
|
|
159
|
+
{ "name": "article_id", "type": "integer", "required": true }
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"namespace": "blogwatcher",
|
|
164
|
+
"resource": "articles",
|
|
165
|
+
"action": "read-all",
|
|
166
|
+
"description": "Mark unread articles as read without prompting",
|
|
167
|
+
"adapter": "process",
|
|
168
|
+
"adapterConfig": {
|
|
169
|
+
"command": "blogwatcher",
|
|
170
|
+
"baseArgs": ["read-all", "--yes"],
|
|
171
|
+
"parseJson": false,
|
|
172
|
+
"timeout_ms": 15000,
|
|
173
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
174
|
+
},
|
|
175
|
+
"args": [
|
|
176
|
+
{ "name": "blog", "type": "string", "required": false }
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"namespace": "blogwatcher",
|
|
181
|
+
"resource": "_",
|
|
182
|
+
"action": "_",
|
|
183
|
+
"description": "Passthrough command to execute any BlogWatcher CLI command",
|
|
184
|
+
"adapter": "process",
|
|
185
|
+
"adapterConfig": {
|
|
186
|
+
"command": "blogwatcher",
|
|
187
|
+
"passthrough": true,
|
|
188
|
+
"parseJson": false,
|
|
189
|
+
"timeout_ms": 15000,
|
|
190
|
+
"missingDependencyHelp": "Please install blogwatcher to use this command."
|
|
191
|
+
},
|
|
192
|
+
"args": []
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { addProvider, syncCatalog } = require("../../../cli/skills-catalog")
|
|
2
|
+
|
|
3
|
+
const OWNER = "Hyaxia"
|
|
4
|
+
const REPO = "blogwatcher"
|
|
5
|
+
const REF = "main"
|
|
6
|
+
const SOURCE_REPO = `https://github.com/${OWNER}/${REPO}`
|
|
7
|
+
const RAW_BASE_URL = `https://raw.githubusercontent.com/${OWNER}/${REPO}/${REF}`
|
|
8
|
+
|
|
9
|
+
const CATALOG_FILES = [
|
|
10
|
+
{
|
|
11
|
+
id: "root.skill",
|
|
12
|
+
name: "BlogWatcher Agent Skill",
|
|
13
|
+
path: "SKILL.md",
|
|
14
|
+
description: "Agent-focused guidance for working with the BlogWatcher CLI, code layout, and testing flow.",
|
|
15
|
+
tags: ["agents", "blogs", "workflow"]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "root.readme",
|
|
19
|
+
name: "BlogWatcher Overview",
|
|
20
|
+
path: "README.md",
|
|
21
|
+
description: "Project overview, installation steps, storage model, and end-user command examples.",
|
|
22
|
+
tags: ["overview", "blogs", "rss"]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
function buildRemoteEntries() {
|
|
27
|
+
return CATALOG_FILES.map(file => ({
|
|
28
|
+
...file,
|
|
29
|
+
source_url: `${RAW_BASE_URL}/${file.path}`
|
|
30
|
+
}))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function run() {
|
|
34
|
+
const entries = buildRemoteEntries()
|
|
35
|
+
addProvider({
|
|
36
|
+
name: "blogwatcher",
|
|
37
|
+
type: "remote_static",
|
|
38
|
+
enabled: true,
|
|
39
|
+
source_repo: SOURCE_REPO,
|
|
40
|
+
ref: REF,
|
|
41
|
+
entries
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const index = syncCatalog()
|
|
45
|
+
return {
|
|
46
|
+
provider: "blogwatcher",
|
|
47
|
+
entries: entries.length,
|
|
48
|
+
synced_skills: Array.isArray(index.skills) ? index.skills.length : 0
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (require.main === module) {
|
|
53
|
+
try {
|
|
54
|
+
const result = run()
|
|
55
|
+
process.stdout.write(JSON.stringify(result))
|
|
56
|
+
} catch (err) {
|
|
57
|
+
process.stderr.write(err.message)
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
CATALOG_FILES,
|
|
64
|
+
buildRemoteEntries,
|
|
65
|
+
run
|
|
66
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { removeProvider, syncCatalog } = require("../../../cli/skills-catalog")
|
|
2
|
+
|
|
3
|
+
function run() {
|
|
4
|
+
const removed = removeProvider("blogwatcher")
|
|
5
|
+
const index = syncCatalog()
|
|
6
|
+
return {
|
|
7
|
+
provider: "blogwatcher",
|
|
8
|
+
removed,
|
|
9
|
+
synced_skills: Array.isArray(index.skills) ? index.skills.length : 0
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (require.main === module) {
|
|
14
|
+
try {
|
|
15
|
+
const result = run()
|
|
16
|
+
process.stdout.write(JSON.stringify(result))
|
|
17
|
+
} catch (err) {
|
|
18
|
+
process.stderr.write(err.message)
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
run
|
|
25
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# clix Plugin Harness
|
|
2
|
+
|
|
3
|
+
This plugin is a hybrid harness for `clix`: it indexes the upstream `SKILL.md` and `README.md` into the local skills catalog and exposes a curated set of safe read-only wrappers.
|
|
4
|
+
|
|
5
|
+
## Why This Scope
|
|
6
|
+
|
|
7
|
+
`clix` can post, delete, like, retweet, and mutate bookmarks using cookie-based auth. The wrapped commands in this plugin intentionally focus on low-risk read-only workflows.
|
|
8
|
+
|
|
9
|
+
- upstream agent docs are indexed into the skills catalog
|
|
10
|
+
- read-only wrappers are exposed for auth status, timelines, search, tweets, users, and bookmarks
|
|
11
|
+
- no wildcard passthrough in v1
|
|
12
|
+
- no auth mutation, posting, delete, like, retweet, or bookmark mutation wrappers
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
supercli plugins install clix --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Explore Indexed Skills
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
supercli skills list --catalog --provider clix --json
|
|
24
|
+
supercli skills get clix:root.skill
|
|
25
|
+
supercli skills get clix:root.readme
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Available CLI Commands
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
supercli clix auth status --json
|
|
32
|
+
supercli clix timeline list --type following --count 20 --json
|
|
33
|
+
supercli clix posts search --query "from:openai" --type latest --count 20 --json
|
|
34
|
+
supercli clix posts show --id 1234567890 --json
|
|
35
|
+
supercli clix users show --handle openai --json
|
|
36
|
+
supercli clix bookmarks list --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Notes
|
|
40
|
+
|
|
41
|
+
- Wrapped commands always request upstream `--json` output and return parsed data in the dcli envelope.
|
|
42
|
+
- `clix` uses cookie-based auth and may access local browser/session data. Treat that auth state as sensitive.
|
|
43
|
+
- Use upstream `clix` directly for login, account switching, posting, deleting, likes, retweets, and bookmark mutations.
|
|
44
|
+
- Removing the plugin also removes its registered skills provider from the local catalog.
|