All checks were successful
CI / Lint, typecheck, test (push) Successful in 2m55s
CI / Build container images (push) Has been skipped
CD / Build and push images (push) Successful in 3m14s
CD / Deploy to Test (push) Successful in 10s
CD / Smoke tests against Test (push) Successful in 1m9s
CD / Promote to Int (push) Successful in 10s
CI / Import/export fidelity gate (push) Successful in 45s
CI / Auth e2e pack (push) Successful in 4m50s
The end-to-end proof of the code-block path: packages/plugins/mermaid
bundles the mermaid library (esbuild, ~3.4 MB unpacked — well under the
20 MiB install gate) so diagrams render entirely inside the sandbox; the
frame CSP forbids any network request (pinned by the e2e's off-origin
request assertion).
- Block data is `{ source, svg }`: the source text is the document of
record, `svg` the last successfully rendered snapshot — persisted
together on every good preview, so office/PDF exports can show the
diagram without executing anything (#79).
- Edit mode: source textarea with a debounced live preview and inline
error display; a failing source still persists (typed text never lost),
paired with the last good snapshot.
- Render mode: renders the stored source; if that stops rendering, it
falls back to the stored snapshot with a "stale" note — a bad edit
never breaks render mode.
- mermaid leaves its scratch element (and, on parse errors, an error SVG)
on document.body — the render helper removes both, so the surface only
shows what the plugin inserts.
- e2e mermaid.spec.ts: flowchart renders + survives reload with zero
off-origin requests, inline syntax errors with intact render mode, and
a collaborator sees the diagram appear live. Wired into CI.
- seed.ts now heals a missing owner-admin grant on existing personal
ponds: a dev database shared with the test suites can lose it to a
cleanup, and the seed's contract is "idempotent", not "first run only".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
35 lines
1.2 KiB
JavaScript
35 lines
1.2 KiB
JavaScript
// Builds the installable plugin (plugin-architecture.md §Package format):
|
|
// bundles src/plugin.ts (SDK + i18n inlined — the sandbox CSP forbids runtime
|
|
// fetches) into plugin.js as a single ES module, then packs the ZIP for the
|
|
// admin upload / dropzone watcher.
|
|
import { mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
import { build } from 'esbuild';
|
|
import { zipSync } from 'fflate';
|
|
|
|
const root = dirname(fileURLToPath(import.meta.url));
|
|
const manifest = JSON.parse(readFileSync(join(root, 'manifest.json'), 'utf8'));
|
|
|
|
mkdirSync(join(root, 'dist'), { recursive: true });
|
|
await build({
|
|
entryPoints: [join(root, 'src/plugin.ts')],
|
|
bundle: true,
|
|
format: 'esm',
|
|
outfile: join(root, 'dist/plugin.js'),
|
|
minify: true,
|
|
});
|
|
|
|
const files = {
|
|
'manifest.json': readFileSync(join(root, 'manifest.json')),
|
|
'plugin.js': readFileSync(join(root, 'dist/plugin.js')),
|
|
};
|
|
for (const name of readdirSync(join(root, 'i18n'))) {
|
|
files[`i18n/${name}`] = readFileSync(join(root, 'i18n', name));
|
|
}
|
|
|
|
const target = join(root, 'dist', `${manifest.id}-${manifest.version}.zip`);
|
|
writeFileSync(target, zipSync(files));
|
|
console.log(`wrote ${target}`);
|