@slack/radar-mcp 1.4.0 → 1.6.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.
@@ -5,12 +5,17 @@
5
5
  * and the same validate/coerce pass runs on every push so a malformed spec surfaces
6
6
  * an error instead of rendering silent zeros.
7
7
  *
8
- * Scope note: this port covers the STREAMING sources only. The on-device SQLite
9
- * browser (`source: "db"`) from the original PoC is intentionally omitted here and
10
- * tracked as a separate change; `SOURCES` therefore does not include "db".
8
+ * Most sources are live STREAMS (network/rtm/clog/log/all). `db` is the odd one out:
9
+ * a read-only, point-in-time SQLite BROWSER over the on-device databases, with no viz /
10
+ * series / match (it has its own list -> tables -> query-grid view). The coerce and
11
+ * validate passes short-circuit for `db` accordingly.
11
12
  */
12
- /** Streaming sources the dashboard can read. "all" is the unified timeline. */
13
- export declare const SOURCES: readonly ["rtm", "network", "clog", "log", "all"];
13
+ /**
14
+ * Sources the dashboard can read. The first five are live streams; "all" is their unified
15
+ * timeline. "db" is a read-only on-device SQLite browser (a point-in-time snapshot, not a
16
+ * stream) and is handled as a distinct view.
17
+ */
18
+ export declare const SOURCES: readonly ["rtm", "network", "clog", "log", "all", "db"];
14
19
  export type Source = (typeof SOURCES)[number];
15
20
  /** Widgets a spec may compose. */
16
21
  export declare const VIZ: readonly ["counter", "rate", "sparkline", "feed", "inspector", "graph"];
@@ -62,6 +67,9 @@ export interface Spec {
62
67
  extract?: Extract;
63
68
  highlight?: Highlight;
64
69
  alert?: Alert;
70
+ db?: string;
71
+ table?: string;
72
+ sql?: string;
65
73
  [key: string]: unknown;
66
74
  }
67
75
  /** The empty dashboard. Rendered until a spec is pushed. */
package/dist/web/spec.js CHANGED
@@ -5,12 +5,17 @@
5
5
  * and the same validate/coerce pass runs on every push so a malformed spec surfaces
6
6
  * an error instead of rendering silent zeros.
7
7
  *
8
- * Scope note: this port covers the STREAMING sources only. The on-device SQLite
9
- * browser (`source: "db"`) from the original PoC is intentionally omitted here and
10
- * tracked as a separate change; `SOURCES` therefore does not include "db".
8
+ * Most sources are live STREAMS (network/rtm/clog/log/all). `db` is the odd one out:
9
+ * a read-only, point-in-time SQLite BROWSER over the on-device databases, with no viz /
10
+ * series / match (it has its own list -> tables -> query-grid view). The coerce and
11
+ * validate passes short-circuit for `db` accordingly.
11
12
  */
12
- /** Streaming sources the dashboard can read. "all" is the unified timeline. */
13
- export const SOURCES = ["rtm", "network", "clog", "log", "all"];
13
+ /**
14
+ * Sources the dashboard can read. The first five are live streams; "all" is their unified
15
+ * timeline. "db" is a read-only on-device SQLite browser (a point-in-time snapshot, not a
16
+ * stream) and is handled as a distinct view.
17
+ */
18
+ export const SOURCES = ["rtm", "network", "clog", "log", "all", "db"];
14
19
  /** Widgets a spec may compose. */
15
20
  export const VIZ = [
16
21
  "counter",
@@ -45,6 +50,9 @@ export function coerceSpec(input) {
45
50
  if (!isRecord(input))
46
51
  return BLANK_SPEC;
47
52
  const s = input;
53
+ // The DB browser has no match/viz/series to repair; leave its db/table/sql untouched.
54
+ if (s.source === "db")
55
+ return s;
48
56
  if (typeof s.match === "string") {
49
57
  // "all" mixes types whose summary fields differ, so a single field guess
50
58
  // would wrongly exclude other types; treat a bare-string match on "all"
@@ -90,6 +98,16 @@ export function validateSpec(s) {
90
98
  if (!spec.source || !SOURCES.includes(spec.source)) {
91
99
  return `source must be one of ${SOURCES.join("|")}`;
92
100
  }
101
+ // The DB browser is a distinct view: no viz/series/match. Only its optional deep-link
102
+ // fields are constrained (each must be a string when present).
103
+ if (spec.source === "db") {
104
+ for (const k of ["db", "table", "sql"]) {
105
+ if (spec[k] !== undefined && typeof spec[k] !== "string") {
106
+ return `${k} must be a string`;
107
+ }
108
+ }
109
+ return null;
110
+ }
93
111
  if (spec.match !== undefined && !isRecord(spec.match)) {
94
112
  return "match must be an object";
95
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slack/radar-mcp",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "MCP server and web dashboard for on-device debugging of the Slack Android app via ADB",
5
5
  "type": "module",
6
6
  "main": "dist/mcp/index.js",
@@ -16,7 +16,8 @@
16
16
  "scripts": {
17
17
  "clean": "rm -rf dist",
18
18
  "prebuild": "npm run clean",
19
- "build": "tsc && cp -r src/web/public dist/web/public && chmod +x dist/mcp/index.js dist/web/bin.js",
19
+ "copy-vendor": "node scripts/copy-vendor.mjs",
20
+ "build": "tsc && cp -r src/web/public dist/web/public && npm run copy-vendor && chmod +x dist/mcp/index.js dist/web/bin.js",
20
21
  "start": "node dist/mcp/index.js",
21
22
  "start:web": "node dist/web/bin.js",
22
23
  "watch": "tsc --watch",
@@ -49,6 +50,8 @@
49
50
  },
50
51
  "devDependencies": {
51
52
  "@types/node": "^22.10.5",
53
+ "htm": "^3.1.1",
54
+ "preact": "^10.29.3",
52
55
  "typescript": "^5.7.2"
53
56
  }
54
57
  }