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 +10 -0
- package/dist/dashboard/http-server.d.ts.map +1 -1
- package/dist/dashboard/http-server.js +15 -6
- package/dist/dashboard/http-server.js.map +1 -1
- package/dist/dashboard/public/app.js +14 -1
- package/dist/dashboard/public/index.html +1 -1
- package/package.json +8 -2
- package/src/dashboard/public/app.js +14 -1
- package/src/dashboard/public/index.html +1 -1
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;
|
|
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
|
|
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({
|
|
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
|
|
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
|
|
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
|
-
|
|
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">☽</span>
|
|
61
61
|
</button>
|
|
62
|
-
<a href="https://github.com/
|
|
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.
|
|
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
|
-
|
|
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">☽</span>
|
|
61
61
|
</button>
|
|
62
|
-
<a href="https://github.com/
|
|
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>
|