import type { ToolboxAppManifest, ToolboxCatalog, } from '@add-ideas/toolbox-contract'; export const pdfManifest: ToolboxAppManifest = { schemaVersion: 1, id: 'de.add-ideas.pdf-tools', name: 'PDF Workbench', version: '0.4.3', description: 'Page-level PDF operations performed locally in the browser.', entry: './', icon: './favicon.svg', categories: ['documents', 'pdf'], tags: ['merge', 'split'], integration: { contextVersion: 1, launchModes: ['navigate', 'new-tab'], embedding: 'unsupported', }, requirements: { secureContext: true, workers: true, indexedDb: true, crossOriginIsolated: false, }, privacy: { processing: 'local', fileUploads: false, telemetry: false, }, source: { repository: 'https://git.add-ideas.de/lotobo/pdf-tools', license: 'AGPL-3.0-only', }, }; export const xsltManifest: ToolboxAppManifest = { ...pdfManifest, id: 'de.add-ideas.xslt-tools', name: 'XSLT Workbench', version: '0.4.2', description: 'Transform XML locally with XSLT in the browser.', icon: './xslt.svg', categories: ['documents', 'developer'], tags: ['transform', 'xml'], source: { repository: 'https://git.add-ideas.de/lotobo/xslt-tools', license: 'AGPL-3.0-only', }, }; export const onenoteManifest: ToolboxAppManifest = { ...pdfManifest, id: 'de.add-ideas.onenote-tools', name: 'OneNote Reader', version: '0.3.3', description: 'Inspect OneNote packages locally in the browser.', icon: './onenote.svg', categories: ['documents', 'notes'], tags: ['onepkg', 'import'], source: { repository: 'https://git.add-ideas.de/lotobo/onenote-tools', license: 'AGPL-3.0-only', }, }; export const regexManifest: ToolboxAppManifest = { ...pdfManifest, id: 'de.add-ideas.regex-tools', name: 'Regex Tools', version: '0.4.1', description: 'Develop, explain, test and apply regular expressions locally in the browser.', icon: './regex.svg', categories: ['developer', 'text', 'regex'], tags: ['regular-expression', 'match', 'replace', 'explain', 'test'], requirements: { secureContext: false, workers: true, indexedDb: true, crossOriginIsolated: false, }, source: { repository: 'https://git.add-ideas.de/lotobo/regex-tools', license: 'GPL-3.0-or-later', }, }; export const svgManifest: ToolboxAppManifest = { ...pdfManifest, id: 'de.add-ideas.svg-tools', name: 'SVG Tools', version: '0.1.0', description: 'Inspect, edit, optimize and transform SVG documents locally in the browser.', icon: './favicon.svg', categories: ['graphics', 'design', 'developer'], tags: [ 'svg', 'vector', 'path', 'xml', 'transform', 'optimize', 'accessibility', ], requirements: { secureContext: false, workers: true, indexedDb: false, crossOriginIsolated: false, topLevelContext: false, }, source: { repository: 'https://git.add-ideas.de/lotobo/svg-tools', license: 'GPL-3.0-or-later', }, assets: ['./canvas-frame-controller.js'], }; export const authManifest: ToolboxAppManifest = { ...pdfManifest, id: 'de.add-ideas.auth-tools', name: 'OTP & Passkey Tools', version: '0.1.0', description: 'Generate, inspect and verify OTP credentials and test WebAuthn/passkey ceremonies locally in the browser.', icon: './favicon.svg', categories: ['security', 'authentication', 'developer'], tags: [ 'otp', 'hotp', 'totp', 'ocra', 'oath', 'webauthn', 'fido2', 'passkey', 'attestation', 'assertion', ], requirements: { secureContext: true, workers: false, indexedDb: false, crossOriginIsolated: false, topLevelContext: true, }, privacy: { processing: 'local', fileUploads: false, telemetry: false, label: 'Authentication material stays in this tab; nothing is uploaded or saved unless you explicitly export it.', }, source: { repository: 'https://git.add-ideas.de/lotobo/auth-tools', license: 'GPL-3.0-or-later', }, }; export const sudokuManifest: ToolboxAppManifest = { schemaVersion: 1, id: 'de.add-ideas.sudoku-tools', name: 'Sudoku Tools', version: '0.1.0', description: 'Set, play, solve and analyse Sudoku puzzles locally in the browser.', entry: './', icon: './favicon.svg', categories: ['games', 'puzzles', 'logic'], tags: ['sudoku', 'killer', 'solver', 'setter', 'generator', 'candidates'], integration: { contextVersion: 1, launchModes: ['navigate', 'new-tab'], embedding: 'unsupported', }, requirements: { secureContext: false, workers: true, indexedDb: true, crossOriginIsolated: false, topLevelContext: false, }, privacy: { processing: 'local', fileUploads: false, telemetry: false, label: 'Puzzles and progress stay in this browser; nothing is uploaded.', }, source: { repository: 'https://git.add-ideas.de/lotobo/sudoku-tools', license: 'GPL-3.0-or-later', }, actions: [ { id: 'source', label: 'Source', url: 'https://git.add-ideas.de/lotobo/sudoku-tools', }, ], }; export const colourManifest: ToolboxAppManifest = { ...sudokuManifest, id: 'de.add-ideas.colour-tools', name: 'Colour Tools', version: '0.1.0', description: 'Convert, composite, compare and build colours locally in the browser.', categories: ['graphics', 'design', 'developer'], tags: ['colour', 'rgba', 'oklch', 'palette', 'gradient', 'contrast'], requirements: { secureContext: false, workers: true, indexedDb: false, crossOriginIsolated: false, topLevelContext: false, }, privacy: { processing: 'local', fileUploads: false, telemetry: false, label: 'Colours and images stay in this browser; nothing is uploaded.', }, source: { repository: 'https://git.add-ideas.de/lotobo/colour-tools', license: 'GPL-3.0-or-later', }, actions: [ { id: 'source', label: 'Source', url: 'https://git.add-ideas.de/lotobo/colour-tools', }, ], }; export const officeManifest: ToolboxAppManifest = { ...sudokuManifest, id: 'de.add-ideas.office-tools', name: 'Office Tools', version: '0.1.0', description: 'Open and inspect documents, spreadsheets and presentations locally in the browser.', categories: ['documents', 'office', 'productivity'], tags: ['document', 'spreadsheet', 'presentation', 'docx', 'xlsx', 'pptx'], requirements: { secureContext: false, workers: true, indexedDb: false, crossOriginIsolated: false, topLevelContext: false, }, privacy: { processing: 'local', fileUploads: false, telemetry: false, label: 'Office files stay in this browser; nothing is uploaded.', }, source: { repository: 'https://git.add-ideas.de/lotobo/office-tools', license: 'GPL-3.0-or-later', }, actions: [ { id: 'source', label: 'Source', url: 'https://git.add-ideas.de/lotobo/office-tools', }, ], }; export const catalogue: ToolboxCatalog = { schemaVersion: 1, id: 'de.add-ideas.toolbox', name: 'add·ideas Toolbox', home: './', theme: { mode: 'system', brand: 'add·ideas' }, apps: [ { manifest: './apps/pdf/toolbox-app.json', enabled: true }, { manifest: './apps/xslt/toolbox-app.json', enabled: true }, { manifest: './apps/onenote/toolbox-app.json', enabled: true }, { manifest: './apps/svg/toolbox-app.json', enabled: true }, { manifest: './apps/auth/toolbox-app.json', enabled: true }, { manifest: './apps/sudoku/toolbox-app.json', enabled: true }, { manifest: './apps/colour/toolbox-app.json', enabled: true }, { manifest: './apps/office/toolbox-app.json', enabled: true }, ], }; export function catalogueFetch(overrides: Record = {}) { return async (input: string | URL | Request): Promise => { const url = new URL( input instanceof Request ? input.url : String(input), document.baseURI ); const custom = overrides[url.pathname]; if (custom) return custom.clone(); if (url.pathname.endsWith('/toolbox.catalog.json')) return Response.json(catalogue); if (url.pathname.endsWith('/apps/pdf/toolbox-app.json')) return Response.json(pdfManifest); if (url.pathname.endsWith('/apps/xslt/toolbox-app.json')) return Response.json(xsltManifest); if (url.pathname.endsWith('/apps/onenote/toolbox-app.json')) return Response.json(onenoteManifest); if (url.pathname.endsWith('/apps/regex/toolbox-app.json')) return Response.json(regexManifest); if (url.pathname.endsWith('/apps/svg/toolbox-app.json')) return Response.json(svgManifest); if (url.pathname.endsWith('/apps/auth/toolbox-app.json')) return Response.json(authManifest); if (url.pathname.endsWith('/apps/sudoku/toolbox-app.json')) return Response.json(sudokuManifest); if (url.pathname.endsWith('/apps/colour/toolbox-app.json')) return Response.json(colourManifest); if (url.pathname.endsWith('/apps/office/toolbox-app.json')) return Response.json(officeManifest); return new Response('Not found', { status: 404 }); }; }