From 61e81aed5f1a29a4050447efe414c938b0769944 Mon Sep 17 00:00:00 2001 From: Sedge Date: Mon, 27 Apr 2026 02:36:13 -0500 Subject: [PATCH 1/2] Fix Sigil CLI import on Python 3.12+ --- tools/intent/sigil.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/intent/sigil.py b/tools/intent/sigil.py index d5d15fb..5a26205 100755 --- a/tools/intent/sigil.py +++ b/tools/intent/sigil.py @@ -4686,16 +4686,20 @@ def cmd_show(args) -> int: print(f"\n Relationships ({len(outgoing) + len(incoming)})") print(f" {'-' * 40}") - # Group by edge type + # Group by edge type. Keep default glyphs outside the f-string + # expressions so the CLI imports cleanly on Python 3.12+. by_type: Dict[str, List[str]] = collections.defaultdict(list) + default_symbol = "\u25cb" + outgoing_arrow = "\u2192" + incoming_arrow = "\u2190" for e in outgoing: if e.dst in g.nodes: t = g.nodes[e.dst] - by_type[e.type].append(f"\u2192 {sym.get(t.type, '\u25cb')} {e.dst} {t.title}") + by_type[e.type].append(f"{outgoing_arrow} {sym.get(t.type, default_symbol)} {e.dst} {t.title}") for e in incoming: if e.src in g.nodes: t = g.nodes[e.src] - by_type[e.type].append(f"\u2190 {sym.get(t.type, '\u25cb')} {e.src} {t.title}") + by_type[e.type].append(f"{incoming_arrow} {sym.get(t.type, default_symbol)} {e.src} {t.title}") for etype in sorted(by_type.keys()): print(f" {etype}:") From a9720e2492a5c42ad4a4e1b618d9069a7a6ef4e1 Mon Sep 17 00:00:00 2001 From: Sedge Date: Sat, 6 Jun 2026 07:36:08 -0500 Subject: [PATCH 2/2] chore: harden npm package posture --- .gitignore | 1 - npm/package.json | 2 +- npm/prepare.mjs | 42 ++++++++++++++++++++ tools/sigil-vscode/package-lock.json | 59 ++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 npm/prepare.mjs create mode 100644 tools/sigil-vscode/package-lock.json diff --git a/.gitignore b/.gitignore index 2c6b6fd..2014d8e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ venv/ node_modules/ npm/lib/ /tools/sigil-vscode/out/ -/tools/sigil-vscode/package-lock.json # Paperclip agents (not part of product) agents/ diff --git a/npm/package.json b/npm/package.json index cdfd9da..729c86e 100644 --- a/npm/package.json +++ b/npm/package.json @@ -29,7 +29,7 @@ "url": "https://github.com/fielding/sigil/issues" }, "scripts": { - "prepublishOnly": "bash prepare.sh" + "prepublishOnly": "node prepare.mjs" }, "engines": { "node": ">=18" diff --git a/npm/prepare.mjs b/npm/prepare.mjs new file mode 100644 index 0000000..a829ea6 --- /dev/null +++ b/npm/prepare.mjs @@ -0,0 +1,42 @@ +#!/usr/bin/env node +// Copy Sigil runtime assets into the npm package for distribution. +// Keep this dependency-free so the publish lifecycle is portable and auditable. + +import { copyFileSync, existsSync, mkdirSync, readdirSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const repoRoot = join(scriptDir, '..'); + +function copyFile(source, destination, label) { + mkdirSync(dirname(destination), { recursive: true }); + copyFileSync(source, destination); + console.log(`Copied ${label}`); +} + +copyFile( + join(repoRoot, 'tools', 'intent', 'sigil.py'), + join(scriptDir, 'lib', 'sigil.py'), + 'sigil.py to npm/lib/' +); + +copyFile( + join(repoRoot, 'tools', 'intent_viewer', 'index.html'), + join(scriptDir, 'lib', 'sigil_viewer.html'), + 'intent_viewer to npm/lib/sigil_viewer.html' +); + +const demoIndexDir = join(repoRoot, 'examples', 'demo-app', '.intent', 'index'); +if (existsSync(demoIndexDir)) { + mkdirSync(join(scriptDir, 'lib', 'demo_index'), { recursive: true }); + for (const file of readdirSync(demoIndexDir).filter((name) => name.endsWith('.json'))) { + copyFile( + join(demoIndexDir, file), + join(scriptDir, 'lib', 'demo_index', file), + `demo index ${file} to npm/lib/demo_index/` + ); + } +} else { + console.log('Skipped demo index copy; examples/demo-app/.intent/index is absent'); +} diff --git a/tools/sigil-vscode/package-lock.json b/tools/sigil-vscode/package-lock.json new file mode 100644 index 0000000..0b73e12 --- /dev/null +++ b/tools/sigil-vscode/package-lock.json @@ -0,0 +1,59 @@ +{ + "name": "sigil-intent", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sigil-intent", + "version": "0.1.0", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.0.0", + "@types/vscode": "^1.85.0", + "typescript": "^5.3.0" + }, + "engines": { + "vscode": "^1.85.0" + } + }, + "node_modules/@types/node": { + "version": "20.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.42.tgz", + "integrity": "sha512-5L7SUaFC1RyDraj2yRhyBzHTobyXHmohD100CChNtyPyleoq37Mqab5Gn8XEKI04dfN/oqPdpHk38MgcQWHbZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/vscode": { + "version": "1.120.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.120.0.tgz", + "integrity": "sha512-feaT4Rst+FkTch5zz/ZbNCxoIvo55YU80Be2kiL7OJcod4+CUYf2lUBPdIJzozNnSEMq1VRTGrWEcCGFB3fBmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +}