@trops/dash-core 0.1.492 → 0.1.494

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/package.json CHANGED
@@ -1,117 +1,121 @@
1
1
  {
2
- "name": "@trops/dash-core",
3
- "version": "0.1.492",
4
- "description": "Core framework for Dash dashboard applications",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
7
- "exports": {
8
- ".": {
9
- "import": "./dist/index.esm.js",
10
- "require": "./dist/index.js"
11
- },
12
- "./electron": {
13
- "require": "./dist/electron/index.js"
14
- }
2
+ "name": "@trops/dash-core",
3
+ "version": "0.1.494",
4
+ "description": "Core framework for Dash dashboard applications",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.esm.js",
10
+ "require": "./dist/index.js"
15
11
  },
16
- "files": [
17
- "dist"
18
- ],
19
- "scripts": {
20
- "build": "npm run build:renderer && npm run build:electron",
21
- "build:renderer": "rollup -c rollup.config.renderer.mjs",
22
- "build:electron": "rollup -c rollup.config.electron.mjs && mkdir -p dist/mcp && cp electron/mcp/mcpServerCatalog.json dist/mcp/ && cp electron/mcp/knownExternalMcpServers.json dist/mcp/ && rm -rf dist/mcp/servers && cp -r electron/mcp/servers dist/mcp/ && node scripts/inject-secrets.js",
23
- "clean": "rm -rf dist",
24
- "prepublishOnly": "npm run clean && npm run build",
25
- "test:mcp": "node --test electron/controller/mcpController.test.js electron/mcp/mcpServerCatalog.test.js electron/mcp/installExternalMcpTool.test.js",
26
- "test:untracked-pin": "node scripts/test-untracked-sources-pin.js",
27
- "check:untracked": "node scripts/check-untracked-sources.js",
28
- "test": "jest --watchAll=false",
29
- "prettify": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\" \"electron/**/*.js\"",
30
- "ci": "./scripts/ci.sh",
31
- "ci:commit": "./scripts/ci.sh --commit",
32
- "ci:push": "./scripts/ci.sh --push",
33
- "ci:pr": "./scripts/ci.sh --pr",
34
- "ci:release": "./scripts/ci.sh --release",
35
- "prdize": "node scripts/prdize.js"
36
- },
37
- "peerDependencies": {
38
- "@headlessui/react": "1.4",
39
- "@heroicons/react": "^2.0.16",
40
- "@trops/dash-react": ">=0.1.187",
41
- "prop-types": "^15.8.1",
42
- "react": "^18.2.0",
43
- "react-dnd": "^16.0.1",
44
- "react-dnd-html5-backend": "^16.0.1",
45
- "react-dom": "^18.2.0",
46
- "react-instantsearch-hooks-web": "^6.26.0",
47
- "react-router-dom": "^6.3.0",
48
- "tailwindcss": "^3.2.7"
49
- },
50
- "dependencies": {
51
- "@anthropic-ai/sdk": "^0.39.0",
52
- "@fortawesome/fontawesome-svg-core": "^6.1.1",
53
- "@fortawesome/free-brands-svg-icons": "^6.1.1",
54
- "@fortawesome/free-solid-svg-icons": "^6.1.1",
55
- "@fortawesome/react-fontawesome": "^0.1.18",
56
- "@modelcontextprotocol/sdk": "^1.26.0",
57
- "adm-zip": "^0.5.16",
58
- "algoliasearch": "^4.13.0",
59
- "clsx": "^2.1.1",
60
- "croner": "^10.0.1",
61
- "css": "^3.0.0",
62
- "csv-parser": "^3.0.0",
63
- "deep-equal": "^2.2.0",
64
- "electron-store": "^8.0.1",
65
- "esbuild": "^0.25.12",
66
- "JSONStream": "^1.3.5",
67
- "live-plugin-manager": "^0.17.1",
68
- "marked": "^17.0.5",
69
- "minimist": "^1.2.8",
70
- "node-forge": "^1.3.1",
71
- "node-vibrant": "^4.0.4",
72
- "objects-to-csv": "^1.3.6",
73
- "openai": "^4.30.0",
74
- "quickjs-emscripten": "^0.32.0",
75
- "ws": "^8.19.0",
76
- "xml2js": "^0.6.2",
77
- "xtreamer": "^1.1.2",
78
- "zod": "^3.23.8"
79
- },
80
- "devDependencies": {
81
- "@babel/cli": "^7.22.0",
82
- "@babel/core": "^7.22.0",
83
- "@babel/plugin-transform-runtime": "^7.22.0",
84
- "@babel/preset-env": "^7.22.0",
85
- "@babel/preset-react": "^7.22.0",
86
- "@babel/preset-typescript": "^7.28.5",
87
- "@babel/runtime": "^7.22.0",
88
- "@rollup/plugin-babel": "^6.0.0",
89
- "@rollup/plugin-commonjs": "^25.0.0",
90
- "@rollup/plugin-json": "^6.0.0",
91
- "@rollup/plugin-node-resolve": "^15.0.0",
92
- "@rollup/plugin-strip": "^3.0.0",
93
- "@rollup/plugin-typescript": "^11.0.0",
94
- "@testing-library/dom": "^10.4.1",
95
- "@testing-library/jest-dom": "^6.9.1",
96
- "@testing-library/react": "^14.0.0",
97
- "@testing-library/user-event": "^14.6.1",
98
- "babel-jest": "^30.2.0",
99
- "jest": "^30.2.0",
100
- "jest-environment-jsdom": "^30.2.0",
101
- "prettier": "^3.0.0",
102
- "react": "^18.2.0",
103
- "react-dom": "^18.2.0",
104
- "rollup": "^3.25.0",
105
- "rollup-plugin-peer-deps-external": "^2.2.4",
106
- "tslib": "^2.8.1",
107
- "typescript": "^5.0.0"
108
- },
109
- "publishConfig": {
110
- "access": "public"
111
- },
112
- "repository": {
113
- "type": "git",
114
- "url": "https://github.com/trops/dash-core.git"
115
- },
116
- "license": "MIT"
12
+ "./electron": {
13
+ "require": "./dist/electron/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "scripts/scanWidgetManifestCli.js"
19
+ ],
20
+ "bin": {
21
+ "dash-scan-manifest": "scripts/scanWidgetManifestCli.js"
22
+ },
23
+ "scripts": {
24
+ "build": "npm run build:renderer && npm run build:electron",
25
+ "build:renderer": "rollup -c rollup.config.renderer.mjs",
26
+ "build:electron": "rollup -c rollup.config.electron.mjs && mkdir -p dist/mcp && cp electron/mcp/mcpServerCatalog.json dist/mcp/ && cp electron/mcp/knownExternalMcpServers.json dist/mcp/ && rm -rf dist/mcp/servers && cp -r electron/mcp/servers dist/mcp/ && node scripts/inject-secrets.js",
27
+ "clean": "rm -rf dist",
28
+ "prepublishOnly": "npm run clean && npm run build",
29
+ "test:mcp": "node --test electron/controller/mcpController.test.js electron/mcp/mcpServerCatalog.test.js electron/mcp/installExternalMcpTool.test.js",
30
+ "test:untracked-pin": "node scripts/test-untracked-sources-pin.js",
31
+ "check:untracked": "node scripts/check-untracked-sources.js",
32
+ "test": "jest --watchAll=false",
33
+ "prettify": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\" \"electron/**/*.js\"",
34
+ "ci": "./scripts/ci.sh",
35
+ "ci:commit": "./scripts/ci.sh --commit",
36
+ "ci:push": "./scripts/ci.sh --push",
37
+ "ci:pr": "./scripts/ci.sh --pr",
38
+ "ci:release": "./scripts/ci.sh --release",
39
+ "prdize": "node scripts/prdize.js"
40
+ },
41
+ "peerDependencies": {
42
+ "@headlessui/react": "1.4",
43
+ "@heroicons/react": "^2.0.16",
44
+ "@trops/dash-react": ">=0.1.187",
45
+ "prop-types": "^15.8.1",
46
+ "react": "^18.2.0",
47
+ "react-dnd": "^16.0.1",
48
+ "react-dnd-html5-backend": "^16.0.1",
49
+ "react-dom": "^18.2.0",
50
+ "react-instantsearch-hooks-web": "^6.26.0",
51
+ "react-router-dom": "^6.3.0",
52
+ "tailwindcss": "^3.2.7"
53
+ },
54
+ "dependencies": {
55
+ "@anthropic-ai/sdk": "^0.39.0",
56
+ "@fortawesome/fontawesome-svg-core": "^6.1.1",
57
+ "@fortawesome/free-brands-svg-icons": "^6.1.1",
58
+ "@fortawesome/free-solid-svg-icons": "^6.1.1",
59
+ "@fortawesome/react-fontawesome": "^0.1.18",
60
+ "@modelcontextprotocol/sdk": "^1.26.0",
61
+ "adm-zip": "^0.5.16",
62
+ "algoliasearch": "^4.13.0",
63
+ "clsx": "^2.1.1",
64
+ "croner": "^10.0.1",
65
+ "css": "^3.0.0",
66
+ "csv-parser": "^3.0.0",
67
+ "deep-equal": "^2.2.0",
68
+ "electron-store": "^8.0.1",
69
+ "esbuild": "^0.25.12",
70
+ "JSONStream": "^1.3.5",
71
+ "live-plugin-manager": "^0.17.1",
72
+ "marked": "^17.0.5",
73
+ "minimist": "^1.2.8",
74
+ "node-forge": "^1.3.1",
75
+ "node-vibrant": "^4.0.4",
76
+ "objects-to-csv": "^1.3.6",
77
+ "openai": "^4.30.0",
78
+ "quickjs-emscripten": "^0.32.0",
79
+ "ws": "^8.19.0",
80
+ "xml2js": "^0.6.2",
81
+ "xtreamer": "^1.1.2",
82
+ "zod": "^3.23.8"
83
+ },
84
+ "devDependencies": {
85
+ "@babel/cli": "^7.22.0",
86
+ "@babel/core": "^7.22.0",
87
+ "@babel/plugin-transform-runtime": "^7.22.0",
88
+ "@babel/preset-env": "^7.22.0",
89
+ "@babel/preset-react": "^7.22.0",
90
+ "@babel/preset-typescript": "^7.28.5",
91
+ "@babel/runtime": "^7.22.0",
92
+ "@rollup/plugin-babel": "^6.0.0",
93
+ "@rollup/plugin-commonjs": "^25.0.0",
94
+ "@rollup/plugin-json": "^6.0.0",
95
+ "@rollup/plugin-node-resolve": "^15.0.0",
96
+ "@rollup/plugin-strip": "^3.0.0",
97
+ "@rollup/plugin-typescript": "^11.0.0",
98
+ "@testing-library/dom": "^10.4.1",
99
+ "@testing-library/jest-dom": "^6.9.1",
100
+ "@testing-library/react": "^14.0.0",
101
+ "@testing-library/user-event": "^14.6.1",
102
+ "babel-jest": "^30.2.0",
103
+ "jest": "^30.2.0",
104
+ "jest-environment-jsdom": "^30.2.0",
105
+ "prettier": "^3.0.0",
106
+ "react": "^18.2.0",
107
+ "react-dom": "^18.2.0",
108
+ "rollup": "^3.25.0",
109
+ "rollup-plugin-peer-deps-external": "^2.2.4",
110
+ "tslib": "^2.8.1",
111
+ "typescript": "^5.0.0"
112
+ },
113
+ "publishConfig": {
114
+ "access": "public"
115
+ },
116
+ "repository": {
117
+ "type": "git",
118
+ "url": "https://github.com/trops/dash-core.git"
119
+ },
120
+ "license": "MIT"
117
121
  }
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * scanWidgetManifestCli.js
4
+ *
5
+ * CLI shim around electron/utils/manifestScanner.js. Run from a widget
6
+ * package root to compare detected MCP usage against the package's
7
+ * `dash.permissions.mcp` block.
8
+ *
9
+ * Usage:
10
+ * npx dash-scan-manifest # scan ./, print diff (default --check)
11
+ * npx dash-scan-manifest <dir> # scan <dir>
12
+ * npx dash-scan-manifest --init # write missing manifest into package.json
13
+ * npx dash-scan-manifest --json # machine-readable output
14
+ *
15
+ * Exit codes:
16
+ * 0 no missing entries (manifest is complete or scan found nothing)
17
+ * 1 scan found tool usage not declared in the manifest
18
+ * 2 invalid arguments / unreadable directory
19
+ */
20
+ "use strict";
21
+
22
+ const fs = require("fs");
23
+ const path = require("path");
24
+
25
+ // Find the scanner in either the repo layout (electron/) or the
26
+ // published package layout (dist/electron/). Whichever exists wins.
27
+ const scannerPath = (() => {
28
+ const distPath = path.join(
29
+ __dirname,
30
+ "..",
31
+ "dist",
32
+ "electron",
33
+ "utils",
34
+ "manifestScanner.js",
35
+ );
36
+ if (fs.existsSync(distPath)) return distPath;
37
+ return path.join(__dirname, "..", "electron", "utils", "manifestScanner.js");
38
+ })();
39
+ const { scanForMcpUsage } = require(scannerPath);
40
+
41
+ function parseArgs(argv) {
42
+ const args = { dir: null, mode: "check", json: false };
43
+ for (const a of argv) {
44
+ if (a === "--init") args.mode = "init";
45
+ else if (a === "--check") args.mode = "check";
46
+ else if (a === "--json") args.json = true;
47
+ else if (a.startsWith("--")) {
48
+ console.error(`Unknown flag: ${a}`);
49
+ process.exit(2);
50
+ } else {
51
+ args.dir = a;
52
+ }
53
+ }
54
+ if (!args.dir) args.dir = process.cwd();
55
+ return args;
56
+ }
57
+
58
+ function readPackageJson(dir) {
59
+ const p = path.join(dir, "package.json");
60
+ if (!fs.existsSync(p)) return { path: p, pkg: null };
61
+ try {
62
+ return { path: p, pkg: JSON.parse(fs.readFileSync(p, "utf8")) };
63
+ } catch (e) {
64
+ console.error(`Could not read ${p}: ${e.message}`);
65
+ process.exit(2);
66
+ }
67
+ }
68
+
69
+ function getDeclaredManifest(pkg) {
70
+ return pkg?.dash?.permissions?.mcp || null;
71
+ }
72
+
73
+ function diff(detected, declared) {
74
+ // detected: { servers: { [name]: { tools[] } } }
75
+ // declared: { [name]: { tools[], readPaths[], writePaths[] } } | null
76
+ const missing = {}; // detected but not declared
77
+ const declaredServers = (declared && declared) || {};
78
+ for (const [name, entry] of Object.entries(detected.servers)) {
79
+ const declTools = declaredServers[name]?.tools || [];
80
+ const missingTools = entry.tools.filter((t) => !declTools.includes(t));
81
+ if (!declaredServers[name] || missingTools.length > 0) {
82
+ missing[name] = {
83
+ tools: missingTools.length > 0 ? missingTools : entry.tools,
84
+ };
85
+ }
86
+ }
87
+ return { missing };
88
+ }
89
+
90
+ function buildSyntheticManifest(detected) {
91
+ const out = {};
92
+ for (const [name, entry] of Object.entries(detected.servers)) {
93
+ out[name] = {
94
+ tools: entry.tools,
95
+ readPaths: [],
96
+ writePaths: [],
97
+ };
98
+ }
99
+ return out;
100
+ }
101
+
102
+ function main() {
103
+ const args = parseArgs(process.argv.slice(2));
104
+ const dir = path.resolve(args.dir);
105
+
106
+ if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {
107
+ console.error(`Directory not found: ${dir}`);
108
+ process.exit(2);
109
+ }
110
+
111
+ const detected = scanForMcpUsage({ dir });
112
+ const { path: pkgPath, pkg } = readPackageJson(dir);
113
+ const declared = getDeclaredManifest(pkg);
114
+ const d = diff(detected, declared);
115
+
116
+ if (args.json) {
117
+ console.log(
118
+ JSON.stringify(
119
+ {
120
+ dir,
121
+ detected: detected.servers,
122
+ declared: declared || null,
123
+ missing: d.missing,
124
+ warnings: detected.warnings,
125
+ },
126
+ null,
127
+ 2,
128
+ ),
129
+ );
130
+ process.exit(Object.keys(d.missing).length > 0 ? 1 : 0);
131
+ }
132
+
133
+ if (args.mode === "init") {
134
+ if (!pkg) {
135
+ console.error(
136
+ `No package.json found in ${dir}. --init requires an existing package.json.`,
137
+ );
138
+ process.exit(2);
139
+ }
140
+ if (declared) {
141
+ console.error(
142
+ `package.json already declares dash.permissions.mcp. --init refuses to overwrite. Use --check to see the diff.`,
143
+ );
144
+ process.exit(2);
145
+ }
146
+ pkg.dash = pkg.dash || {};
147
+ pkg.dash.permissions = pkg.dash.permissions || {};
148
+ pkg.dash.permissions.mcp = buildSyntheticManifest(detected);
149
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
150
+ console.log(`Wrote starter manifest to ${pkgPath}.`);
151
+ console.log(
152
+ "Review the readPaths and writePaths arrays — the scanner cannot infer paths.",
153
+ );
154
+ process.exit(0);
155
+ }
156
+
157
+ // --check (default)
158
+ console.log(`Scanned: ${dir}`);
159
+ if (Object.keys(detected.servers).length === 0) {
160
+ console.log("No literal MCP usage detected.");
161
+ } else {
162
+ console.log("\nDetected MCP usage:");
163
+ for (const [name, entry] of Object.entries(detected.servers)) {
164
+ console.log(
165
+ ` ${name}: ${entry.tools.join(", ") || "(no literal tools)"}`,
166
+ );
167
+ }
168
+ }
169
+
170
+ if (detected.warnings.length > 0) {
171
+ console.log(
172
+ `\n${detected.warnings.length} dynamic call(s) — scanner could not analyze:`,
173
+ );
174
+ for (const w of detected.warnings) {
175
+ console.log(` ${w.file}:${w.line} [${w.kind}] ${w.snippet}`);
176
+ }
177
+ }
178
+
179
+ if (declared) {
180
+ console.log("\nDeclared manifest:");
181
+ for (const [name, entry] of Object.entries(declared)) {
182
+ console.log(` ${name}: ${(entry.tools || []).join(", ") || "(empty)"}`);
183
+ }
184
+ } else {
185
+ console.log("\nNo dash.permissions.mcp block in package.json.");
186
+ }
187
+
188
+ if (Object.keys(d.missing).length > 0) {
189
+ console.log("\nMissing in manifest:");
190
+ for (const [name, entry] of Object.entries(d.missing)) {
191
+ console.log(` ${name}: ${entry.tools.join(", ")}`);
192
+ }
193
+ console.log(
194
+ "\nRun `dash-scan-manifest --init` to write a starter manifest.",
195
+ );
196
+ process.exit(1);
197
+ }
198
+ console.log("\nManifest looks complete.");
199
+ process.exit(0);
200
+ }
201
+
202
+ main();