The webdesktop takes the app's version from upstream.json's tag, so workspace.app.json no longer repeats it. AGENTS.md says what screenshots/ may hold: our own captures of the running app, never upstream's images; captures showing ArtCraft's marks wait for Phil's go (AGL-478). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@workspace.global/gridcraft
GridCraft, spreadsheets and data (a clean-room Microsoft Excel) written in Rust, as a frame app for the workspace.global webdesktop. The repository holds no GridCraft code. The build downloads GridCraft's released WebAssembly build (pinned by sha256 in upstream.json) and unpacks it unchanged into the git-ignored dist_app/app/, next to a shim page from @workspace.global/craftkit that connects it to the webdesktop's window, and the app's workspace.app.json manifest.
Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.
Issues in GridCraft itself belong upstream: github.com/storytold/gridcraft.
Status
GridCraft is alpha software that changes quickly; this package pins release v0.7.0. In the webdesktop:
- Open: File › Open shows the workspace's Open dialog in place of the browser's file picker. A file opened from Files goes in through GridCraft's parent bridge (
gridcraft:open). - Save: GridCraft's saves come through its bridge (
gridcraft:save) and go to the workspace: Save replaces the open file; Save As, exports and new documents go through the workspace's Save dialog. Unsaved changes (gridcraft:dirty) reach the window title and the host. - Pickers: GridCraft prefers the browser's
showSaveFilePickerwhen it runs on its own; inside the webdesktop its bridge takes the saves. - Window: the title shows the open file's name; a press inside GridCraft raises its window; the shim shows a loading notice until GridCraft has started.
- Theme: GridCraft starts in the workspace's theme and follows it live: its web build follows
prefers-color-scheme, which the shim sets from the workspace. It keeps no theme setting on the web, so a theme picked in GridCraft lasts only while its window is open. - On its own (opened outside the webdesktop), GridCraft opens and saves through the browser as usual.
Notes for this app:
- In host mode GridCraft starts with an empty workbook instead of the sample.
What is served
dist_app/ is served at /apps/gridcraft/:
| Path | What it is |
|---|---|
index.html, shim.js |
The shim page: the manifest's entry |
workspace.app.json |
The manifest (IWgAppManifest, kind: 'frame') |
app/ |
GridCraft's web build, unpacked unmodified from the pinned release asset |
The shim loads app/index.html in an iframe on the same origin. GridCraft needs no SharedArrayBuffer, so no cross-origin isolation headers; it needs WebGL2 (WebGPU where the browser has it), .wasm served as application/wasm, and a 404 (not a fallback page) for a missing file.
Build and test
pnpm install
pnpm run build # shim into dist_app/, then downloads and unpacks the pinned release (7.1 MB, once)
pnpm test # no network
pnpm run upstream repeats only the download and unpack step; the download is cached in .nogit/upstream/ and checked against the size and sha256 in upstream.json before it is used. pnpm run check checks the manifest and pin.
Use from the webdesktop
import { manifest, appDir } from '@workspace.global/gridcraft';
// serve appDir at /apps/${manifest.id}/ and register manifest in frameApps
Licenses
The wrapper code is MIT. GridCraft is dual-licensed MIT OR Apache-2.0; its license files ship inside dist_app/app/. The ArtCraft name, wordmark and logos in GridCraft are trademarks of the ArtCraft Team and are not covered by those licenses: they may be used only unmodified, so this package ships the official build untouched. GridCraft is an independent project, not affiliated with the maker of the product it reimplements.