Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
351 commits
Select commit Hold shift + click to select a range
99fc013
WIP: async validation
kasbah Jun 23, 2026
e7f18ac
WIP: no type in linkForHandle
kasbah Jun 23, 2026
8a8a7ba
WIP: non-optional resolveModel
kasbah Jun 23, 2026
27a9fe8
WIP: plain store resolves models
kasbah Jun 23, 2026
30da582
WIP: validate only with core theory
kasbah Jun 23, 2026
a478701
WIP: ValidateableNotebook
kasbah Jun 23, 2026
2524872
WIP: no more link in instantiate
kasbah Jun 23, 2026
463e3fb
WIP: analyses
kasbah Jun 23, 2026
641b089
WIP: simulation
kasbah Jun 23, 2026
4a45f4f
WIP: content -> params
kasbah Jun 23, 2026
17a3af8
WIP: analyses
kasbah Jun 23, 2026
062ca02
WIP: analyses
kasbah Jun 24, 2026
e14862e
WIP: cleanup
kasbah Jun 25, 2026
4a91050
WIP: elaborated model and adjust petri net morphism type
kasbah Jun 25, 2026
1eb7997
WIP: modality list
kasbah Jun 25, 2026
a297c27
WIP: apply
kasbah Jun 25, 2026
7ed93ec
WIP: correct place for modality
kasbah Jun 25, 2026
2e09abf
WIP: minor
kasbah Jun 25, 2026
bb2de78
WIP: always domain codomain
kasbah Jun 25, 2026
ce790f1
WIP: minor
kasbah Jun 25, 2026
c6f7f1a
WIP: completion
kasbah Jun 25, 2026
d6a93f3
WIP: simplify simple schema completion
kasbah Jun 25, 2026
5ef39cc
WIP: typecheck tests
kasbah Jun 25, 2026
58adc15
WIP: notebook.get
kasbah Jun 25, 2026
b9bd10c
WIP: reactive validation
kasbah Jun 25, 2026
31c46e3
WIP: better reactivity
kasbah Jun 25, 2026
29bf526
WIP: cleanup
kasbah Jun 25, 2026
9a1cd73
WIP: cleaner testing
kasbah Jun 25, 2026
6c0299e
WIP: formalCells()
kasbah Jun 25, 2026
1d1bc17
WIP: test resource
kasbah Jun 25, 2026
e2b9497
WIP: onChange
kasbah Jun 26, 2026
b962e2e
WIP: add mutation test for onChange
kasbah Jun 26, 2026
f043065
WIP: onChangeFormalCells
kasbah Jun 26, 2026
91f648f
WIP: onChangeFormalContent
kasbah Jun 26, 2026
9ab234c
WIP: split future
kasbah Jun 26, 2026
b17132a
WIP: remove resolveAnalysis
kasbah Jun 26, 2026
66678e3
WIP: resolveModel
kasbah Jun 26, 2026
c84e8fe
WIP: resolve / validate
kasbah Jun 26, 2026
eb6407f
WIP: resolving
kasbah Jun 26, 2026
9cfad76
WIP: remove resolveWithModel
kasbah Jun 26, 2026
b7cd08e
WIP: getDocument -> getHandle
kasbah Jun 26, 2026
8e1fc79
WIP: clean up instantiation_validation
kasbah Jun 26, 2026
34e1023
WIP: recursive validation against host theory only
kasbah Jun 26, 2026
766a5b6
WIP: add test for instantiating olog in schema
kasbah Jun 26, 2026
97d2a3e
WIP: literate-typescript no .lts dir
kasbah Jun 26, 2026
abba710
WIP: validation test
kasbah Jun 26, 2026
302e73f
WIP: ArkType
kasbah Jun 29, 2026
c389aa5
WIP: rfc
kasbah Jun 29, 2026
4b0a5c0
WIP: standard-schema result
kasbah Jun 29, 2026
29c29b2
WIP: rfc
kasbah Jun 29, 2026
c4cff3c
WIP: get returns result
kasbah Jun 29, 2026
7e2adfb
WIP: result on loadNotebookFromHandle
kasbah Jun 29, 2026
edab274
WIP: loadNotebookFromHandle
kasbah Jun 29, 2026
36c2706
WIP: update "getting a cell by id"
kasbah Jun 29, 2026
3fde7e3
WIP: rfc
kasbah Jun 29, 2026
699e9d2
WIP: diagram
kasbah Jun 29, 2026
fde3e1c
WIP: diagram
kasbah Jun 29, 2026
b9880ea
WIP: rfc
kasbah Jun 30, 2026
3d184ae
WIP: rfc
kasbah Jun 30, 2026
ea069d6
WIP: rfc
kasbah Jun 30, 2026
4258c81
WIP: rfc gaios
kasbah Jun 30, 2026
92118f1
WIP: rfc link
kasbah Jul 1, 2026
3c55bb4
WIP: fix lts rfc
kasbah Jul 1, 2026
475533f
WIP: rfc
kasbah Jul 1, 2026
33cfed5
WIP: verifyer
kasbah Jul 1, 2026
fc903c2
WIP: null
kasbah Jul 1, 2026
06cbf08
WIP: move rfc
kasbah Jul 1, 2026
f39c833
WIP: rfc
kasbah Jul 1, 2026
232d195
WIP: diagrams and analyses
kasbah Jul 1, 2026
9196f27
WIP: rfc
kasbah Jul 1, 2026
b47699a
WIP: delimiters around field names in validation
kasbah Jul 1, 2026
d5f9a47
WIP: rfc
kasbah Jul 1, 2026
f4c5237
WIP: ModelValidationResult
kasbah Jul 1, 2026
4ac39af
WIP: rfc
kasbah Jul 1, 2026
7a24350
WIP: remove `get`
kasbah Jul 1, 2026
1211f29
WIP: result
kasbah Jul 1, 2026
c869f5f
WIP: rfc
kasbah Jul 1, 2026
6dde50f
WIP: rfc
kasbah Jul 2, 2026
dbaea10
WIP: result type for analysis.run
kasbah Jul 2, 2026
fe89021
WIP: result
kasbah Jul 2, 2026
2255ed6
WIP: backend_document_store.test.tsx
kasbah Jul 2, 2026
9e3dc55
WIP: getHandle async
kasbah Jul 2, 2026
0c9c5ed
WIP: doc store
kasbah Jul 2, 2026
95253ff
WIP: async createNotebook
kasbah Jul 2, 2026
4652340
WIP: makeReactiveProjection
kasbah Jul 2, 2026
0b11eeb
WIP: instances
kasbah Jul 2, 2026
a5175c3
WIP: demo
kasbah Jul 2, 2026
cc681d0
WIP: demo deploy
kasbah Jul 3, 2026
e8dd615
WIP: instance document type
kasbah Jul 3, 2026
06197ce
WIP: triples
kasbah Jul 3, 2026
8250844
WIP: fix attribute adding
kasbah Jul 3, 2026
f94a869
WIP: tiling
kasbah Jul 3, 2026
25c005d
WIP: headers
kasbah Jul 3, 2026
d146fda
WIP: ref style
kasbah Jul 3, 2026
6ca0d80
WIP: ref name
kasbah Jul 3, 2026
abdf4af
WIP: bigger tables
kasbah Jul 3, 2026
94bc981
WIP: x
kasbah Jul 3, 2026
57a7b7a
WIP: empty column
kasbah Jul 3, 2026
d991039
WIP: history
kasbah Jul 3, 2026
b1f6aa8
WIP: + row on empty
kasbah Jul 3, 2026
4bb8772
WIP: hack jspreadsheet to not confirm delete row
kasbah Jul 3, 2026
9954cbb
WIP: fix morphism name collisions
kasbah Jul 3, 2026
8ed755e
WIP: script
kasbah Jul 3, 2026
9e0bd7e
WIP: persist memory
kasbah Jul 3, 2026
21ad8e9
WIP: script instance
kasbah Jul 3, 2026
e09c5a5
WIP: no script helpers
kasbah Jul 3, 2026
6899630
WIP: script at bottom
kasbah Jul 3, 2026
3842a80
WIP: rowsOf
kasbah Jul 3, 2026
7fc6396
WIP: reset scripts
kasbah Jul 3, 2026
b9c82b4
WIP: one code
kasbah Jul 3, 2026
754d616
WIP: fix firefox code scroll
kasbah Jul 3, 2026
9b17913
WIP: bottom reset
kasbah Jul 3, 2026
9615c4c
WIP: add example
kasbah Jul 3, 2026
40fccbd
WIP: x
kasbah Jul 3, 2026
46d2fa2
WIP: skill
kasbah Jul 3, 2026
04920b8
WIP: performance
kasbah Jul 3, 2026
35964ca
WIP: entity styling
kasbah Jul 3, 2026
0cf7e1c
WIP: arrow style
kasbah Jul 3, 2026
65f09a9
WIP: don't infer in instance validate
kasbah Jul 3, 2026
2e7097c
WIP: edit font size
kasbah Jul 3, 2026
61deecc
WIP: scripty scripty
kasbah Jul 3, 2026
51c0c7b
WIP: result type
kasbah Jul 6, 2026
d9b960f
WIP: x
kasbah Jul 6, 2026
e44fb17
WIP: lint
kasbah Jul 6, 2026
12a696e
WIP: cleanup
kasbah Jul 6, 2026
92784e3
WIP: rfc shape
kasbah Jul 6, 2026
8ca321d
WIP: rfc shapes
kasbah Jul 6, 2026
d67830f
WIP: solid shape rfc
kasbah Jul 6, 2026
04ebd02
WIP: link shapes-of-a-logic
kasbah Jul 6, 2026
acc40b3
WIP: shape
kasbah Jul 6, 2026
c051603
WIP: shape includeRichText
kasbah Jul 6, 2026
51825b0
WIP: petri net example rfc
kasbah Jul 6, 2026
ed34d50
WIP: cleanup rfc
kasbah Jul 6, 2026
f422375
WIP: getDocument
kasbah Jul 6, 2026
30ac7ec
WIP: subscribe not optional
kasbah Jul 6, 2026
b19fcac
WIP: minor
kasbah Jul 6, 2026
4396a9a
WIP: getHandle LInk
kasbah Jul 6, 2026
079706d
WIP: getDocumentView
kasbah Jul 6, 2026
bc22fdf
WIP: x
kasbah Jul 6, 2026
f272654
WIP: rfc binders
kasbah Jul 6, 2026
c48ae45
WIP: cleanup
kasbah Jul 6, 2026
bfea791
WIP: completion example
kasbah Jul 6, 2026
b257d8c
WIP: no theory on attr picker shape
kasbah Jul 6, 2026
4b97a12
WIP: context
kasbah Jul 6, 2026
c37a55c
WIP: more clear script button
kasbah Jul 6, 2026
92a644f
WIP: demo storage error
kasbah Jul 6, 2026
bd55398
WIP: storage error dialog
kasbah Jul 6, 2026
db8c327
WIP: solid with completions
kasbah Jul 6, 2026
adae8fe
WIP: move settled
kasbah Jul 6, 2026
4746f9a
WIP: remove unknown
kasbah Jul 6, 2026
b98a319
WIP: object editor 1
kasbah Jul 6, 2026
18c4a94
WIP: x
kasbah Jul 6, 2026
01ff067
WIP: object editor
kasbah Jul 6, 2026
d6d340e
WIP: cellsOf in notebook_with_solid_object_editor
kasbah Jul 6, 2026
5317bac
WIP: spread cellsOf
kasbah Jul 6, 2026
a47df51
WIP: schema for notebook_with_solid_object_editor
kasbah Jul 6, 2026
7074b38
WIP: editing schema solid editor
kasbah Jul 6, 2026
bbad8f2
WIP: notebook_with_solid_morphism_editor
kasbah Jul 6, 2026
881be29
WIP: fine grained solid
kasbah Jul 6, 2026
574ab15
WIP: ModelDocument -> Document
kasbah Jul 6, 2026
8c5ef7c
WIP: fix reconcile
kasbah Jul 6, 2026
e3ae5da
WIP: draftDoc
kasbah Jul 6, 2026
3bbe3e6
WIP: ModelDocument -> Document
kasbah Jul 6, 2026
e3bec1f
WIP: doc -> docView
kasbah Jul 6, 2026
a244101
WIP: solid demo
kasbah Jul 6, 2026
2693cd0
WIP: demo "no rows"
kasbah Jul 6, 2026
f37a45a
WIP: better validation in demo
kasbah Jul 6, 2026
ef6e52a
WIP: simple schema example rfc
kasbah Jul 6, 2026
8d9c02a
WIP: rfc cleanup
kasbah Jul 7, 2026
c8f4341
WIP: getCoreTheory
kasbah Jul 7, 2026
ebd739b
WIP: migrate async
kasbah Jul 7, 2026
4e65b39
WIP: migrate schema -> olog
kasbah Jul 7, 2026
0c46b16
WIP: rfc simple-schema
kasbah Jul 7, 2026
4dbecc5
WIP: NotebookCell<>
kasbah Jul 7, 2026
3ebba1a
WIP: NotebookCell
kasbah Jul 7, 2026
47d667f
WIP: cleanup rfc
kasbah Jul 7, 2026
c62f57c
WIP: literate-ts click
kasbah Jul 7, 2026
8975b26
WIP: literate-ts cleanup
kasbah Jul 7, 2026
1e2fe27
WIP: notebook_with_solid_completions
kasbah Jul 7, 2026
9e10141
WIP
kasbah Jul 7, 2026
2d039c0
WIP: schema -> my
kasbah Jul 7, 2026
270c5d6
WIP: move validatable
kasbah Jul 7, 2026
1a10261
WIP: MyContext
kasbah Jul 7, 2026
b937676
WIP: MyNotebook in context
kasbah Jul 7, 2026
8f9875d
WIP: .get in rfc
kasbah Jul 7, 2026
b70ed29
WIP: minor
kasbah Jul 7, 2026
06c8b4d
WIP: informal: [RichText]
kasbah Jul 7, 2026
6306d1e
WIP: typing analysis
kasbah Jul 7, 2026
b7d493f
WIP: test richtext
kasbah Jul 7, 2026
b33cdac
WIP: analysies params type checking
kasbah Jul 7, 2026
108fb4b
WIP: type check analysis result
kasbah Jul 7, 2026
8e6614d
WIP: test richtext
kasbah Jul 7, 2026
9597bec
WIP: rich text test 2
kasbah Jul 7, 2026
f0d59a5
WIP: richtext impl
kasbah Jul 7, 2026
d0b7b27
WIP: richtext impl
kasbah Jul 7, 2026
11764b6
WIP: editorRef
kasbah Jul 7, 2026
a80978a
WIP: richtext_frontend_editor.test.tsx
kasbah Jul 7, 2026
15ce9cb
WIP: rich text ref
kasbah Jul 7, 2026
26f63bd
WIP: rfc solid completions
kasbah Jul 7, 2026
d797e25
WIP: onChange rfc
kasbah Jul 7, 2026
de91107
WIP: mass action
kasbah Jul 7, 2026
ee5533e
WIP: mass action 2
kasbah Jul 7, 2026
a91685f
WIP: rich text example rfc
kasbah Jul 7, 2026
991ba65
WIP: remove prose notebook_with_solid_completions
kasbah Jul 7, 2026
983db2e
WIP: analysis
kasbah Jul 7, 2026
e9c91ba
WIP: minor
kasbah Jul 7, 2026
32f114a
WIP: minor
kasbah Jul 7, 2026
991b9d4
WIP: validation cache
kasbah Jul 7, 2026
1448a93
WIP: onValidation
kasbah Jul 7, 2026
cdba288
WIP: onValidate
kasbah Jul 7, 2026
fef8d27
WIP: svg render
kasbah Jul 7, 2026
0603376
WIP: split analyses files
kasbah Jul 7, 2026
775a02d
WIP: render svg with solid
kasbah Jul 7, 2026
f4a9564
WIP: vhtml visualization
kasbah Jul 7, 2026
9ea6b18
WIP: minor
kasbah Jul 7, 2026
0abaace
WIP: rfc supports
kasbah Jul 7, 2026
c0194c4
WIP: minor
kasbah Jul 7, 2026
7716c11
WIP: onValidate rfc
kasbah Jul 8, 2026
60fad86
WIP: supportsInstances
kasbah Jul 8, 2026
4ee2a75
WIP: result rfc
kasbah Jul 8, 2026
54e3818
WIP: rfc minor
kasbah Jul 8, 2026
2861bdc
WIP: rollout rfc
kasbah Jul 8, 2026
f12e50f
WIP: rfc
kasbah Jul 8, 2026
106f034
WIP: rfc minor
kasbah Jul 8, 2026
0c14523
FIX: tsify output for `Composite`
kasbah Apr 28, 2026
8eef545
ENH: Equations cell editor
kasbah Jun 24, 2026
f9846b6
ENH: Loosely filter out morphisms in paths based on domain
kasbah Jun 24, 2026
084dc63
ENH: Make a specialized path morphism input
kasbah Jun 24, 2026
6f535ed
WIP: path equations
kasbah Jul 8, 2026
d1d417d
WIP: path equations
kasbah Jul 8, 2026
bba459a
WIP: rfc
kasbah Jul 8, 2026
107fb36
WIP: path equations clean up
kasbah Jul 8, 2026
0b78a78
WIP: instance rfc
kasbah Jul 8, 2026
82a2a89
WIP: rfc schema instance schema
kasbah Jul 8, 2026
f84da52
WIP: rfcing
kasbah Jul 8, 2026
800051c
WIP: rfcing2
kasbah Jul 8, 2026
182e57e
WIP: rfcing3
kasbah Jul 8, 2026
8af6ffa
WIP: rfc backport
kasbah Jul 9, 2026
35f611d
WIP: fix dep build in package.json
kasbah Jul 9, 2026
3f709f8
WIP: rfc minor
kasbah Jul 9, 2026
95624c4
WIP: name -> label
kasbah Jul 9, 2026
17de6d9
WIP: loadNotebookFromLink
kasbah Jul 9, 2026
c2a4d0a
WIP: DocumentRef
kasbah Jul 9, 2026
d1b148d
WIP: Link -> DocumentRef
kasbah Jul 9, 2026
9a58f0a
WIP: server optional
kasbah Jul 9, 2026
cdf501d
WIP: getHandle returns Result
kasbah Jul 9, 2026
6ddcfb7
WIP: getDocumentRef
kasbah Jul 9, 2026
3b90815
WIP: remove as const
kasbah Jul 9, 2026
7566c09
WIP: verifier:skip
kasbah Jul 9, 2026
dd25404
WIP: minor
kasbah Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
build_dev_docs:
name: Build developer docs
runs-on: ubuntu-latest
needs: build_instances_mockup
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -58,6 +59,12 @@ jobs:
echo "🔨 Dev docs built and cached"
fi

- name: Include instances mockup in developer docs
uses: actions/download-artifact@v4
with:
name: instances-mockup
path: dev-docs/output/instances-mockup

- name: Upload developer docs
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -168,6 +175,70 @@ jobs:
name: frontend_docs
path: packages/frontend/docs

build_instances_mockup:
name: Build instances mockup
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0

- name: Compute cache key
id: cache-key
run: |
hash=$(git log -1 --format="%H" -- packages/document-methods packages/catlog-wasm packages/document-types packages/ui-components tools/vite-plugin-monorepo-dedupe pnpm-lock.yaml pnpm-workspace.yaml)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "Instances mockup hash: ${hash}"

- name: Cache instances mockup build
id: cache-instances-mockup
uses: actions/cache@v4
with:
path: packages/document-methods/demo/dist
key: instances-mockup-${{ steps.cache-key.outputs.git-hash }}

- name: Setup pnpm
if: steps.cache-instances-mockup.outputs.cache-hit != 'true'
uses: pnpm/action-setup@v4

- name: Setup NodeJS
if: steps.cache-instances-mockup.outputs.cache-hit != 'true'
uses: actions/setup-node@v4
with:
node-version: 24
cache: "pnpm"

- name: Install Rust toolchain from file
if: steps.cache-instances-mockup.outputs.cache-hit != 'true'
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# Don't override flags in cargo config files.
rustflags: ""

- name: Build instances mockup
if: steps.cache-instances-mockup.outputs.cache-hit != 'true'
run: |
pnpm install
pnpm --filter ./packages/document-methods run build:wasm
pnpm --filter ./packages/document-methods exec wasm-pack build ../catlog-wasm --target browser -d ./dist/pkg-browser --debug
pnpm --filter ./packages/document-methods run demo:build

- name: Report cache status
run: |
if [ "${{ steps.cache-instances-mockup.outputs.cache-hit }}" = "true" ]; then
echo "✅ Instances mockup restored from cache"
else
echo "🔨 Instances mockup built and cached"
fi

- name: Upload instances mockup
uses: actions/upload-artifact@v4
with:
name: instances-mockup
path: packages/document-methods/demo/dist

build_rust_docs:
name: Build Rust docs
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
mv rust_docs site/dev/rust
mv frontend_docs site/dev/frontend
mv ui-components site/dev/ui-components
mv instances-mockup site/dev/instances-mockup
mv math-docs site/math
mv rfc site/rfc
echo '/dev/rust /dev/rust/catlog' >> site/_redirects
Expand Down
216 changes: 216 additions & 0 deletions packages/document-methods/.agents/skills/catcolab-demo/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
---
name: catcolab-instances-demo-script
description: Drive the CatColab instances demo by running its script via the WebMCP `run_script` tool over Chrome DevTools. Use when you need to programmatically build or edit the demo's schema and instance (entities, mappings, attributes, and rows) in a running browser.
---

# CatColab instances demo: scripting via WebMCP + Chrome DevTools

The instances demo (`pnpm demo` in `packages/document-methods`) exposes a single
WebMCP tool, `run_script`, on `document.modelContext`. It writes JavaScript into
the demo's script editor, opens the script pane, and **runs it**, returning the
script's return value (or thrown error). This skill covers driving that tool
through the Chrome DevTools MCP and what the script may contain.

## Prerequisites

- The demo dev server is running (default `http://localhost:5173/`). It is
usually already running; check first.
- A Chrome DevTools MCP connection to that page.

The page installs the WebMCP polyfill at startup, so `document.modelContext`
exists app-wide and `run_script` is registered even when the script pane is
closed.

## Using `run_script` over Chrome DevTools

Chrome DevTools MCP has no direct WebMCP bridge, so call the tool through
`evaluate_script`, which runs in the page and can reach `document.modelContext`.

1. Navigate to the demo (only if not already there):

`navigate_page` -> `http://localhost:5173/`

2. (Optional) List tools to confirm registration:

```js
() =>
document.modelContext
.getTools()
.then((ts) => ts.map((t) => ({ name: t.name, inputSchema: t.inputSchema })));
```

Expect a `run_script` tool whose `inputSchema` (returned as a JSON string)
describes a single required `script` string property.

3. Execute it. `executeTool` takes a tool descriptor from `getTools()` and a
**JSON string** of arguments, and returns a JSON string:

```js
async () => {
const mc = document.modelContext;
const tool = (await mc.getTools()).find((t) => t.name === "run_script");
return mc.executeTool(
tool,
JSON.stringify({
script:
`const p = schema.add(Entity, { label: "Person" });\n` +
`schema.add(Attr, { label: "name", from: p, to: attrTypes.String });\n`,
}),
);
};
```

On success it returns
`{"content":[{"type":"text","text":"Script ran successfully."}]}` (with the
returned value appended, if the script returned one), and the script pane
opens with the source shown. If the script throws, the result is an error
with the message `Script threw: …`.

4. Verify (optional). There are two `<textarea>`s on the page (one belongs to
the instance grid); the script editor is the one holding your source:

```js
() => [...document.querySelectorAll("textarea")].map((t) => t.value);
```

The source is also persisted to `localStorage["catcolab-instances-demo:script"]`.

Notes:

- `run_script` executes the script immediately: the schema and instance update
as soon as the tool returns. No human Run press is needed.
- Calling it again replaces the editor contents and runs the new script.

## What can go in the script

The script body runs inside an `async` function (so you may use top-level
`await`) with these names in scope:

| Name | What it is |
| ----------- | ----------------------------------------------------------------- |
| `schema` | The schema notebook (a `Notebook` over `SimpleSchema`). |
| `instance` | The instance (a database of `schema`). |
| `doc` | The demo document wrapper (`{ schema, instance, attrTypes, … }`). |
| `attrTypes` | `{ String, Number }` — the two fixed attribute-type cells. |
| `Entity` | Object def: an entity (a table). |
| `Mapping` | Morphism def: a foreign key `Entity -> Entity`. |
| `Attr` | Morphism def: an attribute `Entity -> AttrType`. |
| `AttrType` | Object def for attribute types (only `String`/`Number` are used). |

Every mutation goes through the same document API the UI uses, so the notebook,
instance tables, history, and persistence all update as with point-and-click
edits. The script has full access to the page (it is a demo affordance, not a
sandbox).

> **Always reset first.** Scripts are additive and the schema/instance persist
> across runs (via `localStorage`), so building on top of whatever is already
> there produces duplicate cells and rows. Unless the human explicitly asks to
> extend the current state, begin every schema-building script with the reset
> block from [Resetting the schema](#resetting-the-schema), which deletes every
> cell except the two fixed `AttrType` cells.

### Schema API (`schema`)

```js
// Add cells. Each returns a live cell handle.
const person = schema.add(Entity, { label: "Person" });
const company = schema.add(Entity, { label: "Company" });
const name = schema.add(Attr, { label: "name", from: person, to: attrTypes.String });
const age = schema.add(Attr, { label: "age", from: person, to: attrTypes.Number });
const employer = schema.add(Mapping, { label: "employer", from: person, to: company });

// List cells of a kind.
schema.cellsOf(Entity); // -> entity cells
schema.cellsOf(Attr); // -> attribute cells
schema.cellsOf(Mapping); // -> mapping cells

// Edit / remove a cell.
person.update({ label: "Human" });
employer.update({ to: company }); // change a mapping's codomain
age.delete(); // remove a cell
```

Attribute codomains must be `attrTypes.String` or `attrTypes.Number`. A
`Mapping`'s `from`/`to` are `Entity` cells; an `Attr`'s `from` is an `Entity`
cell and `to` is an `attrTypes` cell.

#### Resetting the schema

To start from a clean schema, delete every cell **except** the `AttrType` cells.
The fixed `String`/`Number` attribute types are ordinary `AttrType` cells, so
skipping them keeps `doc.attrTypes` pointing at the live cells the UI, instance
editor, and later scripts already reference:

```js
const attrTypeIds = new Set(schema.cellsOf(AttrType).map((c) => c.id));
for (const c of schema.cells()) {
if (!attrTypeIds.has(c.id)) c.delete();
}
```

After this, `attrTypes.String` / `attrTypes.Number` still point at the surviving
attribute-type cells, so schema-building continues as normal.

### Instance API (`instance`)

```js
// Add rows. Inline args name the entity's outgoing attributes and mappings.
const acme = instance.add(company, {});
const fred = instance.add(person, { name: "Fred", employer: acme });

// List rows.
instance.rows(); // all rows
instance.rowsOf(person); // rows of one entity

// Validate against the schema (async).
const result = await instance.validate(); // { tag: "Valid" | "Invalid" | "Illformed", ... }
```

### Row API (a `Row` from `add` / `rows()`)

```js
fred.id; // stable row id (use as a mapping target)
fred.entity; // the schema entity this row is a record of
fred.get(name); // value for a morphism, keyed by its UUID (collision-free)
fred.set(name, "Freddy"); // set an attribute literal, or a mapping's target Row
fred.set(employer, acme); // point a foreign key at another row
fred.set(name, undefined); // clear a value
fred.values; // { [morphismName]: value } (names may collide; last wins)
fred.valuesById; // { [morphismUUID]: value } (collision-free)
fred.delete(); // delete this row
```

- A mapping value is the **target `Row`**; an attribute value is a **literal**
(`string` for `String`, `number` for `Number`).
- Prefer `get(morphism)` / `valuesById` over `values` when a schema may have
two morphisms sharing a name.
- Deleting a row leaves foreign keys pointing at it dangling; they show as
invalid on the next `validate()`.

### Complete example

Build a small schema and populate an instance in one script. Note the reset at
the top — always start from a clean slate unless asked to extend existing state:

```js
// Reset: delete every cell except the two fixed attribute types.
const attrTypeIds = new Set(schema.cellsOf(AttrType).map((c) => c.id));
for (const c of schema.cells()) {
if (!attrTypeIds.has(c.id)) c.delete();
}

const person = schema.add(Entity, { label: "Person" });
const company = schema.add(Entity, { label: "Company" });
schema.add(Attr, { label: "name", from: person, to: attrTypes.String });
schema.add(Mapping, { label: "employer", from: person, to: company });

const acme = instance.add(company, {});
instance.add(person, { name: "Fred", employer: acme });
instance.add(person, { name: "Wilma", employer: acme });

const result = await instance.validate();
result.tag; // the async function's return value is shown in the status line
```

The script's return value (or a thrown error) is returned by `run_script` and
also displayed under the editor.
2 changes: 2 additions & 0 deletions packages/document-methods/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.lts/
demo/dist
12 changes: 12 additions & 0 deletions packages/document-methods/demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CatColab Instances Demo</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading