@thatopen/services 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -352,7 +352,36 @@ is the reply. The full walkthrough (typed contracts, collaboration events,
352
352
  presence) is `node_modules/@thatopen/services/src/core/examples/channel.ts`,
353
353
  indexed in the client API index you already loaded.
354
354
 
355
- ## 5c. The desktop MCP server: `thatopen mcp`
355
+ ## 5c. History and recipes: documents, versions, change requests
356
+
357
+ Three sentences hold the whole model. Every connected document (a Revit model,
358
+ an AutoCAD drawing) has its version history: who synced, when, what changed.
359
+ Nobody writes in somebody else's document: changes arrive as SUGGESTIONS
360
+ (create/modify/delete native data) that the owner accepts or dismisses in the
361
+ native app. A RECIPE is a script that writes suggestions in an application's
362
+ own language, from whatever input.
363
+
364
+ ```ts
365
+ const history = client.history(projectId);
366
+ const docs = await history.docs(); // the connected documents
367
+ const doc = history.doc('revit', docs[0].docId);
368
+ const timeline = await doc.timeline(); // versions, oldest first
369
+ const pending = await doc.pendingSuggestions(); // waiting for the owner
370
+
371
+ client.recipes.register(myRecipe); // manifest + one run()
372
+ await client.recipes.run('my-recipe', { // only QUEUES a suggestion:
373
+ projectId, target: { source: 'revit', docId }, // trying is always safe
374
+ input, settings, author,
375
+ });
376
+ ```
377
+
378
+ This surface is the only supported way in: the storage underneath is private
379
+ and will move. Never list or write the `bimterop` files directly. The full
380
+ walkthrough (manifest fields, StaleHistoryError on concurrent syncs, payloads)
381
+ is `node_modules/@thatopen/services/src/core/examples/history.ts`, indexed in
382
+ the client API index you already loaded.
383
+
384
+ ## 5d. The desktop MCP server: `thatopen mcp`
356
385
 
357
386
  The raw socket above is for tools you write. For an LLM on the desktop (Claude
358
387
  Desktop, Claude Code, anything that speaks MCP), the CLI ships the same bridge
@@ -3,6 +3,13 @@
3
3
  The concrete contract. [The architecture notes](https://raw.githubusercontent.com/ThatOpen/platform_services/main/docs/flow-architecture.md) say why any of this is
4
4
  shaped the way it is; this says what the bytes look like.
5
5
 
6
+ > **Plug-ins only.** Since `@thatopen/services` 0.20, apps and scripts do not write this layout by
7
+ > hand: `client.history(projectId)` reads and writes documents, version timelines and proposals,
8
+ > and `client.recipes` runs the scripts that author them — see `src/core/examples/history.ts` in
9
+ > the package. The bytes below are the contract for NATIVE PLUG-INS (which carry their own client),
10
+ > and the reference for what the API does underneath. Anything else touching these files directly
11
+ > will break when the layout moves behind the API, which is the plan.
12
+
6
13
  Nothing here is aspirational. Every rule below is what the Revit and Rhino plugins already do, and
7
14
  was written from their implementation rather than ahead of it — which is why the awkward parts are
8
15
  stated as plainly as the tidy ones. Where a rule exists because something broke, it says so.
@@ -195,11 +195,17 @@ happened.
195
195
  Points count as items without geometry. That is correct: they are the data the converter reads, not
196
196
  something to draw.
197
197
 
198
- ## 5. The converter
198
+ ## 5. The converter (a recipe)
199
199
 
200
200
  This is the part that is **not** in either plug-in, and should not be. It reads the published
201
201
  `.frag`, decides what it means, and queues a proposal.
202
202
 
203
+ > A converter is one kind of **recipe**: a script that writes proposals in the target program's
204
+ > own words. Since `@thatopen/services` 0.20, write it against the SDK instead of the raw files:
205
+ > `client.history(projectId)` reads the queue and the timeline and queues the proposal
206
+ > (`doc.suggest`), and `client.recipes` is the registry/runner apps use to list it, render its
207
+ > settings form and run it safely. The four steps below are unchanged.
208
+
203
209
  The worked example is `RhinoColumnsConverter`: points on a named layer become Revit columns of a
204
210
  given family and type. It is written to be read and then rewritten — the next person wants walls
205
211
  from curves, or louvres from blocks — but four steps survive any rewrite:
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "access": "public"
16
16
  },
17
17
  "private": false,
18
- "version": "0.20.0",
18
+ "version": "0.22.0",
19
19
  "main": "dist/index.cjs.js",
20
20
  "module": "dist/index.es.js",
21
21
  "types": "dist/index.d.ts",