@lambdacurry/arbor 0.12.3 → 0.12.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.
- package/dist/arbor.js +62 -9
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -1572,6 +1572,8 @@ var previewVersions = sqliteTable("preview_versions", {
|
|
|
1572
1572
|
computerSessionId: text("computer_session_id").notNull().references(() => computerSessions.id),
|
|
1573
1573
|
snapshotId: text("snapshot_id").notNull().references(() => computerSnapshots.id),
|
|
1574
1574
|
publishedByProfileId: text("published_by_profile_id").notNull().references(() => profiles.id),
|
|
1575
|
+
idempotencyKey: text("idempotency_key"),
|
|
1576
|
+
idempotencyFingerprint: text("idempotency_fingerprint"),
|
|
1575
1577
|
publishedExecutionContextId: text("published_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1576
1578
|
failureCode: text("failure_code"),
|
|
1577
1579
|
createdAt: ts("created_at").notNull(),
|
|
@@ -1580,8 +1582,18 @@ var previewVersions = sqliteTable("preview_versions", {
|
|
|
1580
1582
|
previewVersionIdx: uniqueIndex("preview_versions_preview_version_idx").on(t.previewId, t.version),
|
|
1581
1583
|
hostIdx: uniqueIndex("preview_versions_host_idx").on(t.hostLabel),
|
|
1582
1584
|
sessionIdx: index("preview_versions_session_idx").on(t.computerSessionId, t.createdAt),
|
|
1585
|
+
idempotencyIdx: uniqueIndex("preview_versions_idempotency_idx").on(t.computerSessionId, t.publishedByProfileId, t.idempotencyKey),
|
|
1583
1586
|
snapshotIdx: index("preview_versions_snapshot_idx").on(t.snapshotId)
|
|
1584
1587
|
}));
|
|
1588
|
+
var previewVersionFiles = sqliteTable("preview_version_files", {
|
|
1589
|
+
versionId: text("version_id").notNull().references(() => previewVersions.id),
|
|
1590
|
+
path: text("path").notNull(),
|
|
1591
|
+
size: integer("size").notNull(),
|
|
1592
|
+
mimeType: text("mime_type").notNull(),
|
|
1593
|
+
sha256: text("sha256").notNull()
|
|
1594
|
+
}, (t) => ({
|
|
1595
|
+
pk: primaryKey({ columns: [t.versionId, t.path] })
|
|
1596
|
+
}));
|
|
1585
1597
|
var previewVersionFinalizations = sqliteTable("preview_version_finalizations", {
|
|
1586
1598
|
versionId: text("version_id").primaryKey().references(() => previewVersions.id),
|
|
1587
1599
|
finalizedAt: ts("finalized_at").notNull()
|
|
@@ -1646,15 +1658,21 @@ var reviews = sqliteTable("reviews", {
|
|
|
1646
1658
|
var attachments = sqliteTable("attachments", {
|
|
1647
1659
|
id: text("id").primaryKey(),
|
|
1648
1660
|
filename: text("filename").notNull(),
|
|
1661
|
+
description: text("description").notNull().default(""),
|
|
1649
1662
|
mimeType: text("mime_type").notNull(),
|
|
1650
1663
|
size: integer("size").notNull(),
|
|
1651
1664
|
r2Key: text("r2_key").notNull(),
|
|
1652
1665
|
uploadedByProfileId: text("uploaded_by_profile_id").notNull().references(() => profiles.id),
|
|
1666
|
+
computerSessionId: text("computer_session_id").references(() => computerSessions.id),
|
|
1667
|
+
idempotencyKey: text("idempotency_key"),
|
|
1668
|
+
idempotencyFingerprint: text("idempotency_fingerprint"),
|
|
1669
|
+
sha256: text("sha256"),
|
|
1653
1670
|
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1654
1671
|
createdAt: ts("created_at").notNull()
|
|
1655
1672
|
}, (t) => ({
|
|
1656
1673
|
threadIdx: index("attachments_thread_idx").on(t.threadId),
|
|
1657
1674
|
uploaderIdx: index("attachments_uploader_idx").on(t.uploadedByProfileId),
|
|
1675
|
+
computerExportIdempotencyIdx: uniqueIndex("attachments_computer_export_idempotency_idx").on(t.computerSessionId, t.uploadedByProfileId, t.idempotencyKey),
|
|
1658
1676
|
r2KeyIdx: uniqueIndex("attachments_r2_key_uniq").on(t.r2Key)
|
|
1659
1677
|
}));
|
|
1660
1678
|
var reactions = sqliteTable("reactions", {
|
|
@@ -1781,6 +1799,11 @@ var notificationCursors = sqliteTable("notification_cursors", {
|
|
|
1781
1799
|
profileId: text("profile_id").primaryKey().references(() => profiles.id),
|
|
1782
1800
|
lastSeenAt: ts("last_seen_at").notNull()
|
|
1783
1801
|
});
|
|
1802
|
+
var recallIndex = sqliteTable("recall_index", {
|
|
1803
|
+
objectId: text("object_id").primaryKey(),
|
|
1804
|
+
indexedAt: ts("indexed_at").notNull(),
|
|
1805
|
+
chunks: integer("chunks")
|
|
1806
|
+
});
|
|
1784
1807
|
var watches = sqliteTable("watches", {
|
|
1785
1808
|
id: text("id").primaryKey(),
|
|
1786
1809
|
watcherProfileId: text("watcher_profile_id").notNull().references(() => profiles.id),
|
|
@@ -1832,6 +1855,28 @@ class InMemoryBlobStore {
|
|
|
1832
1855
|
async put(key, bytes, mimeType) {
|
|
1833
1856
|
this.store.set(key, { bytes: new Uint8Array(bytes), mimeType });
|
|
1834
1857
|
}
|
|
1858
|
+
async putStream(key, stream, size, mimeType) {
|
|
1859
|
+
const reader = stream.getReader();
|
|
1860
|
+
const bytes = new Uint8Array(size);
|
|
1861
|
+
let offset = 0;
|
|
1862
|
+
try {
|
|
1863
|
+
while (true) {
|
|
1864
|
+
const { done, value } = await reader.read();
|
|
1865
|
+
if (done)
|
|
1866
|
+
break;
|
|
1867
|
+
if (offset + value.byteLength > size) {
|
|
1868
|
+
throw new Error(`Blob stream exceeded its declared ${size} bytes`);
|
|
1869
|
+
}
|
|
1870
|
+
bytes.set(value, offset);
|
|
1871
|
+
offset += value.byteLength;
|
|
1872
|
+
}
|
|
1873
|
+
} finally {
|
|
1874
|
+
reader.releaseLock();
|
|
1875
|
+
}
|
|
1876
|
+
if (offset !== size)
|
|
1877
|
+
throw new Error(`Blob stream ended at ${offset} of ${size} bytes`);
|
|
1878
|
+
this.store.set(key, { bytes, mimeType });
|
|
1879
|
+
}
|
|
1835
1880
|
async get(key, range) {
|
|
1836
1881
|
const blob2 = this.store.get(key);
|
|
1837
1882
|
if (!blob2)
|
|
@@ -1884,6 +1929,8 @@ class InMemoryVectorStore {
|
|
|
1884
1929
|
async query(vector, q) {
|
|
1885
1930
|
const scored = [];
|
|
1886
1931
|
for (const r of this.records.values()) {
|
|
1932
|
+
if ((r.namespace ?? null) !== (q.namespace ?? null))
|
|
1933
|
+
continue;
|
|
1887
1934
|
if (!matchesFilter(r.metadata, q.filter))
|
|
1888
1935
|
continue;
|
|
1889
1936
|
scored.push({ id: r.id, score: cosine(vector, r.vector), metadata: r.metadata });
|
|
@@ -1906,6 +1953,7 @@ class InMemoryVectorStore {
|
|
|
1906
1953
|
var recallFts = sqliteTable("recall_fts", {
|
|
1907
1954
|
id: text("id"),
|
|
1908
1955
|
body: text("body"),
|
|
1956
|
+
org: text("org"),
|
|
1909
1957
|
space: text("space"),
|
|
1910
1958
|
topic: text("topic"),
|
|
1911
1959
|
thread: text("thread")
|
|
@@ -1920,8 +1968,10 @@ var INDEX_ON = new Set([
|
|
|
1920
1968
|
"review.added",
|
|
1921
1969
|
"thread.created",
|
|
1922
1970
|
"topic.created",
|
|
1923
|
-
"topic.edited"
|
|
1971
|
+
"topic.edited",
|
|
1972
|
+
"contribution.restored"
|
|
1924
1973
|
]);
|
|
1974
|
+
var PURGE_ON = new Set(["contribution.deleted"]);
|
|
1925
1975
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
1926
1976
|
var exports_external = {};
|
|
1927
1977
|
__export(exports_external, {
|
|
@@ -16555,10 +16605,12 @@ var ACTIONS = [
|
|
|
16555
16605
|
{
|
|
16556
16606
|
name: "computer_export",
|
|
16557
16607
|
title: "Export a Thread file",
|
|
16558
|
-
description: "Move one bounded image, MP4/WebM video, or supported file from an opened computer into a durable Thread Attachment.
|
|
16608
|
+
description: "Move one bounded image, MP4/WebM video, or supported file from an opened computer into a durable Thread Attachment. Describe what it shows so the returned attachments[].markdown has meaningful image alt text or a video/file label; put that Markdown where the media belongs and bind those ids when contributing or responding. Supply one stable idempotencyKey per logical export: safe retries return the original Attachment, while reusing the key for another path or description conflicts.",
|
|
16559
16609
|
inputSchema: {
|
|
16560
16610
|
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16561
|
-
path: exports_external.string().describe("absolute path to one supported file under /workspace")
|
|
16611
|
+
path: exports_external.string().describe("absolute path to one supported file under /workspace"),
|
|
16612
|
+
description: exports_external.string().min(1).max(500).describe("concise description of what the file shows or contains; becomes image alt text, a video caption, and the Artifact summary"),
|
|
16613
|
+
idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this ONE logical export (≤200 chars); reuse it only to retry the same path")
|
|
16562
16614
|
},
|
|
16563
16615
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
16564
16616
|
toolset: "loop",
|
|
@@ -16606,11 +16658,12 @@ var ACTIONS = [
|
|
|
16606
16658
|
{
|
|
16607
16659
|
name: "computer_publish_preview",
|
|
16608
16660
|
title: "Publish an immutable static Preview",
|
|
16609
|
-
description: "Publish one checked HTML file or bounded static build directory as a private immutable Preview after checkpointing its source. The returned arborthreads.dev URL survives computer teardown; put it on its own line to show the interactive Preview card. A directory must contain index.html, use relative local asset URLs, and cannot include dotfiles, source maps, secrets, symlinks, or server code.",
|
|
16661
|
+
description: "Publish one checked HTML file or bounded static build directory as a private immutable Preview after checkpointing its source. The returned arborthreads.dev URL survives computer teardown; put it on its own line to show the interactive Preview card. A directory must contain index.html, use relative local asset URLs, and cannot include dotfiles, source maps, secrets, symlinks, or server code. Supply one stable idempotencyKey per logical publication: safe retries return the original immutable URL, while reusing the key for another path/title conflicts.",
|
|
16610
16662
|
inputSchema: {
|
|
16611
16663
|
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16612
16664
|
path: exports_external.string().describe("absolute path to one HTML file or static build directory under /workspace"),
|
|
16613
|
-
title: exports_external.string().min(1).max(160).describe("short factual Preview title")
|
|
16665
|
+
title: exports_external.string().min(1).max(160).describe("short factual Preview title"),
|
|
16666
|
+
idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this ONE logical publication (≤200 chars); reuse it only to retry the same path and title")
|
|
16614
16667
|
},
|
|
16615
16668
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
16616
16669
|
toolset: "loop",
|
|
@@ -16694,7 +16747,7 @@ var ACTIONS = [
|
|
|
16694
16747
|
{
|
|
16695
16748
|
name: "create_artifact",
|
|
16696
16749
|
title: "Create an artifact",
|
|
16697
|
-
description: "Promote durable output — a decision, summary, plan, or research brief — into a first-class artifact you own. Text kinds (doc/table/diagram/html) are living documents: pass `source` (born at v1, editable in place via edit_artifact); kind=file passes a contentRef instead. The artifact is AUTOMATICALLY listed on its source thread (no link post needed). When it came from an attached Thread computer, pass that attach_computer receipt as computerSessionId so the artifact cites the reproducible session. Reach for this when a thread has produced something worth retaining and citing beyond the conversation — especially a table or doc the team will UPDATE, which beats pasting it into a prose contribution.",
|
|
16750
|
+
description: "Promote durable output — a decision, summary, plan, or research brief — into a first-class artifact you own. Give it a concise summary of what the Artifact is or accomplishes; this is the skim and retrieval description, not a repeat of its title. Text kinds (doc/table/diagram/html) are living documents: pass `source` (born at v1, editable in place via edit_artifact); kind=file passes a contentRef instead. The artifact is AUTOMATICALLY listed on its source thread (no link post needed). When it came from an attached Thread computer, pass that attach_computer receipt as computerSessionId so the artifact cites the reproducible session. Reach for this when a thread has produced something worth retaining and citing beyond the conversation — especially a table or doc the team will UPDATE, which beats pasting it into a prose contribution.",
|
|
16698
16751
|
inputSchema: {
|
|
16699
16752
|
type: exports_external.string().describe("semantic type, e.g. decision|summary|plan|markdown|table|research-brief"),
|
|
16700
16753
|
kind: exports_external.enum(["doc", "table", "diagram", "html", "file"]).optional().describe("structural kind (default file). doc/table/diagram/html are editable, versioned text"),
|
|
@@ -16702,7 +16755,7 @@ var ACTIONS = [
|
|
|
16702
16755
|
source: exports_external.string().optional().describe("text kinds: the initial content (v1)"),
|
|
16703
16756
|
contentRef: exports_external.string().optional().describe("kind=file: where the content lives, e.g. inline://… or a URL"),
|
|
16704
16757
|
editPolicy: exports_external.enum(["owner", "members", "anyone"]).optional().describe("who may edit (default members)"),
|
|
16705
|
-
summary: exports_external.string().
|
|
16758
|
+
summary: exports_external.string().min(1).max(500).describe("required one-line description of what this durable Artifact is or accomplishes"),
|
|
16706
16759
|
sourceThreadId: exports_external.string().optional(),
|
|
16707
16760
|
sourceContributionIds: exports_external.array(exports_external.string()).optional(),
|
|
16708
16761
|
computerSessionId: exports_external.string().optional().describe("the attached computer session that produced this artifact, cms_…")
|
|
@@ -17500,7 +17553,7 @@ var ACTIONS = [
|
|
|
17500
17553
|
{
|
|
17501
17554
|
name: "artifact",
|
|
17502
17555
|
title: "Durable artifacts",
|
|
17503
|
-
description: "Durable, versioned artifacts — the team's living documents (AD-201). Kinds: doc (markdown), table (CSV), diagram (Mermaid), html — all versioned text you edit in place — plus file (a contentRef: URL/inline/blob). " + "verb=create (kind+type+title, source for text kinds / contentRef for file; a text artifact is born at v1 and is AUTOMATICALLY listed on its sourceThreadId thread — no link post needed). " + "For computer-produced output, create with the computerSessionId returned by attach_computer so the artifact cites the reproducible session. " + "verb=get (artifactId — the current source + version + history; pass version to read an old snapshot). " + "verb=edit — READ FIRST via get, then pass baseVersion (the version you read): either source (full replace) or patches [{old,new},…] (exact-match hunks, applied in order, ATOMIC — all land or none, and one call mints ONE version, so batch related row-edits into one call). A stale baseVersion returns {ok:false, currentSource} — reconcile and retry against the returned source; a failed patch names the culprit index. " + "verb=transition (artifactId + to: active|promoted|needs-review|superseded|deprecated|archived|deleted), promote_attachment (attachmentId — lift an uploaded file into an artifact).",
|
|
17556
|
+
description: "Durable, versioned artifacts — the team's living documents (AD-201). Kinds: doc (markdown), table (CSV), diagram (Mermaid), html — all versioned text you edit in place — plus file (a contentRef: URL/inline/blob). " + "verb=create (kind+type+title+summary, source for text kinds / contentRef for file; summary is the required one-line skim/retrieval description; a text artifact is born at v1 and is AUTOMATICALLY listed on its sourceThreadId thread — no link post needed). " + "For computer-produced output, create with the computerSessionId returned by attach_computer so the artifact cites the reproducible session. " + "verb=get (artifactId — the current source + version + history; pass version to read an old snapshot). " + "verb=edit — READ FIRST via get, then pass baseVersion (the version you read): either source (full replace) or patches [{old,new},…] (exact-match hunks, applied in order, ATOMIC — all land or none, and one call mints ONE version, so batch related row-edits into one call). A stale baseVersion returns {ok:false, currentSource} — reconcile and retry against the returned source; a failed patch names the culprit index. " + "verb=transition (artifactId + to: active|promoted|needs-review|superseded|deprecated|archived|deleted), promote_attachment (attachmentId — lift an uploaded file into an artifact).",
|
|
17504
17557
|
inputSchema: {
|
|
17505
17558
|
verb: exports_external.enum(["create", "get", "edit", "transition", "promote_attachment"]).describe("which artifact move"),
|
|
17506
17559
|
title: exports_external.string().optional().describe("create: the artifact's title"),
|
|
@@ -17509,7 +17562,7 @@ var ACTIONS = [
|
|
|
17509
17562
|
source: exports_external.string().optional().describe("create (text kinds): the initial content · edit verb=replace: the full new content"),
|
|
17510
17563
|
contentRef: exports_external.string().optional().describe("create (kind=file): where the content lives, e.g. inline://… or a URL"),
|
|
17511
17564
|
editPolicy: exports_external.enum(["owner", "members", "anyone"]).optional().describe("create: who may edit (default members)"),
|
|
17512
|
-
summary: exports_external.string().optional().describe("create:
|
|
17565
|
+
summary: exports_external.string().min(1).max(500).optional().describe("create: REQUIRED one-line description of what this Artifact is or accomplishes"),
|
|
17513
17566
|
sourceThreadId: exports_external.string().optional().describe("create: the thread it came from"),
|
|
17514
17567
|
computerSessionId: exports_external.string().optional().describe("create: the attached computer session that produced it, cms_…"),
|
|
17515
17568
|
sourceContributionIds: exports_external.array(exports_external.string()).optional().describe("create: contributions it distills"),
|
package/package.json
CHANGED