Verified script
The full verified first-run script, and the configuration it's confirmed on.
The full verified script
Section titled “The full verified script”The f1-api-first-run.mjs file is part of the Evaluation Kit, but you can just copy it from here: the script finds the processor itself, based on the system it’s running on. If the application is installed in a non-standard folder, set the path with the F1_CLI environment variable.
#!/usr/bin/env node
import { spawn } from "node:child_process";import { createInterface } from "node:readline";import { fileURLToPath, pathToFileURL } from "node:url";import path from "node:path";
// Path to the processor: can be set with the F1_CLI environment variable,// otherwise it uses the current system's standard installation folder.const installed = { darwin: `${process.env.HOME}/Applications/SumSheet.app/Contents/Resources/runtime/native/compute_contract_cli`, win32: "C:\\Program Files\\SumSheet\\resources\\runtime\\native\\compute_contract_cli.exe", linux: "/opt/SumSheet/resources/runtime/native/compute_contract_cli",};const binary = process.env.F1_CLI ?? installed[process.platform];if (!binary) throw new Error(`unknown system: ${process.platform}`);const workDir = path.resolve(process.argv[2] ?? path.dirname(fileURLToPath(import.meta.url)));const source = path.join(workDir, "input.xlsx");const destination = path.join(workDir, "result.xlsx");const viewport = { top: 0, left: 0, rows: 20, cols: 12 };
const child = spawn(binary, ["--session"], { stdio: ["pipe", "pipe", "inherit"],});const lines = createInterface({ input: child.stdout });const queue = [];let pending;
lines.on("line", (line) => { const value = JSON.parse(line); if (pending) { const resolve = pending; pending = undefined; resolve(value); } else { queue.push(value); }});
function nextLine() { if (queue.length) return Promise.resolve(queue.shift()); return new Promise((resolve) => { pending = resolve; });}
async function send(request) { child.stdin.write(`${JSON.stringify(request)}\n`); const response = await nextLine(); if (!response.ok) { throw new Error(`${request.operation}: ${JSON.stringify(response)}`); } return response.payload;}
function edit(sheetKey, row, col, inputKind, input) { return { sheetKey, row, col, inputKind, input };}
try { const handshake = await nextLine(); console.log("1. Session:", handshake.kind);
const opened = await send({ operation: "open_workbook_subset", sourceUri: pathToFileURL(source).href, viewport, requestedBackend: "native-desktop", }); const subsetId = opened.subsetId; const sheetKey = opened.activeSheet.path; console.log("2. Workbook opened:", opened.activeSheet.name, subsetId);
const applied = await send({ operation: "apply_cell_edits", subsetId, edits: [ edit(sheetKey, 0, 0, "text", "SumSheet API"), edit(sheetKey, 0, 1, "number", "21"), edit(sheetKey, 0, 2, "formula", "=B1*2"), ], expectedRevision: 0, viewport, requestedBackend: "native-desktop", }); console.log("3. Changes applied, revision:", applied.workbookHistory?.revision);
const cell = await send({ operation: "read_cell_details", subsetId, row: 0, col: 2, viewport, requestedBackend: "native-desktop", }); console.log("4. C1 after the formula:", cell.cell?.displayValue);
await send({ operation: "replay_workbook_history", subsetId, direction: "undo", viewport, requestedBackend: "native-desktop", }); await send({ operation: "replay_workbook_history", subsetId, direction: "redo", viewport, requestedBackend: "native-desktop", }); console.log("5. Undo/Redo: done");
await send({ operation: "save_workbook_subset", subsetId, destinationUri: pathToFileURL(destination).href, preserveCachedValues: true, requestedBackend: "native-desktop", }); console.log("6. Saved:", destination);
child.stdin.end(); await new Promise((resolve) => child.once("exit", resolve));
const verify = spawn(binary, ["--session"], { stdio: ["pipe", "pipe", "inherit"] }); const verifyLines = createInterface({ input: verify.stdout }); const iterator = verifyLines[Symbol.asyncIterator](); await iterator.next(); verify.stdin.write(`${JSON.stringify({ operation: "open_workbook_subset", sourceUri: pathToFileURL(destination).href, viewport, requestedBackend: "native-desktop", })}\n`); const reopened = JSON.parse((await iterator.next()).value); if (!reopened.ok) throw new Error(`cold reopen: ${JSON.stringify(reopened)}`); const reopenedSubsetId = reopened.payload.subsetId; verify.stdin.write(`${JSON.stringify({ operation: "read_cell_details", subsetId: reopenedSubsetId, row: 0, col: 2, viewport, requestedBackend: "native-desktop", })}\n`); const verified = JSON.parse((await iterator.next()).value); if (!verified.ok) throw new Error(`verify cell: ${JSON.stringify(verified)}`); console.log("7. Reopened, C1:", verified.payload.cell?.displayValue); verify.stdin.end(); verify.kill();} catch (error) { child.kill(); console.error(error); process.exitCode = 1;}The configuration it’s verified on
Section titled “The configuration it’s verified on”| Parameter | Value |
|---|---|
| Release catalog | dl.layers.md |
| Package | The macOS archive for Apple Silicon |
| Package integrity | Verified against SHA256SUMS from the macos/ folder of the release directory |
| Installation | ~/Applications/SumSheet.app |
| Processor | Contents/Resources/runtime/native/compute_contract_cli inside the package |
| Transport | JSON lines over stdin and stdout, --session mode |
| Verified result | C1 = 42 after editing, undo, redo, saving, and reopening in a new process |