2026-07-22 18:10:26 +02:00
2026-07-23 01:23:32 +02:00
2026-07-20 18:40:51 +02:00
2026-07-20 18:40:51 +02:00

add·ideas Toolbox Portal

toolbox-portal is the static launcher and release assembler for the add·ideas browser toolbox. Version 0.2.1 reads one same-origin catalogue, shows each app as a full-page launch tile, and keeps personal pins, drag-and-drop ordering, visibility, and appearance in the current browser. Pinned tools have their own section; search, category, and clickable tag filters stay close to the tool list.

The v1 boundary is intentionally small:

  • apps remain separately versioned and released repositories;
  • @add-ideas/toolbox-contract owns manifest, catalogue, and URL validation;
  • the portal navigates to apps—there are no iframes, plugins, remote modules, or runtime-loaded application code;
  • the assembler copies already-built, exact ZIP artifacts and never builds app source or resolves a latest release.

Development

Requirements: Node.js 22 or newer and npm 11 or newer. The committed .npmrc selects the public, token-free package scope on Gitea; registry credentials are not required to install the Toolbox SDK packages. Install and verify the portal:

npm ci
npm test
npm run lint
npm run build
npm run dev

The package lock resolves the ^0.2.1 SDK ranges to the published 0.2.1 packages. A sibling SDK checkout is only needed when intentionally developing the SDK and portal together.

Vite uses base: './', so the built portal works at / or a nested static path. The development catalogue at public/toolbox.catalog.json points to assembled paths (./apps/pdf/, ./apps/xslt/, and ./apps/onenote/). Those manifests will correctly appear as unavailable until an assembled release is being served.

Catalogue and launches

The portal fetches ./toolbox.catalog.json, validates it with the shared contract, and then validates each enabled manifest. A bad individual manifest is reported without hiding valid apps; a bad or unreachable catalogue gets a retry state. An empty valid catalogue gets its own empty state.

Internal launch links stay same-origin and receive the exact catalogue URL in a toolbox query parameter. For example:

/apps/pdf/?toolbox=https%3A%2F%2Ftoolbox.example%2Ftoolbox.catalog.json

Apps discover that context through the shared shell/contract and retain their standalone fallback when no context is present. External catalogue entries open according to their declared launch mode and do not receive toolbox context.

Personal settings use the namespaced local-storage key @add-ideas/toolbox-portal:v1:preferences. The preferences panel can reset, export, and import the versioned JSON document. The portal itself does not transmit preferences. Because Toolbox apps share an origin, code explicitly trusted in an app can access same-origin browser storage; review each app's privacy and executable-code warning. Light, dark, and system modes are supported.

Production deployment behind Traefik

The committed compose.yaml is the shortest production path. Its release container downloads the immutable Toolbox 0.4.1 ZIP during the image build, verifies SHA-256 before extracting it, and then copies only the verified static files into the pinned unprivileged nginx image. Node.js and a local portal assembly are not required on the deployment host.

Prerequisites:

  • Docker with the Compose plugin;
  • Traefik attached to the existing external Docker network internal;
  • a Traefik HTTPS entrypoint named websecure;
  • a certificate resolver named netcup;
  • DNS for toolbox.add-ideas.de pointing to that Traefik instance; and
  • outbound HTTPS access to git.add-ideas.de while the image is built.

Deploy a fresh clone with:

git clone https://git.add-ideas.de/zemion/toolbox-portal.git
cd toolbox-portal
docker compose up -d --build
docker compose ps

No host port is published. Traefik routes https://toolbox.add-ideas.de to nginx on the shared network at port 8080 and obtains its TLS certificate through netcup. The hostname, network, resolver, release version, and matching checksum can be overridden through environment variables; copy .env.example to .env only when an override is needed. For example, set TOOLBOX_HOST=staging.toolbox.add-ideas.de for a staging host.

The external network is deliberately not created by this project. Creating a private project-local network would prevent an independently managed Traefik container from reaching the service.

Exact release assembly

Every app release ZIP must put these items at its archive root:

index.html (or the entry declared by toolbox-app.json)
toolbox-app.json
CHANGELOG.md
LICENSES/
SOURCE.md
...built static assets

The app release should also publish a matching .sha256 sidecar. The manifest must declare the pinned reverse-DNS id and version. Application and portal versions are independent.

release/toolbox.lock.json is the reviewed v0.4.1 lock. Its URLs and checksums pin the published PDF Tools 0.4.1, XSLT Tools 0.4.1, and OneNote Tools 0.3.1 release bytes. Use release/toolbox.lock.example.json as the template for a future release and verify every downloaded asset before committing updated values. Artifacts may be:

  • a path relative to the lock file;
  • a file: URL; or
  • a credential-free HTTPS URL to an immutable release asset.

For a private Gitea release, download the exact asset first and put its local path in the lock. Do not put credentials in a lock URL.

Build the portal and assemble the distribution:

npm ci
npm test
npm run build
npm run assemble -- \
  --lock release/toolbox.lock.json \
  --portal-dist dist \
  --output build/toolbox \
  --archive build/add-ideas-toolbox-0.4.1.zip

Existing output is refused. Pass --force only when replacing those exact paths is intended. A successful run produces:

build/toolbox/
├── index.html
├── toolbox.catalog.json       generated from the lock
├── toolbox.release.json       ids, versions, targets, checksums
├── LICENSE.txt
├── SOURCE.md
├── THIRD_PARTY_LICENSES.txt
├── THIRD_PARTY_NOTICES.md
└── apps/
    ├── pdf/
    ├── xslt/
    └── onenote/

build/add-ideas-toolbox-0.4.1.zip
build/add-ideas-toolbox-0.4.1.zip.sha256

The assembler verifies SHA-256 before opening an artifact, validates every app manifest with @add-ideas/toolbox-contract, requires its id/version to equal the lock, and smoke-checks each declared entry, icon, and packaged manifest asset after extraction. It rejects insecure or credential-bearing redirects, HTTP, latest aliases, ZIP traversal, absolute paths, symlinks, special files, duplicate paths, oversized entries, and unsafe compression ratios. Canonical path checks protect source and output trees even through symlink aliases, and publication rolls all outputs back if a staged rename fails. Artifacts are unpacked only under apps/<locked-target>. The assembler never runs artifact content.

The archive writer sorts file names and fixes ZIP timestamps and modes so the same assembled directory produces stable bytes. To package an already assembled directory separately:

npm run package:static -- \
  --input build/toolbox \
  --output artifacts/add-ideas-toolbox-0.4.1.zip

This also emits a .sha256 sidecar.

Local assembled container and publication

Containerfile serves only the assembled files with unprivileged nginx on port 8080. It adds restrictive browser headers, same-origin isolation, immutable caching only for Vite-hashed assets, and revalidation for all other files. Assemble first, then:

The packaged policy intentionally does not grant CSP unsafe-eval. SaxonJS's ixsl:eval() extension is therefore unsupported in this deployment profile; normal local XML/XSLT transformations do not require that permission.

podman build -f Containerfile \
  -t git.add-ideas.de/zemion/toolbox:0.4.1 .
podman run --rm -p 8080:8080 \
  git.add-ideas.de/zemion/toolbox:0.4.1

For a direct-port local deployment after assembly, use the separate example:

docker compose -f compose.example.yaml up -d --build

Publish both common architectures from a buildx-enabled workstation or Gitea runner:

docker login git.add-ideas.de
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --file Containerfile.release \
  --tag git.add-ideas.de/zemion/toolbox:0.4.1 \
  --tag git.add-ideas.de/zemion/toolbox:0.4 \
  --push .

The default unprivileged nginx image is the security-fixed 1.31.3-alpine baseline pinned to its reviewed multi-architecture digest. Re-resolve and review that digest whenever the base image is upgraded, then record it in the release notes.

Manual Gitea publication checklist

No credentials belong in this repository. Before the first release, create the zemion/toolbox-portal Gitea repository and grant the workstation or runner permission to push code, releases, and container packages.

  1. Run npm ci, npm test, npm run lint, and npm run build from a clean checkout of the intended portal tag.
  2. Publish each app's versioned ZIP, .sha256, toolbox-app.json, changelog, and licence notices in its own Gitea release.
  3. Verify downloaded app assets with sha256sum -c <asset>.sha256; copy those exact values into a reviewed toolbox lock.
  4. Run the assembler and serve build/toolbox from a nested test path. Open all three apps, switch between them, and confirm the encoded toolbox context.
  5. Verify the distribution with (cd build && sha256sum -c add-ideas-toolbox-0.4.1.zip.sha256).
  6. Commit the reviewed lock, tag the toolbox release (for example v0.4.1), and push the branch and tag to Gitea.
  7. In Gitea, open Releases → New release, select the tag, and upload the static ZIP plus its .sha256 file. Do not use a mutable “latest” URL in a future lock.
  8. Build and push the AMD64/ARM64 OCI image as shown above. Record the resulting multi-architecture manifest digest in the release notes.

For Gitea Actions, store registry credentials as repository secrets, check out the exact tag, install with npm ci, run the same verification/assembly commands, and upload only the already-created ZIP/checksum and OCI image. The workflow must not re-resolve app versions or substitute a newer release.

Existing tools

Tool State and boundary Principal workflows Important concrete scope Critical considerations and integrations
pdf-tools Existing; dedicated repository Merge, split, reorder, rotate and export PDF pages Thumbnail workspace; multi-document operations; ZIP and PDF output; saved local workspace Workers and IndexedDB; large-document memory control; future signature inspection through crypto-tools; metadata and safe-sharing through privacy-tools
xslt-tools Existing; dedicated repository Develop, test and run XSLT transformations XML/XSLT editors; transformation results; local files; saved projects; validation and diagnostics Lazy SaxonJS loading; relocatable assets; useful handoffs to data-tools, schema-tools and diff-tools
onenote-tools Existing rich-reader release; dedicated repository Open, browse, inspect and export OneNote sections and packages locally Desktop/unfragmented FSSHTTPB .one/.onetoc2; none/LZX/MSZIP/Quantum and multi-cabinet .onepkg; trees, rich text, images, tables, ink, attachments and export Native TypeScript worker with no Wasm; bounded parsing, rendering and export; fragmented FSSHTTP fails safely; no editing or pixel-perfect fidelity

Planned tools

Tool State and boundary Principal workflows Important concrete scope Critical considerations and integrations
svg-tools Planned; dedicated repository Source and visual SVG editing Synchronized DOM tree, code and canvas; optimization; path simplification; symbols; accessibility; animation; sanitization SVG is potentially active content; previews require sanitization or sandboxing; integrate with colour-tools, token-tools, image-tools and label-tools
regex-tools Planned; dedicated repository Develop, test and apply regular expressions Corpus mode; replacement preview; capture table; flavour comparison; performance visualization; generated test cases; failing-input minimization Never claim exact equivalence across regex engines without qualification; bound execution; integrate with text-tools, log-tools and minimize-tools
colour-tools Planned; small-to-medium dedicated repository Colour conversion, calculation and palette work sRGB, Display P3, Lab, LCH, OKLab and OKLCH; gamut mapping; contrast; colour-vision simulation; gradients; palette extraction; design-token export Make colour-space assumptions explicit; distinguish mathematical conversion from display simulation; integrate with SVG, image and token tools
rand-tools Planned; small dedicated repository Generate random numbers, strings, identifiers and samples Cryptographically secure generation; deterministic seeded generation; UUIDs, ULIDs, passphrases, dice notation, distributions, weighted selection and shuffling Clearly separate secure randomness from reproducible pseudorandomness; no misleading “strength” claims; natural foundation for fixture-tools
barcode-tools Planned; dedicated repository Generate, inspect and decode QR and barcodes QR, common one- and two-dimensional codes; camera/image decoding; GS1 assistance; CSV batch generation; quiet-zone and print-size checks; structured payload builders Treat decoded payloads as untrusted; never open links automatically; camera permission must be optional; integrate with label-tools, contact-tools and crypto-tools
av-tools Planned; large dedicated repository Light audio and video editing and transcoding Trim, split, concatenate, crop, resize, normalize, fades, waveform, metadata, chapters, subtitles, thumbnail/contact-sheet generation and export presets Heavy WASM and worker workloads; temporary-file storage; configurable memory limits; possibly special cross-origin-isolation headers; integrate with subtitle-tools and image-tools
crypto-tools Planned; dedicated repository Inspect keys, certificates and signatures; validate chains X.509 PEM/DER, CSR, CRL, PKCS #8, encrypted PKCS #8, PKCS #12/PFX, JWK/JWKS; key/certificate matching; path construction; hostname, purpose and time checks; CMS/JWS later Inspection-first; explicit trust anchors; no implication that browser/OS trust stores are used; no private-key persistence; offline revocation first; network checks opt-in; restrictive CSP and worker isolation
data-tools High priority; dedicated repository Inspect, edit, validate, query and convert structured data JSON, YAML, TOML, XML, CSV and NDJSON; tree/table/source views; schema inference; flattening; filtering; field mapping; JSONPath-style queries; conversion recipes Every conversion should disclose information loss, coercion and round-trip instability; XML-specialist workflows hand off to xslt-tools
image-tools High priority; dedicated repository Edit and batch-process raster images Crop, resize, rotate, compress, convert, contact sheets, sprites, responsive sets, favicon generation, metadata removal and visual quality comparison Use workers and off-main-thread rendering; preserve or deliberately remove colour profiles; integrate with colour, SVG, PDF and privacy tools
diff-tools High priority; dedicated repository or shared engine plus UI Compare documents and files semantically Text; JSON object-aware comparison; XML normalization; CSV keyed comparison; images with overlay/heatmap; archives and directories; PDF pages; optional audio waveform comparison Normalization and ignored properties must be visible; produce portable reports and standard patch formats where possible
file-tools High priority; dedicated repository Identify, inspect and organize local files Magic-byte detection; hex view; decoded strings; checksums; directory manifests; split/join; duplicate detection; trailing-data detection; batch-rename preview All inputs are untrusted; format inspectors require strict size and nesting limits; natural entry point to archive, privacy, crypto and package tools
archive-tools Medium-to-high priority; dedicated repository Inspect, create, compare and extract archives ZIP, TAR, gzip and selected additional formats; selective extraction; content preview; deterministic archives; timestamp normalization; archive comparison Expansion-ratio, entry-count and total-size limits; traversal-safe extraction; never execute extracted files
text-tools Medium priority; one app with deep-linked panels Transform and normalize plain text Unicode normalization; line-ending conversion; encoding; sorting; deduplication; case changes; transliteration; escaping; column operations; transformation pipelines Preserve exact input/output visibility; warn about lossy encodings and Unicode confusables; integrate regex operations
query-tools High-value but large; dedicated repository Analyse local tabular and relational data with SQL CSV, JSON, NDJSON, Parquet and SQLite; schema inference; joins; aggregation; pivots; charts; export to common data formats WASM memory and streaming; distinguish this analytical product from document-oriented data-tools; query work must remain local
privacy-tools High priority; dedicated repository Inspect and remove metadata before sharing EXIF and GPS; document author/comments; embedded thumbnails; PDF metadata and attachments; hidden package entries; AV tags; personal filenames; structured safe-sharing report Never promise absolute anonymity; explicitly state inspected, removed, preserved and unsupported structures; integrate with most file-oriented apps
time-tools Medium priority; small dedicated app or helper family Work with dates, timestamps, time zones and recurrences Unix timestamps; date arithmetic; durations; ISO 8601; timezone comparison; cron; RRULE; ICS generation; business days; DST-transition visualization Visualize actual recurrence instances and ambiguous/skipped local times; do not rely on simplified fixed-offset calculations
subtitle-tools Medium priority; dedicated repository Edit, validate and synchronize captions SRT, WebVTT and ASS; timing shifts; stretching; frame-rate conversion; overlap and reading-speed checks; waveform synchronization; revision comparison Direct integration with av-tools; preserve style information when supported and disclose conversion losses
font-tools Medium priority; dedicated repository Inspect, preview and prepare fonts Glyph coverage; variable axes; metadata; fallback comparison; subsetting; CSS generation; arbitrary-text previews Font licensing and embedding restrictions must be visible; use untrusted-font isolation and strict parser limits
label-tools Medium priority; dedicated repository Generate labels and badges from templates and data CSV/JSON merge into SVG templates; QR/barcode fields; serial numbers; A4 label sheets; badges; asset tags; cut marks; calibration Strong suite demonstration linking data, SVG, barcode, random and PDF capabilities; print dimensions must be explicit and testable
flow-tools Later platform layer Compose local processing operations across tools Example: CSV → filter → QR generation → SVG template → PDF → ZIP; reusable recipes; typed inputs and outputs; progress and cancellation Do not load complete React applications into one runtime; expose separate worker-safe operation packages only after several apps have stable operations
fixture-tools Medium priority Generate deterministic test data JSON Schema, XSD, SQL DDL, CSV headings or interactive models to JSON, CSV, XML, SQL and NDJSON; foreign keys; distributions; boundary and invalid cases Seeded reproducibility; uniqueness constraints; privacy-safe synthetic data; natural extension of rand-tools
minimize-tools Distinctive specialist tool Reduce a failing input while preserving a failure Minimize XML triggering an XSLT error; shortest regex pathological input; smallest JSON schema failure; selectable failure predicates Expensive repeated execution must be bounded and cancellable; record the exact predicate and transformation versions
format-lab Later, distinctive product Explore conversion paths and information loss Format graph; round-trip tests; property preservation; type coercion; metadata loss; recommended path selection across data, image, AV and subtitle formats No conversion should be described as lossless without testing relevant properties
repro-tools Medium-to-later Create manifests and provenance records File hashes; directory manifests; operation history; tool/version/parameter records; deterministic package creation; verification reports Useful foundation for reproducible workflows and signed manifests; integrates with crypto, archive and flow tools
package-tools Medium priority Inspect compound and package-based formats EPUB; DOCX/XLSX/PPTX; ODF; JAR; APK; browser extensions; package trees; manifests; relationships; embedded media; signatures; orphaned parts Generic container inspector with format adapters; complements rather than replaces onenote-tools, epub-tools and office-tools
schema-tools Dedicated specialist app Validate, inspect and generate examples for JSON Schema, XSD, Relax NG, Schematron and OpenAPI; visualize references and incompatibilities
log-tools Dedicated app Stream and filter large logs; parse common formats; correlate records; build timelines; extract fields; anonymize values; avoid loading the complete file into memory
network-tools Helper family or small app IPv4/IPv6 subnetting; CIDR ranges; URL and query parsing; DNS-record construction; HTTP headers; CSP generation; MIME lookup; avoid turning it into an intrusive scanner
binary-tools Dedicated specialist app Base64, hexadecimal, CBOR, MessagePack, ASN.1 and Protocol Buffers; schema-assisted decoding; byte-range highlighting; strict depth and size limits
git-tools Small-to-medium app Patch inspection and editing; .gitignore testing; semantic-version comparison; conventional commits; changelog normalization; no repository-hosting dependency
api-tools Medium app OpenAPI validation; request and response examples; curl and client-command generation; saved HTTP-exchange inspection; direct browser requests remain subject to CORS
calendar-tools Small-to-medium app ICS inspection, merging, deduplication, repair, recurrence visualization and timezone diagnostics
contact-tools Small-to-medium app vCard inspection and editing; CSV mapping; deduplication; contact QR generation; treat all contact data as sensitive
mail-tools Medium app EML and MIME inspection; header analysis; attachment extraction; body-part comparison; HTML mail must be heavily sandboxed
epub-tools Medium app EPUB inspection, metadata and cover editing, link validation, chapter extraction and structural repair; sanitize embedded HTML and SVG
scan-tools Large app Camera/document correction; crop, deskew and threshold; page assembly; local OCR; PDF output; model downloads and memory use must be explicit
office-tools Medium-to-large app Inspect rather than reproduce an office suite: package structure, relationships, metadata, comments, embedded images and basic repairs
geo-tools Medium app GeoJSON, GPX, KML and coordinate CSV; format conversion; track simplification; distance/elevation analysis; coordinate-reference assumptions must be explicit
diagram-tools Medium app Code and visual editing for Mermaid, Graphviz and related representations; renderers require sanitization and sandboxing
token-tools Small-to-medium app Design-token editing and conversion between JSON, CSS custom properties, Sass, Android and iOS forms; integrate with colour and SVG tools
3d-tools Large specialist app Inspect STL, OBJ and glTF; dimensions, bounding boxes, mesh simplification and common geometry defects; worker/GPU use and file limits
midi-tools Medium specialist app MIDI event inspection and editing; transpose, quantize, tempo maps and controller data; device access should remain optional
device-tools Specialist app Serial terminal, sensor logger, microcontroller console and controlled firmware installation; explicit permission and browser-capability checks
helpers-tools One shared artifact with deep links Stateless Base64, URL encoding, case conversion, number bases, Unicode code points, unit conversion, small checksums, subnet and timestamp calculators; avoid a repository per calculator

Licensing

Portal source is AGPL-3.0-only; see LICENSE. The contract is Apache-2.0, and each assembled application retains its own licence and notices. An assembled ZIP/container is an aggregate of those independently licensed components; see THIRD_PARTY_NOTICES.md and each apps/<slug>/LICENSES/ directory.

Description
No description provided
Readme AGPL-3.0 1.2 MiB
2026-07-28 00:33:36 +02:00
Languages
TypeScript 62.3%
JavaScript 26.1%
CSS 10.9%
HTML 0.4%
Dockerfile 0.3%