From 1bd570c552b2905c74c856fa242f01020a12f738 Mon Sep 17 00:00:00 2001 From: Melvin Carvalho Date: Thu, 11 Jun 2026 07:59:12 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20bump=20to=200.0.48=20=E2=80=94=20ship?= =?UTF-8?q?=20pane=20features,=20prune=20dead=20scripts,=20track=20MCP=20t?= =?UTF-8?q?ools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bump version 0.0.47 -> 0.0.48 (unpublished pane work from #72 and #74: bookmark enrichment rendering and the searchable collection pane) - Remove one-off ASCII-banner dev scripts (count-ascii.js, count-banner.js, jspod-ascii.js, verify-spacing.js) — referenced nowhere and never published - Track MCP dev tools mcp.js and refresh-mcp-token.sh (outside the npm 'files' allowlist, so not published) - Add CHANGELOG.md recording the 0.0.48 diff vs 0.0.47 Verified: npm pack --dry-run shows 0.0.48 with no dev tools in the tarball; node --check / bash -n pass on all touched scripts. Fixes #75 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++ count-ascii.js | 31 ----------------------------- count-banner.js | 28 --------------------------- jspod-ascii.js | 41 --------------------------------------- mcp.js | 46 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- refresh-mcp-token.sh | 21 ++++++++++++++++++++ verify-spacing.js | 20 ------------------- 8 files changed, 100 insertions(+), 121 deletions(-) create mode 100644 CHANGELOG.md delete mode 100644 count-ascii.js delete mode 100644 count-banner.js delete mode 100644 jspod-ascii.js create mode 100644 mcp.js create mode 100755 refresh-mcp-token.sh delete mode 100644 verify-spacing.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ee2a526 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + +## 0.0.48 — 2026-06-11 + +Changes since 0.0.47 (`a57b66e..`): + +### Features + +- **panes**: render bookmark enrichment — summary, tags, hero image (#71, #72) +- **panes**: searchable bookmark collection pane + container-pane support (#73, #74) + +### Housekeeping + +- Removed one-off ASCII-banner dev scripts (`count-ascii.js`, `count-banner.js`, `jspod-ascii.js`, `verify-spacing.js`) — referenced nowhere, never published (#75) +- Tracked MCP dev tools (not published to npm): + - `mcp.js` — minimal Streamable-HTTP MCP client for the local pod + - `refresh-mcp-token.sh` — re-mints a 1h owner token and registers the pod's `/mcp` endpoint as the `jspod` MCP server in Claude Code + +### Published diff vs 0.0.47 + +``` + data-browser-panes.js | 57 +++++++++++++++------ + examples/panes/bookmark-collection.js | 96 +++++++++++++++++++++++++++++++++++ + examples/panes/bookmark.js | 82 +++++++++++++++++++++++++----- + 3 files changed, 207 insertions(+), 28 deletions(-) +``` + +## 0.0.47 + +- Publish `data-browser-panes.js` + `--browser panes`, a pane-aware data browser augmented by local panes (#69, #70) + +Earlier releases predate this changelog — see `git log` for history. diff --git a/count-ascii.js b/count-ascii.js deleted file mode 100644 index d77ecf3..0000000 --- a/count-ascii.js +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env node - -// Count from user's screenshot -const lines = [ - ' ██╗███████╗███████╗██████╗ ', - ' ██║██╔════╝██╔════╝██╔══██╗ ', - ' ██║███████╗███████╗██║ ██║ ', - ' ██ ██║╚════██║╚════██║██║ ██║ ', - ' ╚█████╔╝███████║███████║██████╔╝ ', - ' ╚════╝ ╚══════╝╚══════╝╚═════╝ ', -]; - -console.log('Current line lengths:\n'); -lines.forEach((line, i) => { - console.log(`Row ${i + 3}: ${line.length} chars`); -}); - -// Measure the ASCII content itself -const asciiLines = [ - ' ██╗███████╗███████╗██████╗ ', - ' ██║██╔════╝██╔════╝██╔══██╗', - ' ██║███████╗███████╗██║ ██║', - '██ ██║╚════██║╚════██║██║ ██║', - '╚█████╔╝███████║███████║██████╔╝', - ' ╚════╝ ╚══════╝╚══════╝╚═════╝ ', -]; - -console.log('\nASCII content lengths:\n'); -asciiLines.forEach((line, i) => { - console.log(`Line ${i + 1}: "${line}" = ${line.length} chars`); -}); diff --git a/count-banner.js b/count-banner.js deleted file mode 100644 index 17eb304..0000000 --- a/count-banner.js +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env node - -// Count characters in the new banner lines - -const lines = [ - ' ', // Line 83 (empty) - ' ██╗███████╗███████╗██████╗ ', // Line 84 - ' ██║██╔════╝██╔════╝██╔══██╗ ', // Line 85 - ' ██║███████╗███████╗██║ ██║ ', // Line 86 - ' ██ ██║╚════██║╚════██║██║ ██║ ', // Line 87 - ' ╚█████╔╝███████║███████║██████╔╝ ', // Line 88 - ' ╚════╝ ╚══════╝╚══════╝╚═════╝ ', // Line 89 - ' ', // Line 90 (empty) - ' JavaScript Solid Pod ', // Line 91 (NEW) - ' Batteries included, just works ', // Line 92 - ' ', // Line 93 (empty) -]; - -console.log('Banner line lengths:\n'); -lines.forEach((line, i) => { - const lineNum = 83 + i; - console.log(`Line ${lineNum}: ${line.length} chars | "${line}"`); -}); - -// Check the text content lengths -console.log('\nText content only:'); -console.log(`"JavaScript Solid Pod" = ${'JavaScript Solid Pod'.length} chars`); -console.log(`"Batteries included, just works" = ${'Batteries included, just works'.length} chars`); diff --git a/jspod-ascii.js b/jspod-ascii.js deleted file mode 100644 index 5f3a3af..0000000 --- a/jspod-ascii.js +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node - -// Generate jspod ASCII art with proper spacing - -const asciiLines = [ - ' ██╗███████╗██████╗ ██████╗ ██████╗ ', - ' ██║██╔════╝██╔══██╗██╔═══██╗██╔══██╗', - ' ██║███████╗██████╔╝██║ ██║██║ ██║', - '██ ██║╚════██║██╔═══╝ ██║ ██║██║ ██║', - '╚█████╔╝███████║██║ ╚██████╔╝██████╔╝', - ' ╚════╝ ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ', -]; - -console.log('ASCII art content lengths:\n'); -asciiLines.forEach((line, i) => { - console.log(`Row ${i + 1}: ${line.length} chars | "${line}"`); -}); - -// Calculate spacing for 67-char total -const targetLength = 67; -console.log('\nSpacing calculation:'); -asciiLines.forEach((line, i) => { - const contentLength = line.length; - const spacesNeeded = targetLength - contentLength; - const leftSpaces = Math.floor(spacesNeeded / 2); - const rightSpaces = spacesNeeded - leftSpaces; - - console.log(`Row ${i + 1}: ${leftSpaces} left + ${contentLength} content + ${rightSpaces} right = ${leftSpaces + contentLength + rightSpaces}`); -}); - -// Generate the properly spaced lines -console.log('\nProperly formatted banner lines:\n'); -asciiLines.forEach((line, i) => { - const contentLength = line.length; - const spacesNeeded = targetLength - contentLength; - const leftSpaces = Math.floor(spacesNeeded / 2); - const rightSpaces = spacesNeeded - leftSpaces; - - const formatted = ' '.repeat(leftSpaces) + line + ' '.repeat(rightSpaces); - console.log(`Line ${i + 1}: "${formatted}" (${formatted.length} chars)`); -}); diff --git a/mcp.js b/mcp.js new file mode 100644 index 0000000..89b2e69 --- /dev/null +++ b/mcp.js @@ -0,0 +1,46 @@ +#!/usr/bin/env node +// Minimal MCP (Streamable-HTTP) client for the local jss pod. +// Usage: node mcp.mjs '' | node mcp.mjs --list +const POD = process.env.POD || 'http://localhost:5444'; +const U = process.env.POD_USER || 'me', P = process.env.POD_PASS || 'me'; + +async function token() { + const r = await fetch(`${POD}/idp/credentials`, { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username: U, password: P }), + }); + const j = await r.json(); + if (!j.access_token) throw new Error('auth failed: ' + JSON.stringify(j)); + return j.access_token; +} + +async function rpc(tok, method, params) { + const r = await fetch(`${POD}/mcp`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${tok}`, + 'Content-Type': 'application/json', + 'Accept': 'application/json, text/event-stream', + }, + body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }), + }); + const text = await r.text(); + // handle both plain JSON and SSE framing + const line = text.includes('data:') ? text.split('\n').filter(l => l.startsWith('data:')).map(l => l.slice(5).trim()).join('') : text; + return JSON.parse(line); +} + +const [, , tool, argstr] = process.argv; +const tok = await token(); + +if (tool === '--list') { + const r = await rpc(tok, 'tools/list', {}); + for (const t of r.result.tools) console.log(`${t.name}\t${(t.description || '').split('\n')[0]}`); + process.exit(0); +} + +const args = argstr ? JSON.parse(argstr) : {}; +const r = await rpc(tok, 'tools/call', { name: tool, arguments: args }); +if (r.error) { console.error('ERR', JSON.stringify(r.error)); process.exit(1); } +const out = r.result?.content?.map(c => c.text ?? JSON.stringify(c)).join('\n') ?? JSON.stringify(r.result); +console.log(out); diff --git a/package.json b/package.json index c8a4ceb..09dfda6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspod", - "version": "0.0.47", + "version": "0.0.48", "description": "JavaScript Solid Pod - Just works, batteries included", "type": "module", "main": "./lib/index.js", diff --git a/refresh-mcp-token.sh b/refresh-mcp-token.sh new file mode 100755 index 0000000..7f15bad --- /dev/null +++ b/refresh-mcp-token.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Re-mint a 1h owner Bearer token from the local jss IdP and (re)register +# the pod's /mcp endpoint as the "jspod" MCP server in Claude Code. +# Usage: ./refresh-mcp-token.sh +set -euo pipefail + +POD="${POD:-http://localhost:5444}" +USER_NAME="${POD_USER:-me}" +PASSWORD="${POD_PASS:-me}" +NAME="${MCP_NAME:-jspod}" + +TOKEN=$(curl -s -m 6 "$POD/idp/credentials" \ + -H "Content-Type: application/json" \ + -d "{\"username\":\"$USER_NAME\",\"password\":\"$PASSWORD\"}" \ + | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{const r=JSON.parse(d);if(!r.access_token){console.error("no token: "+d);process.exit(1)}process.stdout.write(r.access_token)})') + +claude mcp remove "$NAME" 2>/dev/null || true +claude mcp add --transport http "$NAME" "$POD/mcp" \ + --header "Authorization: Bearer $TOKEN" + +echo "Refreshed '$NAME' -> $POD/mcp (token valid ~1h)" diff --git a/verify-spacing.js b/verify-spacing.js deleted file mode 100644 index c7591ab..0000000 --- a/verify-spacing.js +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node - -// Verify the exact spacing in the banner - -const lines = [ - { leading: ' ', content: '██╗███████╗██████╗ ██████╗ ██████╗ ', trailing: ' ' }, // Line 84 - { leading: ' ', content: '██║██╔════╝██╔══██╗██╔═══██╗██╔══██╗', trailing: ' ' }, // Line 85 - { leading: ' ', content: '██║███████╗██████╔╝██║ ██║██║ ██║', trailing: ' ' }, // Line 86 - { leading: ' ', content: '██ ██║╚════██║██╔═══╝ ██║ ██║██║ ██║', trailing: ' ' }, // Line 87 - { leading: ' ', content: '╚█████╔╝███████║██║ ╚██████╔╝██████╔╝', trailing: ' ' }, // Line 88 - { leading: ' ', content: ' ╚════╝ ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ', trailing: ' ' }, // Line 89 -]; - -console.log('Verifying banner spacing:\n'); -lines.forEach((line, i) => { - const lineNum = 84 + i; - const total = line.leading.length + line.content.length + line.trailing.length; - const status = total === 67 ? '✓' : '✗'; - console.log(`Line ${lineNum}: ${line.leading.length} + ${line.content.length} + ${line.trailing.length} = ${total} ${status}`); -});