From be18fb6e90269f6bce0dad1b212c0defbe6d4d16 Mon Sep 17 00:00:00 2001 From: Melvin Carvalho Date: Thu, 11 Jun 2026 07:59:12 +0200 Subject: [PATCH] chore: prune dead banner scripts, track MCP dev tools, add CHANGELOG (#75) No version change: 0.0.48 to 0.0.50 were published separately, so the changelog records what each one shipped and puts this under Unreleased. --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++ count-ascii.js | 31 ----------------------------- count-banner.js | 28 --------------------------- jspod-ascii.js | 41 --------------------------------------- mcp.js | 46 ++++++++++++++++++++++++++++++++++++++++++++ refresh-mcp-token.sh | 21 ++++++++++++++++++++ verify-spacing.js | 20 ------------------- 7 files changed, 100 insertions(+), 120 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..59c162c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +## Unreleased + +### 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) (#75): + - `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 +- Added this changelog (#75) + +## 0.0.50 (2026-11-04) + +- Require jss 0.0.225 for the dotfile guard fix (#82) + +## 0.0.49 (2026-07-11) + +- `--plugin` passthrough to jss, jss 0.0.219, `JSPOD_BROWSER_URL` override +- Seed pod files only if they don't exist, so user edits survive restarts (#81) + +## 0.0.48 (2026-06-15) + +- **panes**: render bookmark enrichment: summary, tags, hero image (#71, #72) +- **panes**: searchable bookmark collection pane, plus container-pane support (#73, #74) +- `jspod install` delegates to the upstream `jss install` (#78) +- Pass `--body-limit 40MB` and require jss >=0.0.208, so large app installs fit (#80) + +## 0.0.47 (2026-06-05) + +- Publish `data-browser-panes.js` and `--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/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}`); -});