@lambdacurry/arbor 0.21.2 → 0.21.4

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 +146 -7
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -2297,6 +2297,16 @@ var artifacts = sqliteTable("artifacts", {
2297
2297
  tierIdx: index("artifacts_tier_idx").on(t.retrievalTier),
2298
2298
  ownerIdx: index("artifacts_owner_idx").on(t.ownerProfileId)
2299
2299
  }));
2300
+ var artifactLivePreviewSurfaces = sqliteTable("artifact_live_preview_surfaces", {
2301
+ artifactId: text("artifact_id").primaryKey().references(() => artifacts.id),
2302
+ threadId: text("thread_id").notNull().references(() => threads.id),
2303
+ boundByProfileId: text("bound_by_profile_id").notNull().references(() => profiles.id),
2304
+ executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
2305
+ revision: integer("revision").notNull().default(1),
2306
+ boundAt: ts("bound_at").notNull()
2307
+ }, (t) => ({
2308
+ threadUq: uniqueIndex("artifact_live_preview_surfaces_thread_uniq").on(t.threadId)
2309
+ }));
2300
2310
  var artifactVersions = sqliteTable("artifact_versions", {
2301
2311
  id: text("id").primaryKey(),
2302
2312
  artifactId: text("artifact_id").notNull().references(() => artifacts.id),
@@ -2394,6 +2404,31 @@ var appBundles = sqliteTable("app_bundles", {
2394
2404
  spaceIdx: index("app_bundles_space_idx").on(t.spaceId, t.createdAt),
2395
2405
  idempotencyUq: uniqueIndex("app_bundles_idempotency_uq").on(t.computerSessionId, t.createdByProfileId, t.idempotencyKey)
2396
2406
  }));
2407
+ var previewApps = sqliteTable("preview_apps", {
2408
+ id: text("id").primaryKey(),
2409
+ threadId: text("thread_id").notNull().references(() => threads.id),
2410
+ spaceId: text("space_id").notNull().references(() => spaces.id),
2411
+ artifactId: text("artifact_id").notNull().references(() => artifacts.id),
2412
+ artifactVersionId: text("artifact_version_id").notNull().references(() => artifactVersions.id),
2413
+ bundleId: text("bundle_id").references(() => appBundles.id),
2414
+ hostLabel: text("host_label").notNull(),
2415
+ lifecycle: text("lifecycle").$type().notNull().default("active"),
2416
+ roomsEnabled: integer("rooms_enabled", { mode: "boolean" }).notNull().default(false),
2417
+ expiresAt: ts("expires_at").notNull(),
2418
+ createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
2419
+ createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
2420
+ idempotencyKey: text("idempotency_key").notNull(),
2421
+ idempotencyFingerprint: text("idempotency_fingerprint").notNull(),
2422
+ createdAt: ts("created_at").notNull(),
2423
+ retiredAt: ts("retired_at"),
2424
+ retireReason: text("retire_reason").$type()
2425
+ }, (t) => ({
2426
+ hostUq: uniqueIndex("preview_apps_host_uq").on(t.hostLabel),
2427
+ creatorIdempotencyUq: uniqueIndex("preview_apps_creator_idempotency_uq").on(t.createdByProfileId, t.idempotencyKey),
2428
+ threadIdx: index("preview_apps_thread_idx").on(t.threadId, t.lifecycle, t.createdAt),
2429
+ artifactIdx: index("preview_apps_artifact_idx").on(t.artifactId, t.lifecycle, t.createdAt),
2430
+ expiryIdx: index("preview_apps_expiry_idx").on(t.lifecycle, t.expiresAt)
2431
+ }));
2397
2432
  var apps = sqliteTable("apps", {
2398
2433
  id: text("id").primaryKey(),
2399
2434
  orgId: text("org_id").notNull().references(() => orgs.id),
@@ -2776,6 +2811,9 @@ var PREVIEW_MIME_TYPES = new Set([
2776
2811
  "font/woff",
2777
2812
  "font/woff2"
2778
2813
  ]);
2814
+ // ../core/src/ops/preview-app.ts
2815
+ var PREVIEW_APP_DEFAULT_TTL_SECONDS = 60 * 60;
2816
+ var PREVIEW_APP_MAX_TTL_SECONDS = 24 * 60 * 60;
2779
2817
  // ../core/src/ops/app.ts
2780
2818
  var APP_MAX_MODULE_BYTES = 10 * 1024 * 1024;
2781
2819
  var APP_MAX_ASSET_BYTES = 25 * 1024 * 1024;
@@ -17163,6 +17201,24 @@ var recallHit = exports_external.looseObject({
17163
17201
  url: nullableString,
17164
17202
  createdAt: timestamp
17165
17203
  });
17204
+ var artifactLivePreviewThread = exports_external.looseObject({
17205
+ id,
17206
+ title: exports_external.string()
17207
+ });
17208
+ var artifactLivePreview = exports_external.discriminatedUnion("status", [
17209
+ exports_external.looseObject({
17210
+ thread: artifactLivePreviewThread,
17211
+ boundAt: timestamp,
17212
+ status: exports_external.literal("configured"),
17213
+ url: exports_external.string()
17214
+ }),
17215
+ exports_external.looseObject({
17216
+ thread: artifactLivePreviewThread,
17217
+ boundAt: timestamp,
17218
+ status: exports_external.literal("unavailable"),
17219
+ url: exports_external.never().optional()
17220
+ })
17221
+ ]);
17166
17222
  var contributionRef = exports_external.looseObject({
17167
17223
  id,
17168
17224
  objectType: exports_external.string(),
@@ -17984,7 +18040,10 @@ var MCP_OUTPUT_SCHEMAS = {
17984
18040
  url: exports_external.string().optional(),
17985
18041
  versions: exports_external.array(jsonObject).optional(),
17986
18042
  appBundles: exports_external.array(jsonObject).optional(),
17987
- usedByApps: exports_external.array(jsonObject).optional()
18043
+ usedByApps: exports_external.array(jsonObject).optional(),
18044
+ livePreview: artifactLivePreview.nullable().optional(),
18045
+ threadId: id.nullable().optional(),
18046
+ changed: exports_external.boolean().optional()
17988
18047
  }),
17989
18048
  artifact_get: exports_external.looseObject({
17990
18049
  id,
@@ -17996,6 +18055,7 @@ var MCP_OUTPUT_SCHEMAS = {
17996
18055
  versions: exports_external.array(jsonObject).optional(),
17997
18056
  appBundles: exports_external.array(jsonObject),
17998
18057
  usedByApps: exports_external.array(jsonObject),
18058
+ livePreview: artifactLivePreview.nullable(),
17999
18059
  watching: exports_external.boolean(),
18000
18060
  url: exports_external.string()
18001
18061
  }),
@@ -18033,6 +18093,35 @@ var MCP_OUTPUT_SCHEMAS = {
18033
18093
  bindingName: exports_external.string().optional(),
18034
18094
  unbound: exports_external.boolean().optional()
18035
18095
  }),
18096
+ preview_app_create: exports_external.looseObject({
18097
+ id,
18098
+ artifactId: id,
18099
+ artifactVersionId: id,
18100
+ bundleId: id.nullable(),
18101
+ hostLabel: exports_external.string(),
18102
+ lifecycle: exports_external.string(),
18103
+ roomsEnabled: exports_external.boolean(),
18104
+ expiresAt: timestamp,
18105
+ url: exports_external.string(),
18106
+ replayed: exports_external.boolean()
18107
+ }),
18108
+ preview_app_get: exports_external.looseObject({
18109
+ id,
18110
+ artifactId: id,
18111
+ artifactVersionId: id,
18112
+ bundleId: id.nullable(),
18113
+ lifecycle: exports_external.string(),
18114
+ roomsEnabled: exports_external.boolean(),
18115
+ expiresAt: timestamp,
18116
+ url: exports_external.string(),
18117
+ effectiveStatus: exports_external.string()
18118
+ }),
18119
+ preview_app_retire: exports_external.looseObject({
18120
+ id,
18121
+ lifecycle: exports_external.string(),
18122
+ url: exports_external.string(),
18123
+ replayed: exports_external.boolean()
18124
+ }),
18036
18125
  app_list: exports_external.object({ result: exports_external.array(app2) }),
18037
18126
  app_get: exports_external.looseObject({
18038
18127
  app: app2,
@@ -18664,6 +18753,9 @@ var MCP_TOOL_ANNOTATIONS = {
18664
18753
  artifact_transition: additive,
18665
18754
  artifact_delete: destructive,
18666
18755
  secrets: destructive,
18756
+ preview_app_get: readOnly,
18757
+ preview_app_create: idempotent,
18758
+ preview_app_retire: destructiveIdempotent,
18667
18759
  app_get: readOnly,
18668
18760
  app_list: readOnly,
18669
18761
  app_deployment_get: readOnly,
@@ -18750,7 +18842,7 @@ ${ARBOR_FEEDBACK_GUIDANCE}
18750
18842
  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.
18751
18843
  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.
18752
18844
  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.
18753
- 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.
18845
+ 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.
18754
18846
  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.
18755
18847
  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.`;
18756
18848
  var PROSE_LISTS = exports_external.registry();
@@ -19687,7 +19779,7 @@ var ACTION_DEFINITIONS = [
19687
19779
  {
19688
19780
  name: "get_artifact",
19689
19781
  title: "Read an artifact",
19690
- description: "Read an artifact: current source + version + immutable versions[].id (artv_…), plus who edited and via what. READ BEFORE YOU EDIT — the version number you read is the baseVersion your edit must name. Use the matching versions[].id as artifactVersionId when publishing an AppBundle. Pass --version to read an old snapshot.",
19782
+ description: "Read an Artifact's current source/version/history plus its current executable Live Preview surface when bound. READ BEFORE YOU EDIT — the version number you read is the baseVersion your edit must name. Surface binding is current Artifact identity metadata and remains current even when --version reads old content.",
19691
19783
  inputSchema: {
19692
19784
  artifactId: exports_external.string().describe("the artifact, art_…"),
19693
19785
  version: exports_external.number().optional().describe("read this old snapshot instead of the current")
@@ -19714,6 +19806,18 @@ var ACTION_DEFINITIONS = [
19714
19806
  verb: Array.isArray(input.patches) ? "patch" : "replace"
19715
19807
  })
19716
19808
  },
19809
+ {
19810
+ name: "set_artifact_live_preview",
19811
+ title: "Set an Artifact's live Thread surface",
19812
+ description: "Bind one Artifact to an existing same-Space Thread Live Preview, making the Artifact the durable entry point for that executable surface. Omit --thread-id to clear the binding; this changes no Artifact source/version and does not create or reconfigure a Computer.",
19813
+ inputSchema: {
19814
+ artifactId: exports_external.string().describe("the Artifact, art_…"),
19815
+ threadId: exports_external.string().optional().describe("the configured Thread Live Preview to bind, thr_…; omit to clear")
19816
+ },
19817
+ surfaces: ["cli"],
19818
+ toolset: "artifacts",
19819
+ run: forward("artifact.setLivePreview")
19820
+ },
19717
19821
  {
19718
19822
  name: "transition_artifact",
19719
19823
  title: "Transition an artifact's lifecycle",
@@ -20529,9 +20633,9 @@ var ACTION_DEFINITIONS = [
20529
20633
  {
20530
20634
  name: "artifact",
20531
20635
  title: "Create or edit an Artifact",
20532
- description: "Create or edit a durable versioned Artifact, or promote a Thread attachment; read artifact_get and its baseVersion before editing, while lifecycle/removal stay in artifact_transition and artifact_delete. Text edits replace source or apply exact-match patches atomically, file artifacts use contentRef, and computer-produced artifacts may cite computerSessionId.",
20636
+ 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.",
20533
20637
  inputSchema: {
20534
- verb: exports_external.enum(["create", "edit", "promote_attachment"]).describe("which artifact move"),
20638
+ verb: exports_external.enum(["create", "edit", "set_live_preview", "promote_attachment"]).describe("which artifact move"),
20535
20639
  title: exports_external.string().optional().describe("create: the artifact's title"),
20536
20640
  kind: exports_external.enum(["doc", "table", "diagram", "html", "file"]).optional().describe("create: structural kind (default file). doc/table/diagram/html are editable text"),
20537
20641
  type: exports_external.string().optional().describe("create: semantic type, e.g. decision|summary|plan|markdown|table|research-brief"),
@@ -20542,7 +20646,8 @@ var ACTION_DEFINITIONS = [
20542
20646
  sourceThreadId: exports_external.string().optional().describe("create: the thread it came from"),
20543
20647
  computerSessionId: exports_external.string().optional().describe("create: the attached computer session that produced it, cms_…"),
20544
20648
  sourceContributionIds: exports_external.array(exports_external.string()).optional().describe("create: contributions it distills"),
20545
- artifactId: exports_external.string().optional().describe("edit: the Artifact, art_…"),
20649
+ artifactId: exports_external.string().optional().describe("edit/set_live_preview: the Artifact, art_…"),
20650
+ threadId: exports_external.string().optional().describe("set_live_preview: the configured Thread Live Preview, thr_…; omit to clear the binding"),
20546
20651
  baseVersion: exports_external.number().optional().describe("edit: the version you READ (from get/create) — stale base is rejected with the current source"),
20547
20652
  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"),
20548
20653
  note: exports_external.string().optional().describe("edit: one-line summary of what changed"),
@@ -20553,13 +20658,14 @@ var ACTION_DEFINITIONS = [
20553
20658
  run: dispatch({
20554
20659
  create: "artifact.create",
20555
20660
  edit: "artifact.edit",
20661
+ set_live_preview: "artifact.setLivePreview",
20556
20662
  promote_attachment: "attachment.promote"
20557
20663
  }, (verb, input) => verb === "edit" ? { ...input, verb: Array.isArray(input.patches) ? "patch" : "replace" } : input)
20558
20664
  },
20559
20665
  {
20560
20666
  name: "artifact_get",
20561
20667
  title: "Read an Artifact",
20562
- description: "Read an Artifact's current source, version, immutable history, and AppBundle references, or pass version for an older snapshot. It cannot edit content, change lifecycle, promote an attachment, or delete an Artifact.",
20668
+ description: "Read an Artifact's current source, version, immutable history, AppBundle references, and current executable Live Preview surface, or pass version for an older content snapshot. It cannot edit content, bind a surface, change lifecycle, promote an attachment, or delete an Artifact.",
20563
20669
  inputSchema: {
20564
20670
  artifactId: exports_external.string().describe("the Artifact, art_…"),
20565
20671
  version: exports_external.number().optional().describe("read this old snapshot instead of the current")
@@ -20800,6 +20906,39 @@ var ACTION_DEFINITIONS = [
20800
20906
  toolset: "apps",
20801
20907
  run: forward("app.get")
20802
20908
  },
20909
+ {
20910
+ name: "preview_app_create",
20911
+ title: "Create a public Preview App",
20912
+ 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.",
20913
+ inputSchema: {
20914
+ artifactId: exports_external.string().describe("source Artifact, art_…; its current version is pinned"),
20915
+ bundleId: exports_external.string().optional().describe("optional fetch AppBundle, bnd_…, built from that exact current ArtifactVersion"),
20916
+ roomsEnabled: exports_external.boolean().optional().describe("allow named WebSocket rooms backed by preview-scoped SQLite Durable Object facets"),
20917
+ ttlSeconds: exports_external.number().int().min(60).max(86400).optional().describe("Preview lifetime in seconds; default 3600, hard max 86400"),
20918
+ idempotencyKey: exports_external.string().min(1).max(200).describe("stable retry key for this one logical Preview App mint")
20919
+ },
20920
+ surfaces: ["computer-mcp", "cli"],
20921
+ toolset: "apps",
20922
+ run: forward("preview_app.create")
20923
+ },
20924
+ {
20925
+ name: "preview_app_get",
20926
+ title: "Read a Preview App",
20927
+ 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.",
20928
+ inputSchema: { previewAppId: exports_external.string().describe("the Preview App, papp_…") },
20929
+ surfaces: ["computer-mcp", "cli"],
20930
+ toolset: "apps",
20931
+ run: forward("preview_app.get")
20932
+ },
20933
+ {
20934
+ name: "preview_app_retire",
20935
+ title: "Retire a Preview App",
20936
+ 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.",
20937
+ inputSchema: { previewAppId: exports_external.string().describe("the Preview App, papp_…") },
20938
+ surfaces: ["computer-mcp", "cli"],
20939
+ toolset: "apps",
20940
+ run: forward("preview_app.retire")
20941
+ },
20803
20942
  {
20804
20943
  name: "app_create",
20805
20944
  title: "Create an App",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.21.2",
3
+ "version": "0.21.4",
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",