@lambdacurry/arbor 0.23.37 → 0.23.39
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 +196 -4
- 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.23.
|
|
5
|
+
version: "0.23.39",
|
|
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",
|
|
@@ -7384,6 +7384,9 @@ var artifactVersions = sqliteTable("artifact_versions", {
|
|
|
7384
7384
|
source: text("source").notNull(),
|
|
7385
7385
|
sourceAttachmentId: text("source_attachment_id").references(() => attachments.id),
|
|
7386
7386
|
sourceSha256: text("source_sha256"),
|
|
7387
|
+
gitCommitSha: text("git_commit_sha"),
|
|
7388
|
+
gitSourceSha256: text("git_source_sha256"),
|
|
7389
|
+
gitRepositoryName: text("git_repository_name"),
|
|
7387
7390
|
tldrawDocumentClock: integer2("tldraw_document_clock"),
|
|
7388
7391
|
editorProfileId: text("editor_profile_id").notNull().references(() => profiles.id),
|
|
7389
7392
|
executionContextId: text("execution_context_id").references(() => executionContexts.id),
|
|
@@ -7392,6 +7395,29 @@ var artifactVersions = sqliteTable("artifact_versions", {
|
|
|
7392
7395
|
}, (t) => ({
|
|
7393
7396
|
artifactVersionUq: uniqueIndex("artifact_versions_artifact_version_uq").on(t.artifactId, t.version)
|
|
7394
7397
|
}));
|
|
7398
|
+
var artifactGitWriteIntents = sqliteTable("artifact_git_write_intents", {
|
|
7399
|
+
artifactId: text("artifact_id").notNull(),
|
|
7400
|
+
requestKey: text("request_key").notNull(),
|
|
7401
|
+
fingerprint: text("fingerprint").notNull(),
|
|
7402
|
+
baseVersion: integer2("base_version").notNull(),
|
|
7403
|
+
expectedParentSha: text("expected_parent_sha"),
|
|
7404
|
+
targetVersion: integer2("target_version").notNull(),
|
|
7405
|
+
targetVersionId: text("target_version_id").notNull(),
|
|
7406
|
+
targetSourceSha256: text("target_source_sha256").notNull(),
|
|
7407
|
+
state: text("state").$type().notNull().default("pending"),
|
|
7408
|
+
gitCommitSha: text("git_commit_sha"),
|
|
7409
|
+
gitRepositoryName: text("git_repository_name"),
|
|
7410
|
+
createdAt: ts("created_at").notNull(),
|
|
7411
|
+
finalizedAt: ts("finalized_at"),
|
|
7412
|
+
requestJson: text("request_json")
|
|
7413
|
+
}, (t) => ({
|
|
7414
|
+
pk: primaryKey({ columns: [t.artifactId, t.requestKey] }),
|
|
7415
|
+
pendingUq: uniqueIndex("artifact_git_write_intents_one_pending_uq").on(t.artifactId).where(sql`${t.state} = 'pending'`),
|
|
7416
|
+
targetVersionIdx: index("artifact_git_write_intents_artifact_target_idx").on(t.artifactId, t.targetVersion),
|
|
7417
|
+
stateCheck: check("artifact_git_write_intents_state_check", sql`(${t.state} = 'pending' AND ${t.finalizedAt} IS NULL)
|
|
7418
|
+
OR (${t.state} = 'finalized' AND ${t.gitCommitSha} IS NOT NULL AND ${t.finalizedAt} IS NOT NULL)`),
|
|
7419
|
+
versionCheck: check("artifact_git_write_intents_version_check", sql`${t.baseVersion} >= 0 AND ${t.targetVersion} > 0`)
|
|
7420
|
+
}));
|
|
7395
7421
|
var artifactTldrawBoards = sqliteTable("artifact_tldraw_boards", {
|
|
7396
7422
|
artifactId: text("artifact_id").primaryKey().references(() => artifacts.id, { onDelete: "cascade" }),
|
|
7397
7423
|
roomGeneration: integer2("room_generation").notNull().default(1),
|
|
@@ -8245,6 +8271,12 @@ var SPACE_ARTIFACT_STATUSES = [
|
|
|
8245
8271
|
"archived"
|
|
8246
8272
|
];
|
|
8247
8273
|
var artifactUpdatedAt = sql`coalesce((select max(${events.createdAt}) from ${events} where ${events.objectType} = 'artifact' and ${events.objectId} = ${artifacts.id}), ${artifacts.createdAt})`;
|
|
8274
|
+
// ../core/src/ops/artifact-git-intent.ts
|
|
8275
|
+
var RETRYABLE_REPAIR = new Set([
|
|
8276
|
+
"pending_push_unconfirmed",
|
|
8277
|
+
"remote_unavailable",
|
|
8278
|
+
"finalize_failed"
|
|
8279
|
+
]);
|
|
8248
8280
|
// ../core/src/ops/request.ts
|
|
8249
8281
|
var REQUEST_TTL_MS = 14 * 24 * 60 * 60 * 1000;
|
|
8250
8282
|
|
|
@@ -12414,7 +12446,8 @@ var ACTION_DEFINITIONS = [
|
|
|
12414
12446
|
baseVersion: number2().describe("the version you READ (get_artifact) — stale is rejected"),
|
|
12415
12447
|
source: string2().optional().describe("full replace: the complete new content"),
|
|
12416
12448
|
patches: array(object({ old: string2(), new: string2() })).optional().describe("exact-match hunks applied in order; each old must match exactly once"),
|
|
12417
|
-
note: string2().optional().describe("one-line summary of what changed")
|
|
12449
|
+
note: string2().optional().describe("one-line summary of what changed"),
|
|
12450
|
+
idempotencyKey: string2().min(1).max(200).optional().describe("stable retry key for this logical edit; the CLI derives one from the artifact, base version, and content when omitted")
|
|
12418
12451
|
},
|
|
12419
12452
|
surfaces: ["cli"],
|
|
12420
12453
|
toolset: "artifacts",
|
|
@@ -13394,7 +13427,7 @@ var ACTION_DEFINITIONS = [
|
|
|
13394
13427
|
{
|
|
13395
13428
|
name: "artifact",
|
|
13396
13429
|
title: "Create or edit an Artifact",
|
|
13397
|
-
description: "Create
|
|
13430
|
+
description: "Create/edit an Artifact, bind a Thread Live Preview, set a Computer snapshot, or promote a Thread attachment to a file Artifact. Git writes: stable key; same-key retry only after unknown outcome. To reference an exported report within an existing baseline Artifact, use the Attachment's durable downloadUrl instead of promoting it into that artifactId. For a computer:// .tldr snapshot mint: computer_export the exact locator path and same-Thread PNG, then use set_snapshot. Board save and TLP do not mint snapshots. set_snapshot does not wake Computer or change the locator; read artifact_get before changing it, while lifecycle/removal stay in artifact_transition and artifact_delete.",
|
|
13398
13431
|
inputSchema: {
|
|
13399
13432
|
verb: _enum(["create", "edit", "set_live_preview", "set_snapshot", "promote_attachment"]).describe("which artifact move"),
|
|
13400
13433
|
title: string2().optional().describe("create: the artifact's title"),
|
|
@@ -13412,6 +13445,7 @@ var ACTION_DEFINITIONS = [
|
|
|
13412
13445
|
baseVersion: number2().optional().describe("edit: the version you READ (from get/create) — stale base is rejected with the current source"),
|
|
13413
13446
|
patches: array(object({ old: string2(), new: string2() })).optional().describe("edit: exact-match hunks applied in order, atomically; each old must match exactly once"),
|
|
13414
13447
|
note: string2().optional().describe("edit: one-line summary of what changed"),
|
|
13448
|
+
idempotencyKey: string2().min(1).max(200).optional().describe("create/edit for Git-backed text: stable key for one logical write; reuse unchanged only to recover an unknown outcome, never to start a new write"),
|
|
13415
13449
|
sourceAttachmentId: string2().optional().describe("set_snapshot: computer_export of the exact computer:// locator path; MIME application/vnd.tldraw+json, computerPath stamped and matching defaultCwd + locator"),
|
|
13416
13450
|
previewAttachmentId: string2().optional().describe("set_snapshot: same-Thread computer_export image/png Attachment, used as the asleep face preview"),
|
|
13417
13451
|
attachmentId: string2().optional().describe("promote_attachment: the upload, att_…"),
|
|
@@ -14177,7 +14211,7 @@ function retentionAction(action) {
|
|
|
14177
14211
|
if (action.name === "artifact") {
|
|
14178
14212
|
return {
|
|
14179
14213
|
...action,
|
|
14180
|
-
description: "Create/edit a durable
|
|
14214
|
+
description: "Create/edit a durable Artifact with full|checkpoint retention or manage Live Preview/snapshot/attachments. Git text writes require a stable idempotencyKey; retry the same key only after an unknown outcome; promote_attachment creates a separate file Artifact from a source Contribution; exported reports use the Attachment's durable downloadUrl; content edits return artifactVersionId; identical edits reuse the current version; policy/checkpoint changes do not mint content versions.",
|
|
14181
14215
|
inputSchema: {
|
|
14182
14216
|
...action.inputSchema,
|
|
14183
14217
|
historyPolicy: historyPolicySchema,
|
|
@@ -15220,6 +15254,159 @@ function buildInput(inputSchema, flags, command) {
|
|
|
15220
15254
|
}
|
|
15221
15255
|
|
|
15222
15256
|
// src/commands.ts
|
|
15257
|
+
var SHA256_K = [
|
|
15258
|
+
1116352408,
|
|
15259
|
+
1899447441,
|
|
15260
|
+
3049323471,
|
|
15261
|
+
3921009573,
|
|
15262
|
+
961987163,
|
|
15263
|
+
1508970993,
|
|
15264
|
+
2453635748,
|
|
15265
|
+
2870763221,
|
|
15266
|
+
3624381080,
|
|
15267
|
+
310598401,
|
|
15268
|
+
607225278,
|
|
15269
|
+
1426881987,
|
|
15270
|
+
1925078388,
|
|
15271
|
+
2162078206,
|
|
15272
|
+
2614888103,
|
|
15273
|
+
3248222580,
|
|
15274
|
+
3835390401,
|
|
15275
|
+
4022224774,
|
|
15276
|
+
264347078,
|
|
15277
|
+
604807628,
|
|
15278
|
+
770255983,
|
|
15279
|
+
1249150122,
|
|
15280
|
+
1555081692,
|
|
15281
|
+
1996064986,
|
|
15282
|
+
2554220882,
|
|
15283
|
+
2821834349,
|
|
15284
|
+
2952996808,
|
|
15285
|
+
3210313671,
|
|
15286
|
+
3336571891,
|
|
15287
|
+
3584528711,
|
|
15288
|
+
113926993,
|
|
15289
|
+
338241895,
|
|
15290
|
+
666307205,
|
|
15291
|
+
773529912,
|
|
15292
|
+
1294757372,
|
|
15293
|
+
1396182291,
|
|
15294
|
+
1695183700,
|
|
15295
|
+
1986661051,
|
|
15296
|
+
2177026350,
|
|
15297
|
+
2456956037,
|
|
15298
|
+
2730485921,
|
|
15299
|
+
2820302411,
|
|
15300
|
+
3259730800,
|
|
15301
|
+
3345764771,
|
|
15302
|
+
3516065817,
|
|
15303
|
+
3600352804,
|
|
15304
|
+
4094571909,
|
|
15305
|
+
275423344,
|
|
15306
|
+
430227734,
|
|
15307
|
+
506948616,
|
|
15308
|
+
659060556,
|
|
15309
|
+
883997877,
|
|
15310
|
+
958139571,
|
|
15311
|
+
1322822218,
|
|
15312
|
+
1537002063,
|
|
15313
|
+
1747873779,
|
|
15314
|
+
1955562222,
|
|
15315
|
+
2024104815,
|
|
15316
|
+
2227730452,
|
|
15317
|
+
2361852424,
|
|
15318
|
+
2428436474,
|
|
15319
|
+
2756734187,
|
|
15320
|
+
3204031479,
|
|
15321
|
+
3329325298
|
|
15322
|
+
];
|
|
15323
|
+
function rotateRight(value, bits) {
|
|
15324
|
+
return value >>> bits | value << 32 - bits;
|
|
15325
|
+
}
|
|
15326
|
+
function sha256Hex(value) {
|
|
15327
|
+
const bytes = new TextEncoder().encode(value);
|
|
15328
|
+
const bitLength = bytes.length * 8;
|
|
15329
|
+
const paddedLength = bytes.length + 9 + 63 >> 6 << 6;
|
|
15330
|
+
const padded = new Uint8Array(paddedLength);
|
|
15331
|
+
padded.set(bytes);
|
|
15332
|
+
padded[bytes.length] = 128;
|
|
15333
|
+
const highLength = Math.floor(bitLength / 4294967296);
|
|
15334
|
+
const lowLength = bitLength >>> 0;
|
|
15335
|
+
for (let i = 0;i < 4; i++) {
|
|
15336
|
+
padded[paddedLength - 8 + i] = highLength >>> 24 - i * 8;
|
|
15337
|
+
padded[paddedLength - 4 + i] = lowLength >>> 24 - i * 8;
|
|
15338
|
+
}
|
|
15339
|
+
const hash = [
|
|
15340
|
+
1779033703,
|
|
15341
|
+
3144134277,
|
|
15342
|
+
1013904242,
|
|
15343
|
+
2773480762,
|
|
15344
|
+
1359893119,
|
|
15345
|
+
2600822924,
|
|
15346
|
+
528734635,
|
|
15347
|
+
1541459225
|
|
15348
|
+
];
|
|
15349
|
+
const words = new Uint32Array(64);
|
|
15350
|
+
for (let offset = 0;offset < padded.length; offset += 64) {
|
|
15351
|
+
for (let i = 0;i < 16; i++) {
|
|
15352
|
+
const index = offset + i * 4;
|
|
15353
|
+
words[i] = padded[index] << 24 | padded[index + 1] << 16 | padded[index + 2] << 8 | padded[index + 3];
|
|
15354
|
+
}
|
|
15355
|
+
for (let i = 16;i < 64; i++) {
|
|
15356
|
+
const x = words[i - 15];
|
|
15357
|
+
const y = words[i - 2];
|
|
15358
|
+
const sigma0 = rotateRight(x, 7) ^ rotateRight(x, 18) ^ x >>> 3;
|
|
15359
|
+
const sigma1 = rotateRight(y, 17) ^ rotateRight(y, 19) ^ y >>> 10;
|
|
15360
|
+
words[i] = words[i - 16] + sigma0 + words[i - 7] + sigma1 >>> 0;
|
|
15361
|
+
}
|
|
15362
|
+
let [a, b, c, d, e, f, g, h] = hash;
|
|
15363
|
+
for (let i = 0;i < 64; i++) {
|
|
15364
|
+
const sigma1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
|
|
15365
|
+
const choice = e & f ^ ~e & g;
|
|
15366
|
+
const temp1 = h + sigma1 + choice + SHA256_K[i] + words[i] >>> 0;
|
|
15367
|
+
const sigma0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
|
|
15368
|
+
const majority = a & b ^ a & c ^ b & c;
|
|
15369
|
+
const temp2 = sigma0 + majority >>> 0;
|
|
15370
|
+
h = g;
|
|
15371
|
+
g = f;
|
|
15372
|
+
f = e;
|
|
15373
|
+
e = d + temp1 >>> 0;
|
|
15374
|
+
d = c;
|
|
15375
|
+
c = b;
|
|
15376
|
+
b = a;
|
|
15377
|
+
a = temp1 + temp2 >>> 0;
|
|
15378
|
+
}
|
|
15379
|
+
hash[0] = hash[0] + a >>> 0;
|
|
15380
|
+
hash[1] = hash[1] + b >>> 0;
|
|
15381
|
+
hash[2] = hash[2] + c >>> 0;
|
|
15382
|
+
hash[3] = hash[3] + d >>> 0;
|
|
15383
|
+
hash[4] = hash[4] + e >>> 0;
|
|
15384
|
+
hash[5] = hash[5] + f >>> 0;
|
|
15385
|
+
hash[6] = hash[6] + g >>> 0;
|
|
15386
|
+
hash[7] = hash[7] + h >>> 0;
|
|
15387
|
+
}
|
|
15388
|
+
return hash.map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
15389
|
+
}
|
|
15390
|
+
function artifactEditIdempotencyKey(input) {
|
|
15391
|
+
const artifactId = input.artifactId;
|
|
15392
|
+
const baseVersion = input.baseVersion;
|
|
15393
|
+
const hasSource = typeof input.source === "string";
|
|
15394
|
+
const hasPatches = Array.isArray(input.patches);
|
|
15395
|
+
if (typeof artifactId !== "string" || !Number.isInteger(baseVersion) || !hasSource && !hasPatches) {
|
|
15396
|
+
return;
|
|
15397
|
+
}
|
|
15398
|
+
const version = baseVersion;
|
|
15399
|
+
const payload = JSON.stringify({
|
|
15400
|
+
artifactId,
|
|
15401
|
+
baseVersion: version,
|
|
15402
|
+
source: hasSource ? input.source : undefined,
|
|
15403
|
+
patches: hasPatches ? input.patches : undefined,
|
|
15404
|
+
note: typeof input.note === "string" ? input.note : undefined,
|
|
15405
|
+
retainSource: typeof input.retainSource === "boolean" ? input.retainSource : undefined
|
|
15406
|
+
});
|
|
15407
|
+
const digest = sha256Hex(payload);
|
|
15408
|
+
return `cli-artifact-edit:${artifactId}:${version}:${digest}`;
|
|
15409
|
+
}
|
|
15223
15410
|
var COMMAND_WORD_OVERRIDES = {
|
|
15224
15411
|
contribute_arbor_feedback: "feedback",
|
|
15225
15412
|
feedback_recall: "feedback find",
|
|
@@ -15502,6 +15689,11 @@ async function runObjectVerb(positionals, flags, ctx) {
|
|
|
15502
15689
|
delete inputFlags.json;
|
|
15503
15690
|
}
|
|
15504
15691
|
const input = buildInput(action.inputSchema, inputFlags, commandWords(action));
|
|
15692
|
+
if (action.name === "edit_artifact" && input.idempotencyKey === undefined) {
|
|
15693
|
+
const idempotencyKey = artifactEditIdempotencyKey(input);
|
|
15694
|
+
if (idempotencyKey !== undefined)
|
|
15695
|
+
input.idempotencyKey = idempotencyKey;
|
|
15696
|
+
}
|
|
15505
15697
|
if (action.name === "computer_exec" && flags["no-wait"] !== undefined && input.waitForTerminalMs !== undefined) {
|
|
15506
15698
|
throw new UsageError("--no-wait and --wait-for-terminal-ms are mutually exclusive", {
|
|
15507
15699
|
reason: "validation.invalid_value",
|
package/package.json
CHANGED