superacli 1.1.20 → 1.1.21

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.
Files changed (125) hide show
  1. package/cli/adapter-schema.js +1 -6
  2. package/cli/config.js +95 -0
  3. package/cli/executor.js +90 -11
  4. package/cli/server-command.js +395 -0
  5. package/cli/supercli.js +82 -1
  6. package/docs/adapters.md +159 -0
  7. package/docs/changelog-2026-04.html +15 -0
  8. package/docs/index.html +314 -98
  9. package/docs/meta-plugins.json +24424 -1247
  10. package/docs/plugins-examples.md +8 -8
  11. package/docs/plugins-how-to.md +0 -13
  12. package/docs/plugins.html +165 -61
  13. package/docs/server.md +50 -0
  14. package/graphify-out/GRAPH_REPORT.md +141 -136
  15. package/graphify-out/cache/1821936911d6eb3130499b6b45b8e6d760d6c05328131e115ac9825a5e3061cd.json +1 -0
  16. package/graphify-out/cache/20b0e1261b41286d639e7b039c8143682001981f607e26eb2a492a06f12c233a.json +1 -0
  17. package/graphify-out/cache/21dc011c08a0813ac33c0520c9cf131d8922e6007df7d9b51df740974fee5fb3.json +1 -0
  18. package/graphify-out/cache/22d3d43c24fdff310ab8445bd442fbcf4714872c6950f15b90777e5a8358dcd9.json +1 -0
  19. package/graphify-out/cache/2b8a3fbc23afe7bbc1a5ecb60d4074f39afdf6cb42120922176c280f4cc4ab4b.json +1 -0
  20. package/graphify-out/cache/37418b8b152d9c436d75361969c39bc74a76260ab7209ceabf455f80452f1654.json +1 -0
  21. package/graphify-out/cache/3b9aae57e4326f5862f8153c13b7d809a34c422996993e7b491c5ea3a66b5e04.json +1 -0
  22. package/graphify-out/cache/448f8e0c5e77cfb15fa625ed40ee0dc1622d9814d24905fe4c12c4d175131dc9.json +1 -0
  23. package/graphify-out/cache/47dd42009ceac28b7a7fec5586e565e7bc850c80be96b8329e1ed7c49efbe34f.json +1 -0
  24. package/graphify-out/cache/492712949d38efbe312c303fe717e5c93e1ecc8888e1ceb855750afc48caffdb.json +1 -0
  25. package/graphify-out/cache/494fd6af80b6a1bb7a2a5641c6ad11e2fbe2a67b5a2b3ff57fd04bb49ccad1c4.json +1 -0
  26. package/graphify-out/cache/4b31b0de656deff083119780df64d17205c45e72233987e1c495f2121c4923fd.json +1 -0
  27. package/graphify-out/cache/5a16fa8cdd687a39661321adb39186ce8cf924a79ef936e42b365380b5e3543e.json +1 -0
  28. package/graphify-out/cache/644fcb129e595cfdb4e3a9757ed9658230347f5ed0652be45a894528a2b6585b.json +1 -0
  29. package/graphify-out/cache/6b8762db2c5f51408cf49d915f3e44bcc25c7ebb32abc635307fdf2a672b370c.json +1 -0
  30. package/graphify-out/cache/6db88050060880e56dd26ec58f29e3b56a409ace48e31bc75f54cab7dc74e409.json +1 -0
  31. package/graphify-out/cache/7932d1b6a9751b2cb2f4dc6b4e5f9fd7dcc2cee82d7866ec3d655482010533c0.json +1 -0
  32. package/graphify-out/cache/8140a76ff5b70dfdd0d020aeffff27f87af39da5b237c35baa938fcc4b288ba5.json +1 -0
  33. package/graphify-out/cache/8876638878758733a412bd4ca4cbd22863322689fbba9f037d92abfa877ea3ab.json +1 -0
  34. package/graphify-out/cache/90445359c448f8135207ddcd378c8391b9274460064cf998f1ea2ad6f2173703.json +1 -0
  35. package/graphify-out/cache/b01f675bb3942d2e8f359d11c38d52f28487544f54cdef518c60b7d8dfd2b383.json +1 -0
  36. package/graphify-out/cache/bc353b40b348d54c730d8498af675f57998b14ae796b4f952cdc200147008f13.json +1 -0
  37. package/graphify-out/cache/c38b2e784b1c441121b422db0c79b4911fb525d2a3cfad10d3fd561a07900bd5.json +1 -0
  38. package/graphify-out/cache/ce9df9bb2d36ecf310a53fb34526168bdf25773edf0826c1f55accebfa3c012d.json +1 -0
  39. package/graphify-out/cache/ceaeb0f99851d313b29cb1440240db1cf835de425b9b0c1e58fa3035355c2b2b.json +1 -0
  40. package/graphify-out/cache/d8f3e78931a41cd0f367fdab1d11b634bbffb2c90280c75a80a1a53a6b2d6bc7.json +1 -0
  41. package/graphify-out/cache/f574e4ce3bcb1250ca88410519fb4fd26c5b6cd786039410880fbd6e606ab23f.json +1 -0
  42. package/graphify-out/cache/faa65636d5f779b8b1c790dde11cc6470b48125bf42a12a77651827fd1653fd7.json +1 -0
  43. package/graphify-out/graph.json +4173 -2115
  44. package/ideal-plugins.csv +124 -0
  45. package/package.json +3 -2
  46. package/plugin-scores.csv +999 -0
  47. package/plugins/beads/plugin.json +2 -2
  48. package/plugins/biome/install-guidance.json +11 -0
  49. package/plugins/biome/meta.json +13 -0
  50. package/plugins/biome/plugin.json +83 -0
  51. package/plugins/biome/skills/quickstart/SKILL.md +25 -0
  52. package/plugins/bore/install-guidance.json +11 -0
  53. package/plugins/bore/meta.json +11 -0
  54. package/plugins/bore/plugin.json +65 -0
  55. package/plugins/bore/skills/quickstart/SKILL.md +25 -0
  56. package/plugins/ccf-deadlines/install-guidance.json +11 -0
  57. package/plugins/ccf-deadlines/meta.json +11 -0
  58. package/plugins/ccf-deadlines/plugin.json +28 -0
  59. package/plugins/ccf-deadlines/skills/quickstart/SKILL.md +25 -0
  60. package/plugins/code2prompt/install-guidance.json +11 -0
  61. package/plugins/code2prompt/meta.json +12 -0
  62. package/plugins/code2prompt/plugin.json +46 -0
  63. package/plugins/code2prompt/skills/quickstart/SKILL.md +25 -0
  64. package/plugins/commiat/install-guidance.json +10 -0
  65. package/plugins/commiat/plugin.json +2 -2
  66. package/plugins/dua-cli/install-guidance.json +11 -0
  67. package/plugins/dua-cli/meta.json +11 -0
  68. package/plugins/dua-cli/plugin.json +57 -0
  69. package/plugins/dua-cli/skills/quickstart/SKILL.md +25 -0
  70. package/plugins/forever/install-guidance.json +11 -0
  71. package/plugins/forever/meta.json +11 -0
  72. package/plugins/forever/plugin.json +75 -0
  73. package/plugins/forever/skills/quickstart/SKILL.md +25 -0
  74. package/plugins/gitmoji-cli/install-guidance.json +11 -0
  75. package/plugins/gitmoji-cli/meta.json +11 -0
  76. package/plugins/gitmoji-cli/plugin.json +49 -0
  77. package/plugins/gitmoji-cli/skills/quickstart/SKILL.md +25 -0
  78. package/plugins/google-maps-scraper/plugin.json +1 -1
  79. package/plugins/gwc/install-guidance.json +10 -0
  80. package/plugins/gwc/plugin.json +2 -2
  81. package/plugins/quarto/install-guidance.json +11 -0
  82. package/plugins/quarto/meta.json +11 -0
  83. package/plugins/quarto/plugin.json +61 -0
  84. package/plugins/quarto/skills/quickstart/SKILL.md +25 -0
  85. package/plugins/readme-md-generator/install-guidance.json +11 -0
  86. package/plugins/readme-md-generator/meta.json +11 -0
  87. package/plugins/readme-md-generator/plugin.json +28 -0
  88. package/plugins/readme-md-generator/skills/quickstart/SKILL.md +25 -0
  89. package/plugins/twarc/install-guidance.json +11 -0
  90. package/plugins/twarc/meta.json +13 -0
  91. package/plugins/twarc/plugin.json +165 -0
  92. package/plugins/twarc/skills/quickstart/SKILL.md +61 -0
  93. package/plugins/vale/install-guidance.json +11 -0
  94. package/plugins/vale/meta.json +12 -0
  95. package/plugins/vale/plugin.json +50 -0
  96. package/plugins/vale/skills/quickstart/SKILL.md +25 -0
  97. package/plugins/volta/install-guidance.json +11 -0
  98. package/plugins/volta/meta.json +12 -0
  99. package/plugins/volta/plugin.json +75 -0
  100. package/plugins/volta/skills/quickstart/SKILL.md +25 -0
  101. package/plugins/wgcf/install-guidance.json +11 -0
  102. package/plugins/wgcf/meta.json +12 -0
  103. package/plugins/wgcf/plugin.json +45 -0
  104. package/plugins/wgcf/skills/quickstart/SKILL.md +25 -0
  105. package/scripts/analyze-plugins.js +130 -0
  106. package/scripts/enrich-meta-plugins.js +67 -0
  107. package/server/app.js +23 -1
  108. package/server/routes/adapters.js +356 -0
  109. package/server/routes/dashboard.js +113 -0
  110. package/server/routes/jobs.js +26 -0
  111. package/server/services/adaptersService.js +284 -0
  112. package/server/services/pluginsService.js +4 -0
  113. package/server/views/adapter-edit.ejs +226 -0
  114. package/server/views/adapter-packages.ejs +191 -0
  115. package/server/views/adapters.ejs +112 -0
  116. package/server/views/command-edit.ejs +48 -21
  117. package/server/views/commands.ejs +25 -22
  118. package/server/views/dashboard.ejs +196 -0
  119. package/server/views/layout.ejs +94 -14
  120. package/server/views/mcp.ejs +38 -35
  121. package/server/views/partials/head.ejs +88 -12
  122. package/server/views/plugins.ejs +9 -0
  123. package/server/views/specs.ejs +33 -30
  124. package/cli/adapters/builtin.js +0 -43
  125. package/index.html +0 -384
@@ -0,0 +1,25 @@
1
+ # vale Quickstart
2
+
3
+ Markup-aware linter for prose
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ brew install vale
9
+ ```
10
+
11
+ ## Quick Examples
12
+
13
+ ```bash
14
+ # Check version
15
+ vale --version
16
+
17
+ # Get help
18
+ vale --help
19
+ ```
20
+
21
+ ## Resources
22
+
23
+ - GitHub: https://github.com/vale-cli/vale
24
+ - Stars: 5,360
25
+ - Language: go
@@ -0,0 +1,11 @@
1
+ {
2
+ "plugin": "volta",
3
+ "binary": "volta",
4
+ "check": "which volta",
5
+ "install_steps": [
6
+ "curl https://get.volta.sh | bash",
7
+ "Verify: volta --version",
8
+ "supercli plugins install ./plugins/volta --on-conflict replace --json"
9
+ ],
10
+ "note": "Source: https://github.com/volta-cli/volta (12,933 stars). Written in rust."
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "description": "JS Toolchains as Code - hassle-free JavaScript tools",
3
+ "tags": [
4
+ "volta",
5
+ "javascript",
6
+ "nodejs",
7
+ "toolchain",
8
+ "version-manager",
9
+ "rust"
10
+ ],
11
+ "has_learn": true
12
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "volta",
3
+ "version": "0.1.0",
4
+ "description": "JS Toolchains as Code - hassle-free JavaScript tools",
5
+ "source": "https://github.com/volta-cli/volta",
6
+ "checks": [
7
+ {
8
+ "type": "binary",
9
+ "name": "volta"
10
+ }
11
+ ],
12
+ "learn": {
13
+ "file": "skills/quickstart/SKILL.md"
14
+ },
15
+ "commands": [
16
+ {
17
+ "namespace": "volta",
18
+ "resource": "install",
19
+ "action": "package",
20
+ "description": "Install a package",
21
+ "adapter": "process",
22
+ "adapterConfig": {
23
+ "command": "volta",
24
+ "baseArgs": [
25
+ "install"
26
+ ],
27
+ "passthrough": true
28
+ },
29
+ "args": [
30
+ {
31
+ "name": "package",
32
+ "type": "string",
33
+ "required": true,
34
+ "description": "Package to install"
35
+ }
36
+ ]
37
+ },
38
+ {
39
+ "namespace": "volta",
40
+ "resource": "pin",
41
+ "action": "tool",
42
+ "description": "Pin tool version",
43
+ "adapter": "process",
44
+ "adapterConfig": {
45
+ "command": "volta",
46
+ "baseArgs": [
47
+ "pin"
48
+ ],
49
+ "passthrough": true
50
+ },
51
+ "args": [
52
+ {
53
+ "name": "tool",
54
+ "type": "string",
55
+ "required": true,
56
+ "description": "Tool to pin"
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ "namespace": "volta",
62
+ "resource": "list",
63
+ "action": "tools",
64
+ "description": "List installed tools",
65
+ "adapter": "process",
66
+ "adapterConfig": {
67
+ "command": "volta",
68
+ "baseArgs": [
69
+ "list"
70
+ ],
71
+ "passthrough": true
72
+ }
73
+ }
74
+ ]
75
+ }
@@ -0,0 +1,25 @@
1
+ # volta Quickstart
2
+
3
+ JS Toolchains as Code - hassle-free JavaScript tools
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ curl https://get.volta.sh | bash
9
+ ```
10
+
11
+ ## Quick Examples
12
+
13
+ ```bash
14
+ # Check version
15
+ volta --version
16
+
17
+ # Get help
18
+ volta --help
19
+ ```
20
+
21
+ ## Resources
22
+
23
+ - GitHub: https://github.com/volta-cli/volta
24
+ - Stars: 12,933
25
+ - Language: rust
@@ -0,0 +1,11 @@
1
+ {
2
+ "plugin": "wgcf",
3
+ "binary": "wgcf",
4
+ "check": "which wgcf",
5
+ "install_steps": [
6
+ "go install github.com/ViRb3/wgcf@latest",
7
+ "Verify: wgcf --version",
8
+ "supercli plugins install ./plugins/wgcf --on-conflict replace --json"
9
+ ],
10
+ "note": "Source: https://github.com/ViRb3/wgcf (8,192 stars). Written in go."
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "description": "Cross-platform CLI for Cloudflare Warp",
3
+ "tags": [
4
+ "wgcf",
5
+ "cloudflare",
6
+ "warp",
7
+ "wireguard",
8
+ "vpn",
9
+ "go"
10
+ ],
11
+ "has_learn": true
12
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "wgcf",
3
+ "version": "0.1.0",
4
+ "description": "Cross-platform CLI for Cloudflare Warp",
5
+ "source": "https://github.com/ViRb3/wgcf",
6
+ "checks": [
7
+ {
8
+ "type": "binary",
9
+ "name": "wgcf"
10
+ }
11
+ ],
12
+ "learn": {
13
+ "file": "skills/quickstart/SKILL.md"
14
+ },
15
+ "commands": [
16
+ {
17
+ "namespace": "wgcf",
18
+ "resource": "account",
19
+ "action": "register",
20
+ "description": "Register new Cloudflare account",
21
+ "adapter": "process",
22
+ "adapterConfig": {
23
+ "command": "wgcf",
24
+ "baseArgs": [
25
+ "register"
26
+ ],
27
+ "passthrough": true
28
+ }
29
+ },
30
+ {
31
+ "namespace": "wgcf",
32
+ "resource": "profile",
33
+ "action": "generate",
34
+ "description": "Generate WireGuard profile",
35
+ "adapter": "process",
36
+ "adapterConfig": {
37
+ "command": "wgcf",
38
+ "baseArgs": [
39
+ "generate"
40
+ ],
41
+ "passthrough": true
42
+ }
43
+ }
44
+ ]
45
+ }
@@ -0,0 +1,25 @@
1
+ # wgcf Quickstart
2
+
3
+ Cross-platform CLI for Cloudflare Warp
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ go install github.com/ViRb3/wgcf@latest
9
+ ```
10
+
11
+ ## Quick Examples
12
+
13
+ ```bash
14
+ # Check version
15
+ wgcf --version
16
+
17
+ # Get help
18
+ wgcf --help
19
+ ```
20
+
21
+ ## Resources
22
+
23
+ - GitHub: https://github.com/ViRb3/wgcf
24
+ - Stars: 8,192
25
+ - Language: go
@@ -0,0 +1,130 @@
1
+ // Analyze all plugins and score them based on agent-friendly criteria
2
+ // Scoring criteria:
3
+ // - no_interactive: +3 (very important for agents)
4
+ // - go_rust_nodejs: +2 (preferred languages)
5
+ // - cli: +2 (must be a CLI)
6
+ // - tui: -3 (strong penalty for TUI)
7
+ // - auth_required: -1 (penalty but acceptable)
8
+ // - binary: +1 (bonus, not required)
9
+ // - json_support: +2 (bonus for agents)
10
+ // - complexity: low=+2, medium=+1, high=0
11
+ // Usage: node scripts/analyze-plugins.js
12
+ const f=require('fs'),p=require('path'),b='/home/jarancibia/ai/supercli/plugins';
13
+ const plugins=f.readdirSync(b).filter(x=>!x.startsWith('.'));
14
+ const results=[];
15
+
16
+ for(const name of plugins){
17
+ const dir=p.join(b,name);
18
+ const pj=p.join(dir,'plugin.json');
19
+ const mj=p.join(dir,'meta.json');
20
+ const ij=p.join(dir,'install-guidance.json');
21
+
22
+ if(!f.existsSync(pj)) continue;
23
+
24
+ try{
25
+ const plugin=JSON.parse(f.readFileSync(pj));
26
+ const meta=f.existsSync(mj)?JSON.parse(f.readFileSync(mj)):null;
27
+ const guide=f.existsSync(ij)?JSON.parse(f.readFileSync(ij)):null;
28
+
29
+ // Analyze criteria
30
+ const source=plugin.source||'';
31
+ const install=guide?.install_steps?.[0]||'';
32
+ const binary=guide?.binary||plugin.checks?.[0]?.name||'';
33
+
34
+ // Language detection from source URL
35
+ const isGo=source.includes('github.com')&&install.includes('go install')||install.includes('curl')&&source.includes('/go');
36
+ const isRust=source.includes('github.com')&&install.includes('cargo install')||install.includes('curl')&&source.includes('/rs');
37
+ const isNode=install.includes('npm install')||install.includes('yarn')||install.includes('pnpm')||source.includes('/node')||source.includes('/js')||source.includes('/ts');
38
+
39
+ // Binary detection (bonus, not requirement)
40
+ const isBinary=install.includes('curl')||install.includes('wget')||install.includes('brew')||install.includes('apt')||install.includes('snap')||install.includes('go install')||install.includes('cargo install');
41
+
42
+ // CLI detection (from description and commands)
43
+ const desc=plugin.description||'';
44
+ const isCLI=desc.toLowerCase().includes('cli')||desc.toLowerCase().includes('command line')||desc.toLowerCase().includes('command-line')||plugin.commands?.length>0;
45
+
46
+ // TUI/interactive detection (strong penalty)
47
+ const isTUI=desc.toLowerCase().includes('tui')||desc.toLowerCase().includes('interactive')||desc.toLowerCase().includes('terminal ui')||meta?.tags?.some(t=>t.toLowerCase().includes('tui')||t.toLowerCase().includes('interactive'));
48
+
49
+ // Auth detection (penalty but acceptable)
50
+ const isAuth=desc.toLowerCase().includes('auth')||desc.toLowerCase().includes('authentication')||desc.toLowerCase().includes('login')||desc.toLowerCase().includes('token')||desc.toLowerCase().includes('api key')||meta?.tags?.some(t=>t.toLowerCase().includes('auth')||t.toLowerCase().includes('oauth'));
51
+
52
+ // Complexity (based on install steps count and description length)
53
+ const complexityScore=(install.length/100)+(desc.length/50);
54
+ let complexity='low';
55
+ if(complexityScore>3) complexity='medium';
56
+ if(complexityScore>6) complexity='high';
57
+
58
+ // Non-interactive/JSON support (very important for agents)
59
+ const hasJSON=plugin.commands?.some(c=>c.adapterConfig?.parseJson)||desc.toLowerCase().includes('json')||install.includes('json');
60
+ const isNonInteractive=!isTUI;
61
+
62
+ results.push({
63
+ name,
64
+ no_interactive: isNonInteractive ? 'yes' : 'no',
65
+ go_rust_nodejs: (isGo||isRust||isNode) ? 'yes' : 'no',
66
+ language: isGo?'go':isRust?'rust':isNode?'nodejs':'other',
67
+ cli: isCLI ? 'yes' : 'no',
68
+ tui: isTUI ? 'yes' : 'no',
69
+ auth_required: isAuth ? 'yes' : 'no',
70
+ complexity,
71
+ binary: isBinary ? 'yes' : 'no',
72
+ json_support: hasJSON ? 'yes' : 'no',
73
+ description: desc.substring(0,100),
74
+ install: install.substring(0,80)
75
+ });
76
+ }catch(e){
77
+ console.error('Error parsing',name,e.message);
78
+ }
79
+ }
80
+
81
+ // Improved scoring - more balanced, not requiring ALL criteria
82
+ results.forEach(r=>{
83
+ let score=0;
84
+ if(r.no_interactive==='yes') score+=3; // Very important for agents
85
+ if(r.go_rust_nodejs==='yes') score+=2; // Preferred languages
86
+ if(r.cli==='yes') score+=2; // Must be a CLI
87
+ if(r.tui==='yes') score-=3; // Strong penalty for TUI
88
+ if(r.auth_required==='yes') score-=1; // Penalty but acceptable
89
+ if(r.binary==='yes') score+=1; // Bonus, not required
90
+ if(r.json_support==='yes') score+=2; // Bonus for agents
91
+ if(r.complexity==='low') score+=2; // Prefer simple
92
+ else if(r.complexity==='medium') score+=1;
93
+ r.score=score;
94
+ });
95
+
96
+ // Sort by score descending
97
+ results.sort((a,b)=>b.score-a.score);
98
+
99
+ // Write CSV
100
+ const header='name,score,no_interactive,go_rust_nodejs,language,cli,tui,auth_required,complexity,binary,json_support,description,install\n';
101
+ const csv=header+results.map(r=>[
102
+ r.name,
103
+ r.score,
104
+ r.no_interactive,
105
+ r.go_rust_nodejs,
106
+ r.language,
107
+ r.cli,
108
+ r.tui,
109
+ r.auth_required,
110
+ r.complexity,
111
+ r.binary,
112
+ r.json_support,
113
+ `"${r.description.replace(/"/g,'""')}"`,
114
+ `"${r.install.replace(/"/g,'""')}"`
115
+ ].join(',')).join('\n');
116
+
117
+ f.writeFileSync('/tmp/plugin-scores-v2.csv',csv);
118
+ console.log('Analyzed',results.length,'plugins');
119
+ console.log('CSV written to /tmp/plugin-scores-v2.csv');
120
+ console.log('\nTop 50 plugins by score:');
121
+ results.slice(0,50).forEach(r=>console.log(`${r.name}: ${r.score} (${r.language}, tui=${r.tui}, auth=${r.auth_required}, binary=${r.binary})`));
122
+
123
+ // Count plugins by score ranges
124
+ const highScore=results.filter(r=>r.score>=8).length;
125
+ const medScore=results.filter(r=>r.score>=5&&r.score<8).length;
126
+ const lowScore=results.filter(r=>r.score<5).length;
127
+ console.log(`\nScore distribution:`);
128
+ console.log(`High score (8+): ${highScore}`);
129
+ console.log(`Medium score (5-7): ${medScore}`);
130
+ console.log(`Low score (<5): ${lowScore}`);
@@ -0,0 +1,67 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const SCORES_CSV = path.join(__dirname, '..', 'plugin-scores.csv');
5
+ const META_PLUGINS = path.join(__dirname, '..', 'docs', 'meta-plugins.json');
6
+
7
+ function parseCSV(filePath) {
8
+ const content = fs.readFileSync(filePath, 'utf8');
9
+ const lines = content.trim().split('\n');
10
+ const headers = lines[0].split(',').map(h => h.trim());
11
+
12
+ const scores = {};
13
+
14
+ for (let i = 1; i < lines.length; i++) {
15
+ const values = lines[i].split(',').map(v => v.trim());
16
+ const row = {};
17
+ headers.forEach((header, index) => {
18
+ row[header] = values[index];
19
+ });
20
+ scores[row.name] = row;
21
+ }
22
+
23
+ return scores;
24
+ }
25
+
26
+ function enrichMetaPlugins() {
27
+ const scores = parseCSV(SCORES_CSV);
28
+ const metaPlugins = JSON.parse(fs.readFileSync(META_PLUGINS, 'utf8'));
29
+
30
+ const enrichedPlugins = metaPlugins.plugins.map(plugin => {
31
+ const scoreData = scores[plugin.name];
32
+
33
+ if (scoreData) {
34
+ return {
35
+ ...plugin,
36
+ score: {
37
+ value: parseInt(scoreData.score, 10),
38
+ no_interactive: scoreData.no_interactive === 'yes',
39
+ go_rust_nodejs: scoreData.go_rust_nodejs === 'yes',
40
+ language: scoreData.language,
41
+ cli: scoreData.cli === 'yes',
42
+ tui: scoreData.tui === 'yes',
43
+ auth_required: scoreData.auth_required === 'yes',
44
+ complexity: scoreData.complexity,
45
+ binary: scoreData.binary === 'yes',
46
+ json_support: scoreData.json_support === 'yes',
47
+ install: scoreData.install
48
+ }
49
+ };
50
+ }
51
+
52
+ return plugin;
53
+ });
54
+
55
+ const output = {
56
+ generated: new Date().toISOString(),
57
+ count: enrichedPlugins.length,
58
+ plugins: enrichedPlugins
59
+ };
60
+
61
+ fs.writeFileSync(META_PLUGINS, JSON.stringify(output, null, 2));
62
+ console.log(`Enriched ${META_PLUGINS} with score metadata`);
63
+ const pluginsWithScores = enrichedPlugins.filter(p => p.score).length;
64
+ console.log(`Added scores to ${pluginsWithScores} plugins`);
65
+ }
66
+
67
+ enrichMetaPlugins();
package/server/app.js CHANGED
@@ -2,6 +2,8 @@ const express = require("express");
2
2
  const path = require("path");
3
3
  const { getStorage } = require("./storage/adapter");
4
4
 
5
+ const dashboardRouter = require("./routes/dashboard");
6
+ const adaptersRouter = require("./routes/adapters");
5
7
  const commandsRouter = require("./routes/commands");
6
8
  const configRouter = require("./routes/config");
7
9
  const specsRouter = require("./routes/specs");
@@ -24,6 +26,8 @@ app.set("views", path.join(__dirname, "views"));
24
26
  app.use("/static", express.static(path.join(__dirname, "public")));
25
27
 
26
28
  // API routes
29
+ app.use("/api/dashboard", dashboardRouter);
30
+ app.use("/api/adapters", adaptersRouter);
27
31
  app.use("/api/config", configRouter);
28
32
  app.use("/api/commands", commandsRouter);
29
33
  app.use("/api/specs", specsRouter);
@@ -36,14 +40,32 @@ app.use("/api/plugins", pluginsRouter);
36
40
  // Tree/command endpoints under /api (config router handles them)
37
41
  app.use("/api", configRouter);
38
42
 
43
+ app.use("/", dashboardRouter);
44
+
45
+ // Error handler - return JSON for API requests
46
+ app.use((err, req, res, next) => {
47
+ if (req.path.startsWith('/api') || req.headers.accept?.includes('application/json')) {
48
+ res.status(err.status || 500).json({
49
+ error: {
50
+ code: err.code || 500,
51
+ type: err.type || 'internal_error',
52
+ message: err.message || 'Internal server error',
53
+ recoverable: !!err.recoverable
54
+ }
55
+ });
56
+ } else {
57
+ res.status(err.status || 500).render('error', { message: err.message || 'Internal server error' });
58
+ }
59
+ });
60
+
39
61
  // UI page redirects
40
- app.get("/", (req, res) => res.redirect("/api/commands"));
41
62
  app.get("/commands", (req, res) => res.redirect("/api/commands"));
42
63
  app.get("/commands/new", (req, res) => res.redirect("/api/commands/new"));
43
64
  app.get("/specs", (req, res) => res.redirect("/api/specs"));
44
65
  app.get("/mcp", (req, res) => res.redirect("/api/mcp"));
45
66
  app.get("/jobs", (req, res) => res.redirect("/api/jobs"));
46
67
  app.get("/plugins", (req, res) => res.redirect("/api/plugins"));
68
+ app.get("/adapters", (req, res) => res.redirect("/api/adapters"));
47
69
 
48
70
  async function start() {
49
71
  try {