superproductivity-mcp 1.2.6.dev9__tar.gz → 1.2.6.dev11__tar.gz

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 (27) hide show
  1. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/PKG-INFO +1 -1
  2. superproductivity_mcp-1.2.6.dev11/build-plugin.sh +44 -0
  3. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/plugin/index.html +102 -14
  4. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/plugin/manifest.json +1 -1
  5. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/plugin/plugin.js +14 -15
  6. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/pyproject.toml +1 -1
  7. superproductivity_mcp-1.2.6.dev9/build-plugin.sh +0 -23
  8. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.github/workflows/build.yml +0 -0
  9. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.github/workflows/publish-dev.yml +0 -0
  10. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.github/workflows/publish.yml +0 -0
  11. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.github/workflows/release.yml +0 -0
  12. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.github/workflows/version-gate.yml +0 -0
  13. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.gitignore +0 -0
  14. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.mcp.json.example +0 -0
  15. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/.mise.toml +0 -0
  16. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/LICENSE.txt +0 -0
  17. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/README.md +0 -0
  18. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/docs/superpowers/plans/2026-04-29-packaging-distribution.md +0 -0
  19. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/docs/superpowers/plans/2026-04-30-gitflow-ci.md +0 -0
  20. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/docs/superpowers/specs/2026-04-29-gitflow-ci-design.md +0 -0
  21. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/docs/superpowers/specs/2026-04-29-packaging-distribution-design.md +0 -0
  22. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/src/superproductivity_mcp/__init__.py +0 -0
  23. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/src/superproductivity_mcp/__main__.py +0 -0
  24. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/src/superproductivity_mcp/server.py +0 -0
  25. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/tests/__init__.py +0 -0
  26. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/tests/test_mcp_logic.py +0 -0
  27. {superproductivity_mcp-1.2.6.dev9 → superproductivity_mcp-1.2.6.dev11}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superproductivity-mcp
3
- Version: 1.2.6.dev9
3
+ Version: 1.2.6.dev11
4
4
  Summary: Super Productivity MCP server for Claude Desktop integration
5
5
  Project-URL: Homepage, https://github.com/ben-elliot-nice/superproductivity-mcp
6
6
  License-File: LICENSE.txt
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # Build the Super Productivity plugin zip for upload.
3
+ # Usage: ./build-plugin.sh
4
+ # Output: plugin/superproductivity-mcp-plugin-v<version>.zip (version read from plugin/manifest.json)
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ PLUGIN_DIR="$SCRIPT_DIR/plugin"
10
+ MANIFEST="$PLUGIN_DIR/manifest.json"
11
+
12
+ VERSION=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['version'])" "$MANIFEST")
13
+ OUT="$PLUGIN_DIR/superproductivity-mcp-plugin-v${VERSION}.zip"
14
+
15
+ echo "Building plugin v${VERSION}..."
16
+
17
+ # Remove any previous build of this version
18
+ rm -f "$OUT"
19
+
20
+ # Stamp version into a temp copy of index.html
21
+ TEMP_HTML="$(mktemp).html"
22
+ sed "s/__PLUGIN_VERSION__/${VERSION}/g" "$PLUGIN_DIR/index.html" > "$TEMP_HTML"
23
+ trap "rm -f '$TEMP_HTML'" EXIT
24
+
25
+ cd "$PLUGIN_DIR"
26
+ zip -j "$OUT" "$TEMP_HTML" manifest.json plugin.js "$SCRIPT_DIR/README.md"
27
+
28
+ # zip uses the temp filename — rename the entry to index.html inside the zip
29
+ python3 - <<PYEOF
30
+ import zipfile, os, shutil
31
+
32
+ out = "${OUT}"
33
+ tmp = out + ".tmp.zip"
34
+ with zipfile.ZipFile(out, 'r') as zin, zipfile.ZipFile(tmp, 'w', zipfile.ZIP_DEFLATED) as zout:
35
+ for item in zin.infolist():
36
+ data = zin.read(item.filename)
37
+ # Rename the temp html file entry to index.html
38
+ if item.filename.endswith('.html') and item.filename != 'index.html':
39
+ item.filename = 'index.html'
40
+ zout.writestr(item, data)
41
+ os.replace(tmp, out)
42
+ PYEOF
43
+
44
+ echo "Built: $OUT"
@@ -52,6 +52,7 @@
52
52
  .grid {
53
53
  display: grid;
54
54
  grid-template-columns: 1fr 1fr;
55
+ grid-template-rows: auto auto;
55
56
  gap: 1rem;
56
57
  margin-bottom: 1rem;
57
58
  }
@@ -63,6 +64,14 @@
63
64
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
64
65
  }
65
66
 
67
+ /* Settings spans both rows in right column */
68
+ .card-settings {
69
+ grid-column: 2;
70
+ grid-row: 1 / 3;
71
+ }
72
+
73
+ .full-width { grid-column: 1 / -1; }
74
+
66
75
  .card-header {
67
76
  display: flex;
68
77
  justify-content: space-between;
@@ -88,8 +97,6 @@
88
97
  .stat-label { font-weight: 500; }
89
98
  .stat-value { color: #b0b0b0; }
90
99
 
91
- .full-width { grid-column: 1 / -1; }
92
-
93
100
  /* Settings form — vertical layout */
94
101
  .form-group {
95
102
  display: flex;
@@ -158,6 +165,53 @@
158
165
  margin-top: 0.25rem;
159
166
  }
160
167
 
168
+ /* MCP Install card */
169
+ .install-hint {
170
+ font-size: 0.8125rem;
171
+ color: #b0b0b0;
172
+ margin-bottom: 0.75rem;
173
+ }
174
+
175
+ .install-code {
176
+ background: #141414;
177
+ border: 1px solid #404040;
178
+ border-radius: 4px;
179
+ padding: 0.75rem;
180
+ font-family: 'Courier New', monospace;
181
+ font-size: 0.8125rem;
182
+ color: #a8e6cf;
183
+ white-space: pre;
184
+ overflow-x: auto;
185
+ margin-bottom: 0.75rem;
186
+ line-height: 1.6;
187
+ }
188
+
189
+ .install-copy-row {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 0.75rem;
193
+ }
194
+
195
+ .copy-feedback {
196
+ font-size: 0.8125rem;
197
+ color: #4CAF50;
198
+ opacity: 0;
199
+ transition: opacity 0.3s;
200
+ }
201
+
202
+ .copy-feedback.visible { opacity: 1; }
203
+
204
+ .install-path-hint {
205
+ margin-top: 0.75rem;
206
+ font-size: 0.75rem;
207
+ color: #616161;
208
+ }
209
+
210
+ .install-path-hint code {
211
+ color: #888;
212
+ font-family: 'Courier New', monospace;
213
+ }
214
+
161
215
  /* Logs */
162
216
  .logs-container {
163
217
  background: #141414;
@@ -192,6 +246,7 @@
192
246
 
193
247
  @media (max-width: 768px) {
194
248
  .grid { grid-template-columns: 1fr; }
249
+ .card-settings { grid-column: 1; grid-row: auto; }
195
250
  }
196
251
  </style>
197
252
  </head>
@@ -204,7 +259,7 @@
204
259
  <div class="container">
205
260
  <div class="grid">
206
261
 
207
- <!-- Statistics Card -->
262
+ <!-- Statistics Card (left col, row 1) -->
208
263
  <div class="card">
209
264
  <div class="card-header">
210
265
  <h3>📊 Statistics</h3>
@@ -231,8 +286,8 @@
231
286
  </div>
232
287
  </div>
233
288
 
234
- <!-- Settings Card -->
235
- <div class="card">
289
+ <!-- Settings Card (right col, spans both rows) -->
290
+ <div class="card card-settings">
236
291
  <div class="card-header">
237
292
  <h3>⚙️ Settings</h3>
238
293
  </div>
@@ -272,7 +327,31 @@
272
327
  <button class="btn btn-primary btn-update" onclick="updatePollingFrequency()">Update Settings</button>
273
328
  </div>
274
329
 
275
- <!-- Activity Logs -->
330
+ <!-- MCP Install Card (left col, row 2) -->
331
+ <div class="card">
332
+ <div class="card-header">
333
+ <h3>🔌 Claude Desktop</h3>
334
+ </div>
335
+ <p class="install-hint">Add to your Claude Desktop config to use this plugin version:</p>
336
+ <div class="install-code" id="installSnippet">{
337
+ "mcpServers": {
338
+ "super-productivity": {
339
+ "command": "uvx",
340
+ "args": ["superproductivity-mcp==__PLUGIN_VERSION__"]
341
+ }
342
+ }
343
+ }</div>
344
+ <div class="install-copy-row">
345
+ <button class="btn btn-primary btn-sm" onclick="copyInstall()">Copy</button>
346
+ <span class="copy-feedback" id="copyFeedback">Copied!</span>
347
+ </div>
348
+ <p class="install-path-hint">
349
+ macOS: <code>~/Library/Application Support/Claude/claude_desktop_config.json</code><br>
350
+ Windows: <code>%APPDATA%\Claude\claude_desktop_config.json</code>
351
+ </p>
352
+ </div>
353
+
354
+ <!-- Activity Logs (full width) -->
276
355
  <div class="card full-width">
277
356
  <div class="card-header">
278
357
  <h3>📝 Activity Logs</h3>
@@ -369,10 +448,10 @@
369
448
  const uptime = Math.floor((Date.now() - bridgeStatus.stats.startTime) / 1000);
370
449
  document.getElementById('uptime').textContent = formatUptime(uptime);
371
450
 
372
- document.getElementById('mcpPath').textContent = bridgeStatus.mcpPath || '—';
373
- document.getElementById('commandsDir').textContent = bridgeStatus.commandsDir || '—';
451
+ document.getElementById('mcpPath').textContent = bridgeStatus.mcpPath || '—';
452
+ document.getElementById('commandsDir').textContent = bridgeStatus.commandsDir || '—';
374
453
  document.getElementById('responsesDir').textContent = bridgeStatus.responsesDir || '—';
375
- document.getElementById('pollingFrequency').value = bridgeStatus.pollingFrequency;
454
+ document.getElementById('pollingFrequency').value = bridgeStatus.pollingFrequency;
376
455
  }
377
456
 
378
457
  function formatUptime(seconds) {
@@ -384,6 +463,15 @@
384
463
  return `${s}s`;
385
464
  }
386
465
 
466
+ function copyInstall() {
467
+ const text = document.getElementById('installSnippet').textContent;
468
+ navigator.clipboard.writeText(text).then(() => {
469
+ const fb = document.getElementById('copyFeedback');
470
+ fb.classList.add('visible');
471
+ setTimeout(() => fb.classList.remove('visible'), 2000);
472
+ });
473
+ }
474
+
387
475
  function addLogEntry(message, level = 'info', timestamp = null) {
388
476
  const logsContainer = document.getElementById('logsContainer');
389
477
  const cssLevel = level === 'warn' ? 'warning' : level;
@@ -463,12 +551,12 @@
463
551
  if (status) {
464
552
  syncLogBuffer(status.logBuffer);
465
553
  updateBridgeStatus({
466
- status: { type: status.isInitialized ? 'connected' : 'disconnected' },
467
- mcpPath: status.mcpServerPath,
468
- commandDir: status.commandDir,
554
+ status: { type: status.isInitialized ? 'connected' : 'disconnected' },
555
+ mcpPath: status.mcpServerPath,
556
+ commandDir: status.commandDir,
469
557
  responseDir: status.responseDir,
470
- stats: status.stats,
471
- config: status.config
558
+ stats: status.stats,
559
+ config: status.config
472
560
  });
473
561
  }
474
562
  }
@@ -2,7 +2,7 @@
2
2
  "id": "sp-mcp-bridge",
3
3
  "name": "MCP Bridge",
4
4
  "description": "Bridge between Super Productivity and MCP (Model Context Protocol) servers for Claude Desktop integration",
5
- "version": "1.2.6.dev9",
5
+ "version": "1.2.6.dev11",
6
6
  "manifestVersion": 1,
7
7
  "author": "Super Productivity Team",
8
8
  "homepage": "https://github.com/johannesjo/super-productivity",
@@ -556,26 +556,25 @@ class MCPBridgePlugin {
556
556
  }
557
557
  }
558
558
 
559
- // Step 2: Remove subtasks from project taskIds tasks created without parentId
560
- // get added to project.taskIds by SP; later setting parentId doesn't remove them,
561
- // causing double-display (root AND nested). Fix: remove any task with parentId from
562
- // its project's taskIds, grouped by project to avoid multiple updates per project.
559
+ // Step 2: Build authoritative set of all task IDs that are subtasks of anything.
560
+ // Use subTaskIds scan (not parentId) more reliable since parentId may be stale/missing.
561
+ const knownSubtaskIds = new Set(
562
+ allTasks.flatMap(t => t.subTaskIds || [])
563
+ );
564
+
565
+ // Remove any task from project.taskIds that is a known subtask.
566
+ // Tasks created without parentId get added to project.taskIds by SP; later
567
+ // parentId/subTaskIds updates don't remove them, causing double-display.
563
568
  const projects = await PluginAPI.getAllProjects();
564
569
  for (const project of projects) {
565
- const subtaskIdsInProject = (project.taskIds || []).filter(id => {
566
- const t = taskMap.get(id);
567
- return t && t.parentId;
568
- });
569
- if (subtaskIdsInProject.length > 0) {
570
+ const wronglyInProject = (project.taskIds || []).filter(id => knownSubtaskIds.has(id));
571
+ if (wronglyInProject.length > 0) {
570
572
  try {
571
- const cleaned = (project.taskIds || []).filter(id => {
572
- const t = taskMap.get(id);
573
- return !t || !t.parentId;
574
- });
573
+ const cleaned = (project.taskIds || []).filter(id => !knownSubtaskIds.has(id));
575
574
  await PluginAPI.updateProject(project.id, { taskIds: cleaned });
576
- fixes.push(`project taskIds: removed ${subtaskIdsInProject.length} subtasks from "${project.title}"`);
575
+ fixes.push(`project "${project.title}": removed ${wronglyInProject.length} subtasks from root list`);
577
576
  } catch (e) {
578
- errors.push(`failed to fix taskIds for project "${project.title}": ${e.message}`);
577
+ errors.push(`failed to clean project "${project.title}": ${e.message}`);
579
578
  }
580
579
  }
581
580
  }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superproductivity-mcp"
3
- version = "1.2.6.dev9"
3
+ version = "1.2.6.dev11"
4
4
  description = "Super Productivity MCP server for Claude Desktop integration"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Build the Super Productivity plugin zip for upload.
3
- # Usage: ./build-plugin.sh
4
- # Output: plugin/superproductivity-mcp-plugin-v<version>.zip (version read from plugin/manifest.json)
5
-
6
- set -euo pipefail
7
-
8
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- PLUGIN_DIR="$SCRIPT_DIR/plugin"
10
- MANIFEST="$PLUGIN_DIR/manifest.json"
11
-
12
- VERSION=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['version'])" "$MANIFEST")
13
- OUT="$PLUGIN_DIR/superproductivity-mcp-plugin-v${VERSION}.zip"
14
-
15
- echo "Building plugin v${VERSION}..."
16
-
17
- # Remove any previous build of this version
18
- rm -f "$OUT"
19
-
20
- cd "$PLUGIN_DIR"
21
- zip -j "$OUT" index.html manifest.json plugin.js "$SCRIPT_DIR/README.md"
22
-
23
- echo "Built: $OUT"