@lambdacurry/arbor 0.21.3 → 0.21.5

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 +129 -4
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -2247,6 +2247,7 @@ var attachments = sqliteTable("attachments", {
2247
2247
  r2Key: text("r2_key").notNull(),
2248
2248
  uploadedByProfileId: text("uploaded_by_profile_id").notNull().references(() => profiles.id),
2249
2249
  computerSessionId: text("computer_session_id").references(() => computerSessions.id),
2250
+ computerPath: text("computer_path"),
2250
2251
  idempotencyKey: text("idempotency_key"),
2251
2252
  idempotencyFingerprint: text("idempotency_fingerprint"),
2252
2253
  sha256: text("sha256"),
@@ -2307,6 +2308,17 @@ var artifactLivePreviewSurfaces = sqliteTable("artifact_live_preview_surfaces",
2307
2308
  }, (t) => ({
2308
2309
  threadUq: uniqueIndex("artifact_live_preview_surfaces_thread_uniq").on(t.threadId)
2309
2310
  }));
2311
+ var artifactFileSnapshots = sqliteTable("artifact_file_snapshots", {
2312
+ artifactId: text("artifact_id").primaryKey().references(() => artifacts.id, { onDelete: "cascade" }),
2313
+ sourceAttachmentId: text("source_attachment_id").notNull().references(() => attachments.id),
2314
+ previewAttachmentId: text("preview_attachment_id").notNull().references(() => attachments.id),
2315
+ capturedByProfileId: text("captured_by_profile_id").notNull().references(() => profiles.id),
2316
+ executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
2317
+ capturedAt: ts("captured_at").notNull()
2318
+ }, (t) => ({
2319
+ sourceIdx: index("artifact_file_snapshots_source_attachment_idx").on(t.sourceAttachmentId),
2320
+ previewIdx: index("artifact_file_snapshots_preview_attachment_idx").on(t.previewAttachmentId)
2321
+ }));
2310
2322
  var artifactVersions = sqliteTable("artifact_versions", {
2311
2323
  id: text("id").primaryKey(),
2312
2324
  artifactId: text("artifact_id").notNull().references(() => artifacts.id),
@@ -2404,6 +2416,31 @@ var appBundles = sqliteTable("app_bundles", {
2404
2416
  spaceIdx: index("app_bundles_space_idx").on(t.spaceId, t.createdAt),
2405
2417
  idempotencyUq: uniqueIndex("app_bundles_idempotency_uq").on(t.computerSessionId, t.createdByProfileId, t.idempotencyKey)
2406
2418
  }));
2419
+ var previewApps = sqliteTable("preview_apps", {
2420
+ id: text("id").primaryKey(),
2421
+ threadId: text("thread_id").notNull().references(() => threads.id),
2422
+ spaceId: text("space_id").notNull().references(() => spaces.id),
2423
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id),
2424
+ artifactVersionId: text("artifact_version_id").notNull().references(() => artifactVersions.id),
2425
+ bundleId: text("bundle_id").references(() => appBundles.id),
2426
+ hostLabel: text("host_label").notNull(),
2427
+ lifecycle: text("lifecycle").$type().notNull().default("active"),
2428
+ roomsEnabled: integer("rooms_enabled", { mode: "boolean" }).notNull().default(false),
2429
+ expiresAt: ts("expires_at").notNull(),
2430
+ createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
2431
+ createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
2432
+ idempotencyKey: text("idempotency_key").notNull(),
2433
+ idempotencyFingerprint: text("idempotency_fingerprint").notNull(),
2434
+ createdAt: ts("created_at").notNull(),
2435
+ retiredAt: ts("retired_at"),
2436
+ retireReason: text("retire_reason").$type()
2437
+ }, (t) => ({
2438
+ hostUq: uniqueIndex("preview_apps_host_uq").on(t.hostLabel),
2439
+ creatorIdempotencyUq: uniqueIndex("preview_apps_creator_idempotency_uq").on(t.createdByProfileId, t.idempotencyKey),
2440
+ threadIdx: index("preview_apps_thread_idx").on(t.threadId, t.lifecycle, t.createdAt),
2441
+ artifactIdx: index("preview_apps_artifact_idx").on(t.artifactId, t.lifecycle, t.createdAt),
2442
+ expiryIdx: index("preview_apps_expiry_idx").on(t.lifecycle, t.expiresAt)
2443
+ }));
2407
2444
  var apps = sqliteTable("apps", {
2408
2445
  id: text("id").primaryKey(),
2409
2446
  orgId: text("org_id").notNull().references(() => orgs.id),
@@ -2786,6 +2823,9 @@ var PREVIEW_MIME_TYPES = new Set([
2786
2823
  "font/woff",
2787
2824
  "font/woff2"
2788
2825
  ]);
2826
+ // ../core/src/ops/preview-app.ts
2827
+ var PREVIEW_APP_DEFAULT_TTL_SECONDS = 60 * 60;
2828
+ var PREVIEW_APP_MAX_TTL_SECONDS = 24 * 60 * 60;
2789
2829
  // ../core/src/ops/app.ts
2790
2830
  var APP_MAX_MODULE_BYTES = 10 * 1024 * 1024;
2791
2831
  var APP_MAX_ASSET_BYTES = 25 * 1024 * 1024;
@@ -18014,6 +18054,8 @@ var MCP_OUTPUT_SCHEMAS = {
18014
18054
  appBundles: exports_external.array(jsonObject).optional(),
18015
18055
  usedByApps: exports_external.array(jsonObject).optional(),
18016
18056
  livePreview: artifactLivePreview.nullable().optional(),
18057
+ snapshot: jsonObject.nullable().optional(),
18058
+ sourceLivePreview: jsonObject.nullable().optional(),
18017
18059
  threadId: id.nullable().optional(),
18018
18060
  changed: exports_external.boolean().optional()
18019
18061
  }),
@@ -18028,6 +18070,8 @@ var MCP_OUTPUT_SCHEMAS = {
18028
18070
  appBundles: exports_external.array(jsonObject),
18029
18071
  usedByApps: exports_external.array(jsonObject),
18030
18072
  livePreview: artifactLivePreview.nullable(),
18073
+ snapshot: jsonObject.nullable().optional(),
18074
+ sourceLivePreview: jsonObject.nullable().optional(),
18031
18075
  watching: exports_external.boolean(),
18032
18076
  url: exports_external.string()
18033
18077
  }),
@@ -18065,6 +18109,35 @@ var MCP_OUTPUT_SCHEMAS = {
18065
18109
  bindingName: exports_external.string().optional(),
18066
18110
  unbound: exports_external.boolean().optional()
18067
18111
  }),
18112
+ preview_app_create: exports_external.looseObject({
18113
+ id,
18114
+ artifactId: id,
18115
+ artifactVersionId: id,
18116
+ bundleId: id.nullable(),
18117
+ hostLabel: exports_external.string(),
18118
+ lifecycle: exports_external.string(),
18119
+ roomsEnabled: exports_external.boolean(),
18120
+ expiresAt: timestamp,
18121
+ url: exports_external.string(),
18122
+ replayed: exports_external.boolean()
18123
+ }),
18124
+ preview_app_get: exports_external.looseObject({
18125
+ id,
18126
+ artifactId: id,
18127
+ artifactVersionId: id,
18128
+ bundleId: id.nullable(),
18129
+ lifecycle: exports_external.string(),
18130
+ roomsEnabled: exports_external.boolean(),
18131
+ expiresAt: timestamp,
18132
+ url: exports_external.string(),
18133
+ effectiveStatus: exports_external.string()
18134
+ }),
18135
+ preview_app_retire: exports_external.looseObject({
18136
+ id,
18137
+ lifecycle: exports_external.string(),
18138
+ url: exports_external.string(),
18139
+ replayed: exports_external.boolean()
18140
+ }),
18068
18141
  app_list: exports_external.object({ result: exports_external.array(app2) }),
18069
18142
  app_get: exports_external.looseObject({
18070
18143
  app: app2,
@@ -18696,6 +18769,9 @@ var MCP_TOOL_ANNOTATIONS = {
18696
18769
  artifact_transition: additive,
18697
18770
  artifact_delete: destructive,
18698
18771
  secrets: destructive,
18772
+ preview_app_get: readOnly,
18773
+ preview_app_create: idempotent,
18774
+ preview_app_retire: destructiveIdempotent,
18699
18775
  app_get: readOnly,
18700
18776
  app_list: readOnly,
18701
18777
  app_deployment_get: readOnly,
@@ -18782,7 +18858,7 @@ ${ARBOR_FEEDBACK_GUIDANCE}
18782
18858
  4. CHECKPOINT COMPLETE PARENT UNITS. computer_checkpoint advances immutable parent lineage after an intermediate complete unit; computer_stop performs the final checkpoint before teardown. An isolated Run Preview is durable review output, not adoption or a checkpoint. The internal provider-handle publication operations are not agent tools.
18783
18859
  5. GIT AND GITHUB ARE ORDINARY COMMANDS AFTER AUTHORIZATION. Clone, fetch, pull, push, and gh run through computer_exec using a connected human's just-in-time ambient GitHub identity. Credentials never enter argv, workspace files, Git config, checkpoints, Events, logs, or receipts. A restored Computer deliberately keeps the checkout age of its snapshot, so fetch/pull before trusting remote state.
18784
18860
  6. VERIFY, PREVIEW, AND EXPORT. computer_verify captures a public URL directly without opening a project runtime. computer_publish_preview preserves immutable static output from either the parent or an active isolated write Run. computer_export moves bounded files into durable Thread Attachments; place returned Markdown exactly where the media belongs and cite the matching attachment ids.
18785
- 7. PACKAGE, DEPLOY, ACTIVATE, AND OPERATE APPS HERE. computer_publish_app_bundle creates the immutable executable bundle from verified parent bytes. Then use app_create, app_config_apply, app_deploy, app_deployment_get, app_activate, app_get, app_fetch/app_request, app_rollback, app_set_access, app_reset_state/app_restore_state, and app_archive as one workflow-closed release surface. First-class Organization/Profile Secrets remain on Arbor's collaboration MCP because they are broader identity-owned resources; App configuration here references existing Secret ids and never accepts or returns secret material.
18861
+ 7. PACKAGE, DEPLOY, ACTIVATE, AND OPERATE APPS HERE. computer_publish_app_bundle creates the immutable executable bundle from verified parent bytes. For short-lived public Artifact experiments use preview_app_create/get/retire; for published Space Apps use app_create, app_config_apply, app_deploy, app_deployment_get, app_activate, app_get, app_fetch/app_request, app_rollback, app_set_access, app_reset_state/app_restore_state, and app_archive as one workflow-closed release surface. First-class Organization/Profile Secrets remain on Arbor's collaboration MCP because they are broader identity-owned resources; App configuration here references existing Secret ids and never accepts or returns secret material.
18786
18862
  8. FINISH WHAT YOU START. Stop the parent after its final complete unit, finish every Run, and preserve evidence before teardown. When reporting collaboration conclusions through Arbor, pass the producing computerSessionId and attachmentIds to contribute or respond.
18787
18863
  9. CLOSE OUT ARBOR DOGFOOD. When developing Arbor through Arbor, ask: “Did Arbor itself create meaningful friction or require an Arbor-specific workaround?” If yes, apply the classifier above and privately capture one bounded report before closing the development loop; keep unrelated product friction out of the implementation Thread. If no, close normally without manufacturing feedback.`;
18788
18864
  var PROSE_LISTS = exports_external.registry();
@@ -19746,6 +19822,19 @@ var ACTION_DEFINITIONS = [
19746
19822
  verb: Array.isArray(input.patches) ? "patch" : "replace"
19747
19823
  })
19748
19824
  },
19825
+ {
19826
+ name: "set_artifact_snapshot",
19827
+ title: "Set an Artifact's stored file snapshot",
19828
+ description: "Pin exact exported source bytes plus a same-Thread PNG preview as a Computer-backed file Artifact's asleep/share face. This does not change its computer:// locator or create runtime.",
19829
+ inputSchema: {
19830
+ artifactId: exports_external.string().describe("the Computer-backed file Artifact, art_…"),
19831
+ sourceAttachmentId: exports_external.string().describe("exported .tldr Attachment, att_…"),
19832
+ previewAttachmentId: exports_external.string().describe("exported PNG Attachment, att_…")
19833
+ },
19834
+ surfaces: ["cli"],
19835
+ toolset: "artifacts",
19836
+ run: forward("artifact.setSnapshot")
19837
+ },
19749
19838
  {
19750
19839
  name: "set_artifact_live_preview",
19751
19840
  title: "Set an Artifact's live Thread surface",
@@ -20573,9 +20662,9 @@ var ACTION_DEFINITIONS = [
20573
20662
  {
20574
20663
  name: "artifact",
20575
20664
  title: "Create or edit an Artifact",
20576
- description: "Create or edit a durable versioned Artifact, bind its executable Thread Live Preview, or promote a Thread attachment; read artifact_get before changing it, while lifecycle/removal stay in artifact_transition and artifact_delete. Live-surface binding changes Artifact identity metadata, not source/version content.",
20665
+ description: "Create or edit a durable versioned Artifact, bind its executable Thread Live Preview, set a Computer-file asleep/share snapshot, or promote a Thread attachment; read artifact_get before changing it, while lifecycle/removal stay in artifact_transition and artifact_delete. Live-surface binding changes Artifact identity metadata, not source/version content.",
20577
20666
  inputSchema: {
20578
- verb: exports_external.enum(["create", "edit", "set_live_preview", "promote_attachment"]).describe("which artifact move"),
20667
+ verb: exports_external.enum(["create", "edit", "set_live_preview", "set_snapshot", "promote_attachment"]).describe("which artifact move"),
20579
20668
  title: exports_external.string().optional().describe("create: the artifact's title"),
20580
20669
  kind: exports_external.enum(["doc", "table", "diagram", "html", "file"]).optional().describe("create: structural kind (default file). doc/table/diagram/html are editable text"),
20581
20670
  type: exports_external.string().optional().describe("create: semantic type, e.g. decision|summary|plan|markdown|table|research-brief"),
@@ -20586,11 +20675,13 @@ var ACTION_DEFINITIONS = [
20586
20675
  sourceThreadId: exports_external.string().optional().describe("create: the thread it came from"),
20587
20676
  computerSessionId: exports_external.string().optional().describe("create: the attached computer session that produced it, cms_…"),
20588
20677
  sourceContributionIds: exports_external.array(exports_external.string()).optional().describe("create: contributions it distills"),
20589
- artifactId: exports_external.string().optional().describe("edit/set_live_preview: the Artifact, art_…"),
20678
+ artifactId: exports_external.string().optional().describe("edit/set_live_preview/set_snapshot: the Artifact, art_…"),
20590
20679
  threadId: exports_external.string().optional().describe("set_live_preview: the configured Thread Live Preview, thr_…; omit to clear the binding"),
20591
20680
  baseVersion: exports_external.number().optional().describe("edit: the version you READ (from get/create) — stale base is rejected with the current source"),
20592
20681
  patches: exports_external.array(exports_external.object({ old: exports_external.string(), new: exports_external.string() })).optional().describe("edit: exact-match hunks applied in order, atomically; each old must match exactly once"),
20593
20682
  note: exports_external.string().optional().describe("edit: one-line summary of what changed"),
20683
+ sourceAttachmentId: exports_external.string().optional().describe("set_snapshot: exported .tldr Attachment, att_…"),
20684
+ previewAttachmentId: exports_external.string().optional().describe("set_snapshot: exported PNG Attachment, att_…"),
20594
20685
  attachmentId: exports_external.string().optional().describe("promote_attachment: the upload, att_…")
20595
20686
  },
20596
20687
  surfaces: ["mcp"],
@@ -20599,6 +20690,7 @@ var ACTION_DEFINITIONS = [
20599
20690
  create: "artifact.create",
20600
20691
  edit: "artifact.edit",
20601
20692
  set_live_preview: "artifact.setLivePreview",
20693
+ set_snapshot: "artifact.setSnapshot",
20602
20694
  promote_attachment: "attachment.promote"
20603
20695
  }, (verb, input) => verb === "edit" ? { ...input, verb: Array.isArray(input.patches) ? "patch" : "replace" } : input)
20604
20696
  },
@@ -20846,6 +20938,39 @@ var ACTION_DEFINITIONS = [
20846
20938
  toolset: "apps",
20847
20939
  run: forward("app.get")
20848
20940
  },
20941
+ {
20942
+ name: "preview_app_create",
20943
+ title: "Create a public Preview App",
20944
+ description: "Mint a short-lived public no-login Preview App from one Artifact's exact current version, optionally executing a same-version fetch AppBundle with bounded Preview-scoped WebSocket rooms. It stays Thread/Artifact scoped, TTL-bounded, and out of the Space App catalog.",
20945
+ inputSchema: {
20946
+ artifactId: exports_external.string().describe("source Artifact, art_…; its current version is pinned"),
20947
+ bundleId: exports_external.string().optional().describe("optional fetch AppBundle, bnd_…, built from that exact current ArtifactVersion"),
20948
+ roomsEnabled: exports_external.boolean().optional().describe("allow named WebSocket rooms backed by preview-scoped SQLite Durable Object facets"),
20949
+ ttlSeconds: exports_external.number().int().min(60).max(86400).optional().describe("Preview lifetime in seconds; default 3600, hard max 86400"),
20950
+ idempotencyKey: exports_external.string().min(1).max(200).describe("stable retry key for this one logical Preview App mint")
20951
+ },
20952
+ surfaces: ["computer-mcp", "cli"],
20953
+ toolset: "apps",
20954
+ run: forward("preview_app.create")
20955
+ },
20956
+ {
20957
+ name: "preview_app_get",
20958
+ title: "Read a Preview App",
20959
+ description: "READ ONLY: Inspect one Preview App's public URL, pinned ArtifactVersion/AppBundle lineage, absolute expiry, Thread status, and bounded WebSocket room contract. It is not a Space App catalog read.",
20960
+ inputSchema: { previewAppId: exports_external.string().describe("the Preview App, papp_…") },
20961
+ surfaces: ["computer-mcp", "cli"],
20962
+ toolset: "apps",
20963
+ run: forward("preview_app.get")
20964
+ },
20965
+ {
20966
+ name: "preview_app_retire",
20967
+ title: "Retire a Preview App",
20968
+ description: "Retire one short-lived Preview App immediately, stopping its public gateway and tearing down bounded room Durable Objects. Artifact/AppBundle history stays intact, and Thread close performs the same retirement automatically.",
20969
+ inputSchema: { previewAppId: exports_external.string().describe("the Preview App, papp_…") },
20970
+ surfaces: ["computer-mcp", "cli"],
20971
+ toolset: "apps",
20972
+ run: forward("preview_app.retire")
20973
+ },
20849
20974
  {
20850
20975
  name: "app_create",
20851
20976
  title: "Create an App",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.21.3",
3
+ "version": "0.21.5",
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",