@lambdacurry/arbor 0.22.6 → 0.22.8

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.
Files changed (2) hide show
  1. package/dist/arbor.js +441 -1
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // package.json
3
3
  var package_default = {
4
4
  name: "@lambdacurry/arbor",
5
- version: "0.22.6",
5
+ version: "0.22.8",
6
6
  description: "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
7
7
  keywords: [
8
8
  "agents",
@@ -6914,6 +6914,9 @@ var artifactVersions = sqliteTable("artifact_versions", {
6914
6914
  artifactId: text("artifact_id").notNull().references(() => artifacts.id),
6915
6915
  version: integer2("version").notNull(),
6916
6916
  source: text("source").notNull(),
6917
+ sourceAttachmentId: text("source_attachment_id").references(() => attachments.id),
6918
+ sourceSha256: text("source_sha256"),
6919
+ tldrawDocumentClock: integer2("tldraw_document_clock"),
6917
6920
  editorProfileId: text("editor_profile_id").notNull().references(() => profiles.id),
6918
6921
  executionContextId: text("execution_context_id").references(() => executionContexts.id),
6919
6922
  note: text("note"),
@@ -6921,6 +6924,95 @@ var artifactVersions = sqliteTable("artifact_versions", {
6921
6924
  }, (t) => ({
6922
6925
  artifactVersionUq: uniqueIndex("artifact_versions_artifact_version_uq").on(t.artifactId, t.version)
6923
6926
  }));
6927
+ var artifactTldrawBoards = sqliteTable("artifact_tldraw_boards", {
6928
+ artifactId: text("artifact_id").primaryKey().references(() => artifacts.id, { onDelete: "cascade" }),
6929
+ roomGeneration: integer2("room_generation").notNull().default(1),
6930
+ documentClock: integer2("document_clock").notNull().default(0),
6931
+ documentDigest: text("document_digest").notNull(),
6932
+ currentVersion: integer2("current_version").notNull().default(0),
6933
+ createIdempotencyKey: text("create_idempotency_key").notNull(),
6934
+ createActorProfileId: text("create_actor_profile_id").notNull().references(() => profiles.id),
6935
+ createThreadId: text("create_thread_id").notNull().references(() => threads.id),
6936
+ createFingerprint: text("create_fingerprint").notNull(),
6937
+ checkpointedAt: ts("checkpointed_at"),
6938
+ updatedAt: ts("updated_at").notNull()
6939
+ }, (t) => ({
6940
+ createKeyUq: uniqueIndex("artifact_tldraw_boards_create_key_uq").on(t.createActorProfileId, t.createThreadId, t.createIdempotencyKey)
6941
+ }));
6942
+ var artifactTldrawCheckpoints = sqliteTable("artifact_tldraw_checkpoints", {
6943
+ id: text("id").primaryKey(),
6944
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id, { onDelete: "cascade" }),
6945
+ actorProfileId: text("actor_profile_id").notNull().references(() => profiles.id),
6946
+ idempotencyKey: text("idempotency_key").notNull(),
6947
+ requestFingerprint: text("request_fingerprint").notNull(),
6948
+ resultArtifactVersionId: text("result_artifact_version_id").notNull().references(() => artifactVersions.id),
6949
+ resultVersion: integer2("result_version").notNull(),
6950
+ createdAt: ts("created_at").notNull()
6951
+ }, (t) => ({
6952
+ requestUq: uniqueIndex("artifact_tldraw_checkpoints_request_uq").on(t.artifactId, t.actorProfileId, t.idempotencyKey)
6953
+ }));
6954
+ var artifactTldrawScriptVersions = sqliteTable("artifact_tldraw_script_versions", {
6955
+ id: text("id").primaryKey(),
6956
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id, { onDelete: "cascade" }),
6957
+ version: integer2("version").notNull(),
6958
+ attachmentId: text("attachment_id").notNull().references(() => attachments.id),
6959
+ digest: text("digest").notNull(),
6960
+ byteLength: integer2("byte_length").notNull(),
6961
+ createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
6962
+ createdAt: ts("created_at").notNull()
6963
+ }, (t) => ({
6964
+ artifactVersionUq: uniqueIndex("artifact_tldraw_script_versions_artifact_version_uq").on(t.artifactId, t.version),
6965
+ artifactDigestUq: uniqueIndex("artifact_tldraw_script_versions_artifact_digest_uq").on(t.artifactId, t.digest)
6966
+ }));
6967
+ var artifactTldrawDocumentScripts = sqliteTable("artifact_tldraw_document_scripts", {
6968
+ artifactId: text("artifact_id").primaryKey().references(() => artifacts.id, { onDelete: "cascade" }),
6969
+ revision: integer2("revision").notNull().default(0),
6970
+ currentVersion: integer2("current_version"),
6971
+ currentAttachmentId: text("current_attachment_id").references(() => attachments.id),
6972
+ currentDigest: text("current_digest"),
6973
+ currentByteLength: integer2("current_byte_length"),
6974
+ approvedVersion: integer2("approved_version"),
6975
+ approvedDigest: text("approved_digest"),
6976
+ approvedByProfileId: text("approved_by_profile_id").references(() => profiles.id),
6977
+ approvedAt: ts("approved_at"),
6978
+ enabled: integer2("enabled", { mode: "boolean" }).notNull().default(false),
6979
+ updatedAt: ts("updated_at").notNull()
6980
+ });
6981
+ var artifactTldrawExecs = sqliteTable("artifact_tldraw_execs", {
6982
+ id: text("id").primaryKey(),
6983
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id, { onDelete: "cascade" }),
6984
+ requestId: text("request_id").notNull(),
6985
+ sourceDigest: text("source_digest").notNull(),
6986
+ requestFingerprint: text("request_fingerprint").notNull(),
6987
+ expectedDocumentClock: integer2("expected_document_clock"),
6988
+ settleMs: integer2("settle_ms"),
6989
+ startDocumentClock: integer2("start_document_clock").notNull(),
6990
+ startDocumentDigest: text("start_document_digest").notNull(),
6991
+ endDocumentClock: integer2("end_document_clock"),
6992
+ endDocumentDigest: text("end_document_digest"),
6993
+ outcome: text("outcome").notNull(),
6994
+ resultDigest: text("result_digest"),
6995
+ error: text("error"),
6996
+ completionFingerprint: text("completion_fingerprint"),
6997
+ actorProfileId: text("actor_profile_id").notNull().references(() => profiles.id),
6998
+ createdAt: ts("created_at").notNull(),
6999
+ completedAt: ts("completed_at")
7000
+ }, (t) => ({
7001
+ requestUq: uniqueIndex("artifact_tldraw_execs_request_uq").on(t.artifactId, t.actorProfileId, t.requestId),
7002
+ requestLength: check("artifact_tldraw_execs_request_length", sql`length(${t.requestId}) BETWEEN 1 AND 200`),
7003
+ digestLength: check("artifact_tldraw_execs_digest_length", sql`length(${t.sourceDigest}) BETWEEN 1 AND 200`),
7004
+ settleNonnegative: check("artifact_tldraw_execs_settle_nonnegative", sql`${t.settleMs} IS NULL OR ${t.settleMs} >= 0`),
7005
+ resultLength: check("artifact_tldraw_execs_result_length", sql`${t.resultDigest} IS NULL OR length(${t.resultDigest}) <= 200`),
7006
+ errorLength: check("artifact_tldraw_execs_error_length", sql`${t.error} IS NULL OR length(${t.error}) <= 2000`)
7007
+ }));
7008
+ var artifactTldrawViewerGrantUses = sqliteTable("artifact_tldraw_viewer_grant_uses", {
7009
+ id: text("id").primaryKey(),
7010
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id, { onDelete: "cascade" }),
7011
+ grantId: text("grant_id").notNull(),
7012
+ profileId: text("profile_id").notNull().references(() => profiles.id),
7013
+ createdAt: ts("created_at").notNull(),
7014
+ usedAt: ts("used_at")
7015
+ }, (t) => ({ grantUq: uniqueIndex("artifact_tldraw_viewer_grant_uses_grant_uq").on(t.grantId) }));
6924
7016
  var secrets = sqliteTable("secrets", {
6925
7017
  id: text("id").primaryKey(),
6926
7018
  orgId: text("org_id").notNull().references(() => orgs.id),
@@ -8601,6 +8693,116 @@ var MCP_OUTPUT_SCHEMAS = {
8601
8693
  nextLine: number2().int().min(1).nullable().optional(),
8602
8694
  totalLines: number2().int().nonnegative().optional()
8603
8695
  }),
8696
+ tldraw_import: looseObject({
8697
+ artifactId: id,
8698
+ artifactVersionId: id,
8699
+ version: number2().int().min(1),
8700
+ sourceAttachmentId: id,
8701
+ sourceSha256: string2(),
8702
+ documentClock: number2().int().min(0),
8703
+ replayed: boolean2(),
8704
+ url: string2().optional()
8705
+ }),
8706
+ tldraw_get: looseObject({
8707
+ artifactId: id,
8708
+ title: string2(),
8709
+ summary: string2(),
8710
+ sourceThreadId: id,
8711
+ version: number2().int().min(1),
8712
+ selectedVersion: number2().int().min(1),
8713
+ historical: boolean2(),
8714
+ canEdit: boolean2(),
8715
+ source: jsonObject,
8716
+ current: jsonObject,
8717
+ versionRefs: array(jsonObject),
8718
+ script: jsonObject
8719
+ }),
8720
+ tldraw_workbench: looseObject({
8721
+ artifactId: id,
8722
+ runId: id,
8723
+ TLDRAW_LOCAL_ROOT: string2(),
8724
+ paths: looseObject({
8725
+ board: string2(),
8726
+ script: string2().nullable(),
8727
+ manifest: string2()
8728
+ }),
8729
+ manifest: jsonObject
8730
+ }),
8731
+ tldraw_status: looseObject({
8732
+ artifactId: id,
8733
+ room: jsonObject,
8734
+ script: jsonObject
8735
+ }),
8736
+ tldraw_checkpoint: looseObject({
8737
+ artifactId: id,
8738
+ ok: boolean2(),
8739
+ changed: boolean2().optional(),
8740
+ version: number2().int().min(1).optional(),
8741
+ replayed: boolean2().optional()
8742
+ }),
8743
+ tldraw_publish: looseObject({
8744
+ artifactId: id,
8745
+ artifactVersionId: id.optional(),
8746
+ version: number2().int().min(1).optional(),
8747
+ sourceAttachmentId: id.optional(),
8748
+ documentClock: number2().int().min(0).optional(),
8749
+ replayed: boolean2().optional()
8750
+ }),
8751
+ tldraw_script: looseObject({
8752
+ artifactId: id,
8753
+ revision: number2().int().min(0),
8754
+ status: _enum(["absent", "approval-required", "enabled", "disabled"]),
8755
+ source: jsonObject.nullable(),
8756
+ approval: jsonObject.nullable()
8757
+ }),
8758
+ tldraw_observe: looseObject({
8759
+ artifactId: id,
8760
+ documentClock: number2().int().min(0),
8761
+ documentDigest: string2(),
8762
+ scene: looseObject({
8763
+ shapes: array(jsonObject),
8764
+ bindings: array(jsonObject),
8765
+ lint: array(jsonObject),
8766
+ truncation: looseObject({
8767
+ shapesOmitted: number2().int().nonnegative(),
8768
+ bindingsOmitted: number2().int().nonnegative(),
8769
+ bindingRecordsUninspected: number2().int().nonnegative(),
8770
+ findingsOmitted: number2().int().nonnegative(),
8771
+ textShapesTruncated: number2().int().nonnegative(),
8772
+ pageNameCharactersOmitted: number2().int().nonnegative(),
8773
+ serializedBytes: number2().int().nonnegative(),
8774
+ serializedByteLimit: number2().int().positive()
8775
+ })
8776
+ }),
8777
+ image: looseObject({
8778
+ attachmentId: id.optional(),
8779
+ downloadUrl: string2().optional(),
8780
+ mimeType: literal("image/png"),
8781
+ width: number2().int().positive(),
8782
+ height: number2().int().positive(),
8783
+ size: number2().int().nonnegative().optional(),
8784
+ sha256: string2().optional(),
8785
+ data: string2().optional()
8786
+ })
8787
+ }),
8788
+ tldraw_exec: looseObject({
8789
+ executionId: id,
8790
+ artifactId: id,
8791
+ state: _enum(["succeeded", "failed", "unknown", "running"]),
8792
+ start: jsonObject,
8793
+ end: jsonObject.optional(),
8794
+ result: unknown().optional(),
8795
+ error: string2().optional()
8796
+ }),
8797
+ tldraw_exec_get: looseObject({
8798
+ executionId: id,
8799
+ artifactId: id,
8800
+ state: _enum(["succeeded", "failed", "unknown", "running"]),
8801
+ start: jsonObject,
8802
+ end: jsonObject.optional(),
8803
+ result: unknown().optional(),
8804
+ error: string2().optional()
8805
+ }),
8604
8806
  artifact_transition: looseObject({
8605
8807
  artifactId: id,
8606
8808
  status: string2(),
@@ -9407,6 +9609,16 @@ var MCP_TOOL_ANNOTATIONS = {
9407
9609
  curation: additive,
9408
9610
  artifact: additive,
9409
9611
  artifact_get: readOnly,
9612
+ tldraw_import: idempotent,
9613
+ tldraw_get: readOnly,
9614
+ tldraw_workbench: destructive,
9615
+ tldraw_status: readOnly,
9616
+ tldraw_checkpoint: idempotent,
9617
+ tldraw_publish: idempotent,
9618
+ tldraw_script: destructive,
9619
+ tldraw_observe: additive,
9620
+ tldraw_exec: destructiveOpenWorld,
9621
+ tldraw_exec_get: readOnly,
9410
9622
  artifact_transition: additive,
9411
9623
  artifact_delete: destructive,
9412
9624
  secrets: destructive,
@@ -9463,6 +9675,88 @@ function mcpAnnotationsFor(name) {
9463
9675
  return annotations;
9464
9676
  }
9465
9677
 
9678
+ // ../actions/src/tldraw-agent.ts
9679
+ var TLDRAW_EXEC_MAX_OPERATIONS = 100;
9680
+ var shapeId = string2().regex(/^shape:[A-Za-z0-9_-]{1,128}$/).describe("stable tldraw shape id, shape:…");
9681
+ var shapeType = _enum(["geo", "text", "note", "frame", "arrow", "line", "draw", "group"]).describe("built-in tldraw shape type; use code mode for custom or asset-backed shapes");
9682
+ var finite = number2().finite();
9683
+ var jsonRecord = record(string2(), unknown());
9684
+ var create = object({
9685
+ op: literal("create"),
9686
+ id: shapeId,
9687
+ type: shapeType,
9688
+ x: finite,
9689
+ y: finite,
9690
+ parentId: string2().min(1).max(200).optional(),
9691
+ rotation: finite.optional(),
9692
+ opacity: finite.min(0).max(1).optional(),
9693
+ isLocked: boolean2().optional(),
9694
+ props: jsonRecord.optional().describe("shape properties such as w, h, geo, color, or richText"),
9695
+ meta: jsonRecord.optional()
9696
+ }).strict();
9697
+ var update = object({
9698
+ op: literal("update"),
9699
+ id: shapeId,
9700
+ type: shapeType,
9701
+ x: finite.optional(),
9702
+ y: finite.optional(),
9703
+ parentId: string2().min(1).max(200).optional(),
9704
+ rotation: finite.optional(),
9705
+ opacity: finite.min(0).max(1).optional(),
9706
+ isLocked: boolean2().optional(),
9707
+ props: jsonRecord.optional().describe("partial shape properties"),
9708
+ meta: jsonRecord.optional()
9709
+ }).strict();
9710
+ var shapeIds = array(shapeId).min(1).max(TLDRAW_EXEC_MAX_OPERATIONS);
9711
+ var TLDRAW_EXEC_OPERATION_SCHEMA = discriminatedUnion("op", [
9712
+ create,
9713
+ update,
9714
+ object({ op: literal("delete"), ids: shapeIds }).strict(),
9715
+ object({
9716
+ op: literal("align"),
9717
+ ids: shapeIds.min(2),
9718
+ alignment: _enum(["bottom", "center-horizontal", "center-vertical", "left", "right", "top"])
9719
+ }).strict(),
9720
+ object({
9721
+ op: literal("distribute"),
9722
+ ids: shapeIds.min(3),
9723
+ axis: _enum(["horizontal", "vertical"])
9724
+ }).strict(),
9725
+ object({
9726
+ op: literal("group"),
9727
+ ids: shapeIds.min(2),
9728
+ groupId: shapeId.optional()
9729
+ }).strict()
9730
+ ]);
9731
+ var TLDRAW_EXEC_OPERATIONS_SCHEMA = array(TLDRAW_EXEC_OPERATION_SCHEMA).min(1).max(TLDRAW_EXEC_MAX_OPERATIONS).superRefine((operations, ctx) => {
9732
+ const createdIds = new Set;
9733
+ operations.forEach((operation, index) => {
9734
+ if (operation.op === "create") {
9735
+ if (createdIds.has(operation.id)) {
9736
+ ctx.addIssue({
9737
+ code: "custom",
9738
+ message: `duplicate create id: ${operation.id}`,
9739
+ path: [index, "id"]
9740
+ });
9741
+ }
9742
+ createdIds.add(operation.id);
9743
+ }
9744
+ if ("ids" in operation) {
9745
+ const seen = new Set;
9746
+ operation.ids.forEach((id, idIndex) => {
9747
+ if (seen.has(id)) {
9748
+ ctx.addIssue({
9749
+ code: "custom",
9750
+ message: `duplicate shape id: ${id}`,
9751
+ path: [index, "ids", idIndex]
9752
+ });
9753
+ }
9754
+ seen.add(id);
9755
+ });
9756
+ }
9757
+ });
9758
+ }).describe("preferred declarative edits, applied in order; mutually exclusive with code — read skill://arbor/references/tldraw.md before first use");
9759
+
9466
9760
  // ../actions/src/skill.ts
9467
9761
  var ARBOR_SKILL_NAME = "arbor";
9468
9762
  var ARBOR_SKILL_DESCRIPTION = "Work in Arbor (arborthreads.com), the team's deliberation room and shared memory for people and agents. " + "Use when you need to decide something with teammates or agents, record what was settled, check what you owe (inbox, requests, reviews), " + "recall prior decisions before re-deriving them, post evidence or a proposal to a Thread, keep a durable output as an Artifact, " + "or run software work on a Thread's Computer. Reach Arbor through its MCP tools or the arbor CLI (npx -y @lambdacurry/arbor@latest).";
@@ -9508,6 +9802,12 @@ Artifacts Arbor keeps current. Use it to decide things with others and to rememb
9508
9802
  ## How to work well in Arbor
9509
9803
 
9510
9804
  ${orientation}
9805
+
9806
+ ## Native tldraw
9807
+
9808
+ Before creating or modifying a native tldraw Artifact, read the bundled
9809
+ references/tldraw.md. Over MCP it is skill://arbor/references/tldraw.md; when only the CLI or web is
9810
+ available, read ${base}/skill/tldraw.md.
9511
9811
  `;
9512
9812
  }
9513
9813
  // ../actions/src/index.ts
@@ -11623,6 +11923,146 @@ var ACTION_DEFINITIONS = [
11623
11923
  toolset: "artifacts",
11624
11924
  run: forward("artifact.transition")
11625
11925
  },
11926
+ {
11927
+ name: "tldraw_import",
11928
+ title: "Import a tldraw board",
11929
+ description: "Create a durable tldraw Artifact from one uploaded .tldr source after Arbor validates the stored bytes and source thread. Retries with the same idempotencyKey return the original Artifact version.",
11930
+ inputSchema: {
11931
+ sourceAttachmentId: string2().describe("uploaded .tldr Attachment, att_…"),
11932
+ title: string2().min(1).max(200).describe("the board title"),
11933
+ summary: string2().min(1).max(500).describe("one-line description of the board"),
11934
+ sourceThreadId: string2().describe("Thread that owns the source Attachment, thr_…"),
11935
+ idempotencyKey: string2().min(1).max(200).describe("stable key for this import request")
11936
+ },
11937
+ surfaces: ["mcp", "cli"],
11938
+ toolset: "artifacts",
11939
+ run: forward("tldraw.import")
11940
+ },
11941
+ {
11942
+ name: "tldraw_get",
11943
+ title: "Read a tldraw board",
11944
+ description: "Read the current or one historical tldraw board version, its immutable source references, version list, edit access, and document-script state. Historical versions are read-only.",
11945
+ inputSchema: {
11946
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
11947
+ version: number2().int().min(1).optional().describe("optional historical version number")
11948
+ },
11949
+ surfaces: ["mcp", "cli"],
11950
+ toolset: "artifacts",
11951
+ run: forward("tldraw.get")
11952
+ },
11953
+ {
11954
+ name: "tldraw_workbench",
11955
+ title: "Materialize a tldraw workbench",
11956
+ description: "Materialize the current live tldraw board and separate document script in an active same-Thread WRITE Run, writing a manifest that pins the exact ArtifactVersion, live clock/digest, and script source tuple without approving or enabling scripts. Each call creates a fresh workbench directory; idempotencyKey makes only the live checkpoint retry-safe.",
11957
+ inputSchema: {
11958
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
11959
+ runId: string2().describe("active same-Thread WRITE Run, run_…"),
11960
+ idempotencyKey: string2().min(1).max(120).describe("stable key for this workbench materialization")
11961
+ },
11962
+ surfaces: ["computer-mcp", "computer-cli"],
11963
+ toolset: "loop",
11964
+ run: forward("tldraw.workbench")
11965
+ },
11966
+ {
11967
+ name: "tldraw_status",
11968
+ title: "Check tldraw board status",
11969
+ description: "Read the current room status and separately reported script sessions for a tldraw board. Session reports remain per-session observations and are never collapsed into global success.",
11970
+ inputSchema: { artifactId: string2().describe("the tldraw Artifact, art_…") },
11971
+ surfaces: ["mcp", "cli"],
11972
+ toolset: "artifacts",
11973
+ run: forward("tldraw.status")
11974
+ },
11975
+ {
11976
+ name: "tldraw_checkpoint",
11977
+ title: "Checkpoint a tldraw board",
11978
+ description: "Persist a current tldraw room snapshot as the next immutable Artifact version with compare-and-swap clocks. Repeating the same idempotencyKey returns the existing checkpoint receipt.",
11979
+ inputSchema: {
11980
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
11981
+ idempotencyKey: string2().min(1).max(200).describe("stable key for this checkpoint"),
11982
+ reason: _enum(["manual", "autosave", "exec"]).optional().describe("why the room is being checkpointed")
11983
+ },
11984
+ surfaces: ["mcp", "cli"],
11985
+ toolset: "artifacts",
11986
+ run: forward("tldraw.checkpoint")
11987
+ },
11988
+ {
11989
+ name: "tldraw_publish",
11990
+ title: "Publish a tldraw board version",
11991
+ description: "Publish one validated .tldr source into the current board using both the room document clock and Artifact version as compare-and-swap guards. Retries are safe with the same idempotencyKey.",
11992
+ inputSchema: {
11993
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
11994
+ sourceAttachmentId: string2().describe("validated .tldr Attachment, att_…"),
11995
+ expectedDocumentClock: number2().int().min(0).describe("room clock observed before publish"),
11996
+ expectedArtifactVersion: number2().int().min(1).describe("Artifact version observed before publish"),
11997
+ idempotencyKey: string2().min(1).max(200).describe("stable key for this publish")
11998
+ },
11999
+ surfaces: ["mcp", "cli"],
12000
+ toolset: "artifacts",
12001
+ run: forward("tldraw.publish")
12002
+ },
12003
+ {
12004
+ name: "tldraw_script",
12005
+ title: "Manage a tldraw document script",
12006
+ description: "Set, approve, disable, or reload the separate document script for a tldraw board. Approval names the exact displayed source version and digest; scripts never run from historical views.",
12007
+ inputSchema: {
12008
+ verb: _enum(["set", "approve", "disable", "reload"]).describe("the script change"),
12009
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
12010
+ attachmentId: string2().optional().describe("set: uploaded script Attachment, att_…"),
12011
+ expectedRevision: number2().int().min(0).optional().describe("set: script revision observed before the write"),
12012
+ version: number2().int().min(1).optional().describe("approve: exact displayed source version"),
12013
+ digest: string2().regex(/^[a-f0-9]{64}$/).optional().describe("approve: exact displayed source digest")
12014
+ },
12015
+ surfaces: ["mcp", "cli"],
12016
+ toolset: "artifacts",
12017
+ run: dispatch({
12018
+ set: "tldraw.script",
12019
+ approve: "tldraw.script",
12020
+ disable: "tldraw.script",
12021
+ reload: "tldraw.script"
12022
+ }, (verb, input) => ({ ...input, verb }))
12023
+ },
12024
+ {
12025
+ name: "tldraw_observe",
12026
+ title: "Observe a tldraw board",
12027
+ description: "Capture a fresh bounded tldraw scene, lint result, document clock and digest, plus a PNG attachment for visual review. Observe before editing; first-time agents should read skill://arbor/references/tldraw.md (or https://arborthreads.com/skill/tldraw.md).",
12028
+ inputSchema: {
12029
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
12030
+ pageId: string2().min(1).max(200).optional().describe("optional page to observe"),
12031
+ viewportWidth: number2().int().min(320).max(1920).optional(),
12032
+ viewportHeight: number2().int().min(240).max(1080).optional()
12033
+ },
12034
+ surfaces: ["mcp", "cli"],
12035
+ toolset: "artifacts",
12036
+ run: forward("tldraw.observe")
12037
+ },
12038
+ {
12039
+ name: "tldraw_exec",
12040
+ title: "Run a one-shot tldraw program",
12041
+ description: "Modify the current live tldraw board with preferred declarative operations or bounded JavaScript, then return a durable execution receipt. Observe first and read skill://arbor/references/tldraw.md (or https://arborthreads.com/skill/tldraw.md); an unknown result is never replayed automatically.",
12042
+ inputSchema: {
12043
+ artifactId: string2().describe("the tldraw Artifact, art_…"),
12044
+ code: string2().min(1).max(1e5).optional().describe("advanced script source; mutually exclusive with operations"),
12045
+ operations: TLDRAW_EXEC_OPERATIONS_SCHEMA.optional(),
12046
+ idempotencyKey: string2().min(1).max(200).describe("stable key for this execution"),
12047
+ expectedDocumentClock: number2().int().min(0).optional().describe("optional current room clock guard"),
12048
+ boundedSettleMs: number2().int().min(400).max(3000).optional().describe("maximum settle time")
12049
+ },
12050
+ surfaces: ["mcp", "cli"],
12051
+ toolset: "artifacts",
12052
+ run: forward("tldraw.exec")
12053
+ },
12054
+ {
12055
+ name: "tldraw_exec_get",
12056
+ title: "Read a tldraw execution receipt",
12057
+ description: "Read one tldraw execution receipt by execution id. The receipt reports success, failure, running, or unknown without starting another execution.",
12058
+ inputSchema: {
12059
+ executionId: string2().describe("the execution receipt, tex_…"),
12060
+ artifactId: string2().optional().describe("optional board id for a scoped lookup")
12061
+ },
12062
+ surfaces: ["mcp", "cli"],
12063
+ toolset: "artifacts",
12064
+ run: forward("tldraw.exec_get")
12065
+ },
11626
12066
  {
11627
12067
  name: "artifact_delete",
11628
12068
  title: "Permanently delete an Artifact",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.22.6",
3
+ "version": "0.22.8",
4
4
  "description": "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
5
5
  "keywords": [
6
6
  "agents",