twining-mcp 1.8.0 → 1.8.2

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/README.md CHANGED
@@ -145,6 +145,16 @@ The plugin handles agent instructions automatically via skills. For the MCP-only
145
145
 
146
146
  A web dashboard starts automatically at `http://localhost:24282` — browse decisions, blackboard entries, knowledge graph, and agent state. Configurable via `TWINING_DASHBOARD_PORT`.
147
147
 
148
+ <p align="center">
149
+ <img src="assets/dashboard-stats.png" alt="Dashboard — Stats overview" width="700"><br>
150
+ <em>Stats overview: blackboard entries, decisions, graph entities, and activity breakdown</em>
151
+ </p>
152
+
153
+ <p align="center">
154
+ <img src="assets/dashboard-graph.png" alt="Dashboard — Knowledge graph" width="700"><br>
155
+ <em>Interactive knowledge graph: files, decisions, classes, and their relationships</em>
156
+ </p>
157
+
148
158
  ## What's Inside
149
159
 
150
160
  ### Persistent Decisions
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAkI7B;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CA8B/D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAsCvD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAiBpE"}
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAyI7B;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAqC/D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAwCvD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAiBpE"}
@@ -12,10 +12,11 @@ import { fileURLToPath } from "node:url";
12
12
  import { getDashboardConfig } from "./dashboard-config.js";
13
13
  import { createApiHandler } from "./api-routes.js";
14
14
  /**
15
- * Check if a Twining dashboard is already running on the given port.
16
- * Returns true if a health check confirms another instance.
15
+ * Check if a Twining dashboard for the SAME project is already running on the given port.
16
+ * Returns true only when another instance serves the same projectRoot.
17
+ * Different-project dashboards are not considered duplicates.
17
18
  */
18
- function isExistingDashboard(port) {
19
+ function isExistingDashboard(port, projectRoot) {
19
20
  return new Promise((resolve) => {
20
21
  const req = http.get({ hostname: "127.0.0.1", port, path: "/api/health", timeout: 1000 }, (res) => {
21
22
  let body = "";
@@ -25,7 +26,8 @@ function isExistingDashboard(port) {
25
26
  res.on("end", () => {
26
27
  try {
27
28
  const data = JSON.parse(body);
28
- resolve(data.server === "twining-mcp");
29
+ resolve(data.server === "twining-mcp" &&
30
+ data.projectRoot === projectRoot);
29
31
  }
30
32
  catch {
31
33
  resolve(false);
@@ -126,6 +128,7 @@ function tryListen(server, port, maxRetries) {
126
128
  export function handleRequest(publicDir, projectRoot) {
127
129
  const staticHandler = serveStatic(publicDir);
128
130
  const apiHandler = createApiHandler(projectRoot);
131
+ const resolvedProjectRoot = path.resolve(projectRoot);
129
132
  return (req, res) => {
130
133
  // Try API routes first (async)
131
134
  apiHandler(req, res)
@@ -137,7 +140,11 @@ export function handleRequest(publicDir, projectRoot) {
137
140
  res.writeHead(200, {
138
141
  "Content-Type": "application/json; charset=utf-8",
139
142
  });
140
- res.end(JSON.stringify({ ok: true, server: "twining-mcp" }));
143
+ res.end(JSON.stringify({
144
+ ok: true,
145
+ server: "twining-mcp",
146
+ projectRoot: resolvedProjectRoot,
147
+ }));
141
148
  return;
142
149
  }
143
150
  // Fall through to static file serving
@@ -176,7 +183,9 @@ export async function startDashboard(projectRoot) {
176
183
  // If we bound to a different port than requested, check if another
177
184
  // dashboard instance is already running on the original port.
178
185
  // This prevents opening duplicate tabs when multiple MCP instances start.
179
- const skipOpen = port !== config.port && (await isExistingDashboard(config.port));
186
+ const resolvedRoot = path.resolve(projectRoot);
187
+ const skipOpen = port !== config.port &&
188
+ (await isExistingDashboard(config.port, resolvedRoot));
180
189
  if (skipOpen) {
181
190
  console.error(`[twining] Dashboard already running on port ${config.port}, skipping auto-open`);
182
191
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAClB,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,EACnE,CAAC,GAAG,EAAE,EAAE;YACN,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,GAA2B;IACzC,OAAO,EAAE,0BAA0B;IACnC,MAAM,EAAE,yBAAyB;IACjC,KAAK,EAAE,uCAAuC;IAC9C,OAAO,EAAE,iCAAiC;IAC1C,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,cAAc;CACvB,CAAC;AAEF;;;GAGG;AACH,SAAS,WAAW,CAClB,SAAiB;IAEjB,OAAO,KAAK,EAAE,GAAyB,EAAE,GAAwB,EAAE,EAAE;QACnE,6EAA6E;QAC7E,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEhD,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,0BAA0B;aAC9D,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,IAAI,GACR,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG;gBACnC,CAAC,CAAE,GAA6B,CAAC,IAAI;gBACrC,CAAC,CAAC,SAAS,CAAC;YAChB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAChB,MAAmB,EACnB,IAAY,EACZ,UAAkB;IAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,SAAS,OAAO,CAAC,WAAmB;YAClC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;gBAClD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;oBACvD,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE;gBAC3C,kEAAkE;gBAClE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,UAAU,GACd,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;gBACtE,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,WAAmB;IAEnB,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAEjD,OAAO,CAAC,GAAyB,EAAE,GAAwB,EAAE,EAAE;QAC7D,+BAA+B;QAC/B,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;aACjB,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAChB,IAAI,OAAO;gBAAE,OAAO;YAEpB,wBAAwB;YACxB,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,EAAE,CAAC;gBAC9B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBACjB,cAAc,EAAE,iCAAiC;iBAClD,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YAED,sCAAsC;YACtC,OAAO,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACtB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAmB;IAEnB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2DAA2D;IAC3D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAErD,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;IACvC,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IAE7C,2CAA2C;IAC3C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,mEAAmE;QACnE,8DAA8D;QAC9D,0EAA0E;QAC1E,MAAM,QAAQ,GACZ,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,+CAA+C,MAAM,CAAC,IAAI,sBAAsB,CACjF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC;iBACX,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;iBAC/B,KAAK,CAAC,GAAG,EAAE;gBACV,mEAAmE;YACrE,CAAC,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAuB;IAC5D,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,wBAAwB;QAC1B,CAAC,CAAC,CAAC;QACH,4CAA4C;QAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,6CAA6C;QAC7C,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../../src/dashboard/http-server.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,18 @@ var state = {
29
29
  sessionEnded: false
30
30
  };
31
31
 
32
+ /* URL parameter overrides (e.g. ?poll=1000&demo=1 for faster refresh during demos) */
33
+ (function() {
34
+ var params = new URLSearchParams(window.location.search);
35
+ var poll = parseInt(params.get('poll'), 10);
36
+ if (poll && poll >= 500 && poll <= 30000) {
37
+ state.pollInterval = poll;
38
+ }
39
+ if (params.get('demo') === '1') {
40
+ state.demoMode = true;
41
+ }
42
+ })();
43
+
32
44
  /* ========== Debounce Utility ========== */
33
45
 
34
46
  function debounce(fn, delay) {
@@ -96,7 +108,8 @@ function updateConnectionIndicator() {
96
108
  if (state.wasConnected) {
97
109
  state.disconnectCount++;
98
110
  // After 3 consecutive failed polls (~9 seconds), show session ended overlay
99
- if (state.disconnectCount >= 3 && !state.sessionEnded) {
111
+ // In demo mode, never show session ended (server restarts between acts)
112
+ if (state.disconnectCount >= 3 && !state.sessionEnded && !state.demoMode) {
100
113
  showSessionEnded();
101
114
  }
102
115
  }
@@ -59,7 +59,7 @@
59
59
  <button id="theme-toggle" title="Toggle theme" aria-label="Toggle theme">
60
60
  <span id="theme-icon">&#9789;</span>
61
61
  </button>
62
- <a href="https://github.com/twining-mcp/twining-mcp" target="_blank" rel="noopener noreferrer" class="github-link" title="View on GitHub">
62
+ <a href="https://github.com/daveangulo/twining-mcp" target="_blank" rel="noopener noreferrer" class="github-link" title="View on GitHub">
63
63
  <svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>
64
64
  </a>
65
65
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twining-mcp",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "Agent coordination MCP server and Claude Code plugin — shared blackboard, decision tracking, and context assembly",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -18,7 +18,9 @@
18
18
  "build": "tsc",
19
19
  "postbuild": "rm -rf dist/dashboard/public && cp -r src/dashboard/public dist/dashboard/public",
20
20
  "test": "vitest run",
21
- "test:watch": "vitest"
21
+ "test:watch": "vitest",
22
+ "demo:record": "npx tsx examples/demo-automation/playwright/record-demo.ts",
23
+ "demo:record:pause": "DEMO_PAUSE=1 npx tsx examples/demo-automation/playwright/record-demo.ts"
22
24
  },
23
25
  "keywords": [
24
26
  "mcp",
@@ -34,6 +36,9 @@
34
36
  ],
35
37
  "author": "Dave Angulo",
36
38
  "license": "MIT",
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
37
42
  "repository": {
38
43
  "type": "git",
39
44
  "url": "git+https://github.com/daveangulo/twining-mcp.git"
@@ -56,6 +61,7 @@
56
61
  "posthog-node": "^4.18.0"
57
62
  },
58
63
  "devDependencies": {
64
+ "@playwright/test": "^1.52.0",
59
65
  "@types/js-yaml": "^4.0.9",
60
66
  "@types/node": "^25.2.3",
61
67
  "@types/proper-lockfile": "^4.1.4",
@@ -29,6 +29,18 @@ var state = {
29
29
  sessionEnded: false
30
30
  };
31
31
 
32
+ /* URL parameter overrides (e.g. ?poll=1000&demo=1 for faster refresh during demos) */
33
+ (function() {
34
+ var params = new URLSearchParams(window.location.search);
35
+ var poll = parseInt(params.get('poll'), 10);
36
+ if (poll && poll >= 500 && poll <= 30000) {
37
+ state.pollInterval = poll;
38
+ }
39
+ if (params.get('demo') === '1') {
40
+ state.demoMode = true;
41
+ }
42
+ })();
43
+
32
44
  /* ========== Debounce Utility ========== */
33
45
 
34
46
  function debounce(fn, delay) {
@@ -96,7 +108,8 @@ function updateConnectionIndicator() {
96
108
  if (state.wasConnected) {
97
109
  state.disconnectCount++;
98
110
  // After 3 consecutive failed polls (~9 seconds), show session ended overlay
99
- if (state.disconnectCount >= 3 && !state.sessionEnded) {
111
+ // In demo mode, never show session ended (server restarts between acts)
112
+ if (state.disconnectCount >= 3 && !state.sessionEnded && !state.demoMode) {
100
113
  showSessionEnded();
101
114
  }
102
115
  }
@@ -59,7 +59,7 @@
59
59
  <button id="theme-toggle" title="Toggle theme" aria-label="Toggle theme">
60
60
  <span id="theme-icon">&#9789;</span>
61
61
  </button>
62
- <a href="https://github.com/twining-mcp/twining-mcp" target="_blank" rel="noopener noreferrer" class="github-link" title="View on GitHub">
62
+ <a href="https://github.com/daveangulo/twining-mcp" target="_blank" rel="noopener noreferrer" class="github-link" title="View on GitHub">
63
63
  <svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>
64
64
  </a>
65
65
  </div>